Added Eric S. Fraga tutorial about Org Beamer.
[Worg.git] / org-contrib / org-protocol.org
blob0156c20f579c578845bb72bdff1df789ec4ed249
1 #+TITLE:   org-protocol.el -- Intercept calls from emacsclient to trigger custom actions
2 #+OPTIONS: H:3 num:nil toc:t \n:nil @:t ::t |:t -:t f:t *:t TeX:t LaTeX:t skip:nil d:(HIDE) tags:not-in-toc ^:{} author:nil
3 #+STARTUP: odd
4 #+STYLE:   <script type="text/javascript">
5 #+STYLE:   <!--/*--><![CDATA[/*><!--*/
6 #+STYLE:   function makeUrl() {
7 #+STYLE:     return encodeURIComponent(location.href)+
8 #+STYLE:            '/'+encodeURIComponent(document.title)+
9 #+STYLE:            '/'+encodeURIComponent(window.getSelection());
10 #+STYLE:   }
11 #+STYLE:   function storeLink() {
12 #+STYLE:     document.location.href='org-protocol://store-link://'+makeUrl();
13 #+STYLE:   }
14 #+STYLE:   function remember() {
15 #+STYLE:     document.location.href='org-protocol://remember://'+makeUrl();
16 #+STYLE:   }
17 #+STYLE:   /*]]>*///-->
18 #+STYLE:   </script>
20 [[file:index.org][{Back to Worg's contibutions index}]]
22 org-protocol intercepts calls from emacsclient to trigger custom actions without
23 external dependencies. Only one protocol has to be configured with your external
24 applications or the operating system, to trigger an arbitrary number of custom
25 actions. Just register your custom sub-protocol and handler with the variable
26 `org-protocol-protocol-alist'.
28 # <<about>>
29 * About org-protocol.el
31   =org-protocol.el= is based on code and ideas from [[file:./org-annotation-helper.org][org-annotation-helper.el]] and
32   =org-browser-url.el=.
34   "=org-protocol:/sub-protocol:/=" triggers actions assossiated with =sub-protocol=
35   through the custom variable =org-protocol-protocol-alist=.
37   It comes with three predefined handlers:
38     - =org-protocol-store-link= ::
39       triggered through the sub-protocol "=store-link=". Stores an Org-link and
40       pushes the URL to the =kill-ring=.
41     - =org-protocol-remember= ::
42       Fill a remember buffer with informations gathered somewhere else. This one
43       is triggered through the "=remember=" sub-protocol.
44     - =org-protocol-open-source= ::
45       "=open-source=". Maps URLs to local filenames. Use this to open sources of
46       already published contents in emacs for editing.
48   =org-protocol= helps creating custom handlers [[file:../org-tutorials/org-protocol-custom-handler.org][(tutorial)]] and so called
49   =org-protocol-projects=.
52 # <<installation>>
53 * Installation
55   - To load org-protocol.el add the following to your =.emacs=:
57     : (server-start)
58     : (add-to-list 'load-path "~/path/to/org/protocol/")
59     : (require 'org-protocol)
61 * Browser / system setup
63   Windows users proceed to the section [[windows-setup][Windows]].
65 # <<firefox-setup>>
66 *** Firefox
68   As of March 2009 Firefox users follow the steps documented on
69   http://kb.mozillazine.org/Register_protocol. Here is a summary:
71   1. Type "=about:config=" into the location bar and press enter.
72   2. Click "/I'll be careful, I promise!/" to continue.
73   3. Right-click on the grid
74   4. Choose "/New/" -> "/String/" from the context menu.
75   5. Enter "=network.protocol-handler.app.org-protocol=" as the properties name.
76   6. Click "/OK/".
77   7. Leave the value blank.
78   8. Next time you try to open a location "=org-protocol://...=" FF will ask you for
79      the program to use. Enter the path to emacsclient.
81 # <<acrobat-setup>>
82 *** Acrobat Reader
83     :PROPERTIES:
84     :CUSTOM_ID: acrobat-reader-setup
85     :END:
87     Adapted from [[http://article.gmane.org/gmane.emacs.orgmode/6810]]
89     You place a javascript file for each menu entry in
90     =~/.adobe/Acrobat/<VERSION>/JavaScripts= on unix-like systems or
91     =c:/Program Files/Adobe/Acrobat <VERSION>/Reader/Javascripts/= on
92     Windows, or wherever your Adobe Reader Installation might look for
93     javascript.
95     The examples given here will place new menu entries in the "Tools"
96     menu, after restarting Adobe Reader.
98 # <<acrobat-store-link-js>>
99 ***** org-store-link.js
100 : // from http://article.gmane.org/gmane.emacs.orgmode/6810
101 : app.addMenuItem({cName:"org-store-link", cParent:"Tools",
102 :    cExec:"app.launchURL('org-protocol://store-link://' + encodeURIComponent(this.URL) + '/' + encodeURIComponent(this.info.Title));"});
104 # <<acrobat-remember-js>>
105 ***** org-remember.js
106 : // from http://article.gmane.org/gmane.emacs.orgmode/6810
107 : app.addMenuItem({cName:"org-remember", cParent:"Tools",
108 :    cExec:"app.launchURL('org-protocol://remember://' + encodeURIComponent(this.URL) + '/' + encodeURIComponent(this.info.Title) + '/');"});
111 # <<opera-setup>>
112 *** Opera
114   Opera setup is described here:
115   http://www.opera.com/support/kb/view/535/.
117   To set up opera for use with org-protocol, follow these steps:
119   1. Choose "/Tools/" -> "/Prefences/" from the menu.
120   2. Select the tab "/Advanced/".
121   3. Choose "/Programs/" from the list on the left.
122   4. Now click the button "/Add/" on the very right.
123   5. In the new dialog window, enter "=org-protocol=" as "/Protocol/", choose the
124      radio button "/Open with other application/" and enter the path to
125      emacsclient.
127 # <<windows-setup>>
128 *** Windows setup
130   Windows users may register the "=org-protocol=" once for all by adjusting the
131   following to their facts, save it as *.reg file and double-click it. This
132   worked for me on Windows-XP Professional and the emasc23 from ourcomments.org
133   ([[http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl]]). I'm no Windows user
134   though and enhancements are more than welcome on the org-mode mailinglist. The
135   original file is from http://kb.mozillazine.org/Register_protocol.
137 #+begin_example
138 REGEDIT4
140 [HKEY_CLASSES_ROOT\org-protocol]
141 @="URL:Org Protocol"
142 "URL Protocol"=""
143 [HKEY_CLASSES_ROOT\org-protocol\shell]
144 [HKEY_CLASSES_ROOT\org-protocol\shell\open]
145 [HKEY_CLASSES_ROOT\org-protocol\shell\open\command]
146 @="\"C:\\Programme\\Emacs\\emacs\\bin\\emacsclientw.exe\" \"%1\""
147 #+end_example
150 # <<test-org-protocol>>
151 *** Verify the installation
153     After your protocol is registered with your browse/OS, these links here
154     should work. Click on them and see if emacs reacts:
156 #+begin_html
157  <ul>
158   <li><a href="javascript:storeLink();">Org store-link</a></li>
159   <li><a href="javascript:remember();">Org remember (select some text please)</a></li>
160  </ul>
161 #+end_html
164 # <<default-location>>
165 * Using org-protocol
167   To actually use org-protocol add a bookmark to Firefox or opera.
169   Here is the URL to use as "/Location/" for browser bookmarks. Just remove the
170   line breaks and replace "=sub-protocol=" with the real sub-protocol to use:
172   : javascript:location.href='org-protocol://sub-protocol://'+
173   :       encodeURIComponent(location.href)+'/'+
174   :       encodeURIComponent(document.title)+'/'+
175   :       encodeURIComponent(window.getSelection())
177   This URL may be used for all three standard handlers in =org-protocol.el=. Some
178   of the values will be ignored (e.g. =store-link:/= will use the URL and title
179   only).
181 # <<org-protocol-store-link>>
182 * Links and bookmarks: =org-protocol-store-link=
184   =org-store-link= stores an Org-link insertable through =M-x org-insert-link= and
185   pushes the URL found on the =kill-ring= for yanking (=C-y=). The sub-protocol used
186   is "=store-link=":
188   : emacsclient org-protocol:/store-link:/URL/TITLE
190   will store this Org-link:
192 #+begin_example
193 [[URL][TITLE]]
194 #+end_example
196   In addition, =URL= will be pushed on the =kill-ring= for yanking ('=C-y='). You will
197   have to encode =URL= and/or =TITLE= if they contain slashes, and probably quote
198   those for the shell.
200   To use this feature, add a bookmark with an arbitrary name (e.g.
201   "/Org: store-link/") and enter this as "=Location=":
203   : javascript:location.href='org-protocol://store-link://'+encodeURIComponent(location.href)
206 # <<org-protocol-remember>>
207 * Note taking and citations: =org-protocol-remember=
209   This one is triggered through the sub-protocol "=remember=" and consumes up to
210   three data fields:
212   : emacsclient org-protocol:/remember:/URL/TITLE/BODY
214   will pop up an /*Remember*/ buffer and fill the template with the data
215   submitted.
217   To use this feature, add a bookmark with an arbitrary name (e.g.
218   "/Org: remember/") and enter this as "=Location=":
220   : javascript:location.href='org-protocol://remember://'+
221   :       encodeURIComponent(location.href)+'/'+
222   :       encodeURIComponent(document.title)+'/'+
223   :       encodeURIComponent(window.getSelection())
225   The result depends on the template used. See [[example-template][An example remember template]]
226   further down.
228   Note, that this one, as opposed to the other two standard handlers, does not
229   mix with more parameters to emacsclient. All parameters but the
230   #'=org-protocol://org-remember://...=' one will be discarded.
232 # <<which-remember-template>>
233 *** Which remember template is used?
235     You don't need to setup a remember template to use =org-protocol-remember=,
236     since Org-mode provides a default template for those cases. But, for
237     historical reasons, if a template with the template char '=?w=' is defined,
238     this one will be choosen by default. This is to make bookmarks used for
239     [[file:./org-annotation-helper.el][org-annotation-helper]] work without changing the template.
241     The problem with this solution would be, that only one template can be used
242     with the fuction. Luckily, =org-protocol-remember= understands a slightly
243     extended syntax to choose between several templates: If the first field of
244     the data submitted is exactly one character in length, this character will
245     be used to select the template.
247     Here we choose to use the '=?x=' template:
249     : emacsclient org-protocol:/remember:/x/URL/TITLE/BODY
251     And, again, as bookmark location:
252     : javascript:location.href='org-protocol://remember://x/'+
253     :       encodeURIComponent(location.href)+'/'+
254     :       encodeURIComponent(document.title)+'/'+
255     :       encodeURIComponent(window.getSelection())
257 # <<example-template>>
258 *** An example remember template
260 #+begin_src emacs-lisp
261 (setq org-remember-templates
262       '((?w "* %^{Title}\n\n  Source: %u, %c\n\n  %i" nil "Notes")))
263 #+end_src
265     - '=?w=' :: makes this one the default template used for
266               "=org-protocol://remember://=" URLs.
267     - '=%c=' :: will be replaced by an Org-link pointing to the location of the
268              page you have been visiting when clicking on the link. The page
269              title will be the links description.
270     - '=%i=' :: will be replaced by the selected text in your browser window if
271               any.
273     In addition, you may use the following placeholders in your template:
275     | Placeholders  | Replacement               |
276     |---------------+---------------------------|
277     | =%:link=        | URL of the web-page       |
278     | =%:description= | The title of the web-page |
279     | =%:initial=     | Selected text.            |
281     You may read more about templates and their special escape characters in the
282     [[http://orgmode.org/manual/Remember-templates.html#Remember-templates][Org-mode manual]].
285 # <<open-source>>
286 * Edit published content: =org-protocol-open-source=
288   This one was designed to help with opening sources for editing when browsing
289   in the first place. =org-protocol-open-source= uses the custom variable
290   =org-protocol-project-alist= to map URLs to (local) filenames.
292   Let's take http://orgmode.org/worg/ as our example.
294   Our intention is to click a bookmark (or link) to open the source of the
295   published file we are reading in our favourite editor. The bookmark-URL above
296   could be used again. But since =org-protocol-open-source= regards the first
297   field only, this here will do:
299   : javascript:location.href='org-protocol://open-source://'+encodeURIComponent(location.href)
301   To open files publihed on Worg locally, =org-protocol-project-alist= should look
302   like this (you may skip the second project):
304 #+begin_src emacs-lisp
305 (setq org-protocol-project-alist
306       '(("Worg"
307          :base-url "http://orgmode.org/worg/"
308          :working-directory "/home/user/worg/"
309          :online-suffix ".html"
310          :working-suffix ".org")
311         ("My local Org-notes"
312          :base-url "http://localhost/org/"
313          :working-directory "/home/user/org/"
314          :online-suffix ".php"
315          :working-suffix ".org")))
316 #+end_src
318   If you're now browsing http://orgmode.org/worg/org-tutorials/org-protocol.php
319   and find a typo or have an idea how to enhance the documentation, simply click
320   the bookmark and start editing.
322   There are to functions to help you filling =org-protocol-project-alist= with
323   valid contents. First of which is =org-protocol-create= that guides you through
324   the process. If you're editing an Org-mode file that is part of a publishing
325   project in =org-publish-project-alist=, try
327   : M-x org-protocol-create-for-org RET
329 # <<open-source-rewritten-urls>>
330 *** Handle rewritten URLs
332     In some cases, replacing =:base-url= with =:working-directory= and
333     =:online-suffix= with =:working-suffix= will not yield the desired results.
335     Suppose you maintain an online store located at =http://example.com/=. The
336     local sources reside in =/home/user/example/=. While most of the URLs map
337     directly to local file names by stripping URL parameters from the end and
338     replacing the =:base-url= with =:working-diretory= and =:online-suffix= with
339     =working-suffix=, this might not work for rewritten URLs. It's common
340     practice, to serve all products in such a store through one file and rewrite
341     URLs, that do not match an existing file on the server.
343     That way, a request to =http://example.com/print/posters-A4.html= might be
344     rewritten on the server to something like
345     =http://example.com/shop/products.php/posters-A4.html.php=, where
346     =/posters-A4-digital.html.php= is the so called path info. Note, that the
347     browser will not notice the rewrite.
349     If you now click your =org-protocol://open-source://= bookmark, the handler
350     will probably not find a file named
351     =/home/user/example/print/posters-A4.html.php= and fail.
353     Or, even more simple, assume your browsing to =http://example.com/=. A file
354     named =/home/user/example/.php= is not likely to exist.
356     Since Org-mode commit =69b46e10aab3b2374ecbc1a963ba56e77102a9a4= from 15nth
357     Nov. 2009, such an entry in =org-protocol-project-alist= may hold an
358     additional property =:rewrites=. This property is a list of cons cells, each
359     of which maps a regular expression to a path, relative to the
360     =:working-directory=.
362     Now map the URL to the path =/home/user/example/products.php= by adding the
363     =:rewrites= property like this:
365 #+begin_src emacs-lisp
366   (setq org-protocol-project-alist
367         '(("example.com"
368            :base-url "http://example.com/"
369            :working-directory "/home/user/example/"
370            :online-suffix ".php"
371            :working-suffix ".php"
372            :rewrites (("example.com/print/" . "products.php")
373                       ("example.com/$" . "index.php"))
374            )))
375 #+end_src
377    Guess what the second =:rewrites= element does. Since =example.com/$= is used as
378    a regular expression, it maps =http://example.com/=, =https://example.com=,
379    =http://www.example.com/= and similar to =/home/user/example/index.php=.
381    The =:rewrites= are searched as a last resort if, and only if no existing file
382    name is matched.
384 * Other browsers
385 #<<conkeror-setup>>
386 *** Conkeror setup
388 Setting up org-protocol in [[http://conkeror.org/][Conkeror]] (an emacs inspired Mozilla web
389 browser) requires a slightly different method. You may simply add the
390 following snippets of code to your .conkerorrc file.[fn:tassilosblog]
392 For org-store-link, add the following to .conkerorrc:
394 : function org_store_link (url, title, window) {
395 :     var cmd_str = 'emacsclient \"org-protocol://store-link://'+url+'/'+title+'\"';
396 :     if (window != null) {
397 :       window.minibuffer.message('Issuing ' + cmd_str);
398 :     }
399 :     shell_command_blind(cmd_str);
400 : }
402 : interactive("org-store-link", "Stores [[url][title]] as org link and copies url to emacs kill ring",
403 :           function (I) {
404 :               org_store_link(encodeURIComponent(I.buffer.display_uri_string), encodeURIComponent(I.buffer.document.title), I.window);
405 :           });
407 For org-remember, use the following:
409 : function org_remember (url, title, selection, window) {
410 :     var cmd_str = 'emacsclient \"org-protocol://remember://'+url+'/'+title+'/'+selection+'\"';
411 :     if (window != null) {
412 :       window.minibuffer.message('Issuing ' + cmd_str);
413 :     }
414 :     shell_command_blind(cmd_str);
415 : }
417 : interactive("org-remember", "Clip url, title, and selection to remember via org-protocol",
418 :           function (I) {
419 :               org_remember(encodeURIComponent(I.buffer.display_uri_string), encodeURIComponent(I.buffer.document.title), encodeURIComponent(I.buffer.top_frame.getSelection()), I.window);
420 :           });
422 Now, you should be able to invoke the commands from within conkeror
423 with =M-x org-store-link= and =M-x org-remember=.
425 Or, if you'd like your familiar emacs keybindings, you can add the
426 following to your .conkerorrc:
428 : define_key(content_buffer_normal_keymap, "C-c r", "org-remember");
429 : define_key(content_buffer_normal_keymap, "C-c l", "org-store-link");
431 [fn:tassilosblog] Adapted from Tassilo Horn's blog, "Calling
432 org-remember from inside conkeror," November 14, 2008.
433 http://tsdh.wordpress.com/2008/11/14/calling-org-remember-from-inside-conkeror/
435 *** Uzbl
436     :PROPERTIES:
437     :CUSTOM_ID: uzbl
438     :END:
440 Uzbl is a minimalistic webkit browser for Unix/Linux.
442 - [[http://www.uzbl.org/]]
444 You can pass encoded url data from uzbl to org-protocol by adding the
445 following lines to =.config/uzbl/config=.
447 #+begin_src 
449 # Org-protocol
451 @cbind  \\r = sh 'emacsclient "org-protocol://remember://\@<encodeURIComponent(window.location.href)>\@/\@<encodeURIComponent(document.title)>\@/\@<document.getSelection()>\@"'
452 @cbind  \\l = sh 'emacsclient "org-protocol://remember://\@<encodeURIComponent(window.location.href)>\@/\@<encodeURIComponent(document.title)>\@"'
454 #+end_src
456 These bind org-protocol-remember and org-store-line to "\r" and "\l" respectively.
458 # <<firefox-keybindings>>
459 * Keybindings for Firefox
461   You can add key bindings for the =org-protocol= commands using the keyconfig
462   Firefox extension.
464   First, install keyconfig from http://mozilla.dorando.at/keyconfig.xpi.
466   Open the keyconfig dialog by going to Tools and then Keyconfig.
468   Click the 'Add a new Key' button. Enter "Org store link" as the name.
469   Enter the following in the box with /* CODE */ in it:
471   : var orgProtoString = 'org-protocol://store-link://'+
472   :   encodeURIComponent(gBrowser.currentURI.spec) + '/' +
473   :   encodeURIComponent(gBrowser.contentWindow.document.title) + '/' +
474   :   encodeURIComponent(window.getSelection());
475   :
476   : gBrowser.loadURI(orgProtoString);
478   Click OK. You will then need to bind a key by clicking in the box next to the
479   'Apply' button and pressing whatever key combination you want. Click 'Apply' to
480   store the keybinding.
482   Repeat the steps, but call the next key "Org remember" and use the code below:
484   : var orgProtoString = 'org-protocol://remember://'+
485   :   encodeURIComponent(gBrowser.currentURI.spec) + '/' +
486   :   encodeURIComponent(gBrowser.contentWindow.document.title) + '/' +
487   :   encodeURIComponent(window.getSelection());
488   :
489   : gBrowser.loadURI(orgProtoString);
491   Click Close, then OK, and then restart Firefox. You should then be able to
492   access the org-protocol functions with your chosen keys.
494 # <<screencast-intro>>
495 * Screencast: small introduction to org-protocol.el
497 #+begin_html
498 <object width="640" height="464"><param name="allowfullscreen"
499 value="true" /><param name="allowscriptaccess" value="always" /><param
500 name="movie"
501 value="http://vimeo.com/moogaloop.swf?clip_id=5662410&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=FF7700&amp;fullscreen=1"
502 /><embed
503 src="http://vimeo.com/moogaloop.swf?clip_id=5662410&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=1&amp;color=FF7700&amp;fullscreen=1"
504 type="application/x-shockwave-flash" allowfullscreen="true"
505 allowscriptaccess="always" width="640" height="464"></embed></object>
506 #+end_html
508 This screencast shows off some nice things you can do with Firefox,
509 Emacs, Org-mode and org-protocol.el.
511 It first shows how to create two bookmarklets, =org-remember= and
512 =org-store-link=. These bookmarklets enable your Firefox to talk to
513 emacsclient via a new protocol (=org-protocol://=); emacsclient then
514 parses the request and tells Emacs to remember or store stuff at the
515 relevant places in your Org files.
517 At the end of the screencast, we create two ubiquity commands from these
518 bookmarklets.  Now in Firefox =ALT-SPC org-remember RET= creates a note
519 in my Org files.