Inline tasks: Play along with archiving, refiling, and footnotes, store link.
[org-mode.git] / contrib / lisp / org-annotation-helper.el
blobc90233fe2884a015b30b108c6acdc7784efccc2b
1 ;;; org-annotation-helper.el --- start remember from a web browser
2 ;;
3 ;; Author: bzg AT altern DOT org
4 ;; Author: dmg AT uvic DOT org
5 ;;
6 ;; Keywords: org remember
7 ;;
8 ;; Version 0.4, Feb 24, 2009
9 ;; - Patch by David Moffat to force activation of region
11 ;; Version 0.3b, Sept 18, 2008
12 ;; - Added one entry to FAQ
14 ;; Version 0.3a, June 3, 2008
15 ;; - org-fied the FAQ, and fixed typos/grammar. Big thanks to Nick Dokos.
16 ;; - Added a new file: README
18 ;; Version 0.3, May 23, 2008
19 ;;
20 ;; - Simplified call to org-remember by using %w template (thanks to Carsten
21 ; Dominik)
22 ;; - Improved documentation (thanks to Nick Dokos and John Rakestraw for this)
23 ;; - Created a standalone file for the org-annotation-helper script
24 ;; - Added org-annotation-helper.html with a FAQ and quick links to the bookmarkets
26 ;; Version 0.2, May 18, 2008
28 ;;; Commentary:
30 ;; [bzg:] This is an adapted version of the planner-mode extension the
31 ;; was first posted by Geert Kloosterman <g.j.kloosterman@gmail.com> on
32 ;; the Planner mailing list.
34 ;; [dmg:] I have updated and extended the function to allow for
35 ;; handling of the selection (it is now available as a region, so it
36 ;; can be used in a template using %:region )
39 ;; We want to be able to pass a URL and document title directly from a
40 ;; web browser to Emacs.
42 ;; The idea is to educate the browser about two new protocols "remember"
43 ;; and "annotation", so that when it is asked to handle URLs with these
44 ;; protocols, it will execute a shell script and pass some information
45 ;; to it (the URL of the page it's on, the title and, in the case of the
46 ;; remember protocol, the current selection on that page, if any.)
48 ;; The handlers are invoked using bookmarklets (fake bookmarks whose
49 ;; "location" is some javascript code: when the bookmarklet is
50 ;; activated, the javascript code is executed.) The bookmarklets
51 ;; create remember:// or annotation:// URLs dynamically.
53 ;; When a handler is invoked, it executes a shell script to handle the
54 ;; protocol and passes it the gathered information in a standard
55 ;; format. The script, in turn, passes the information to a running
56 ;; Emacs process (using emacsclient/gnuclient), calling the function
57 ;; bzg/org-annotate-helper, which is what this file provides.
59 ;; The protocol types currently recognized and the corresponding actions
60 ;; of bzg/org-annotate-helper are:
61 ;;
62 ;; remember:// assuming you have set up an appropriate remember
63 ;; template (see below), start `remember' with the
64 ;; url, title and current selection filled in
66 ;; annotation:// make an org link out of the url and the title and
67 ;; glom it onto the kill ring, from where it can be
68 ;; retrieved either with a yank or through
69 ;; org-insert-link.
71 ;; The urls used internally have the following form:
73 ;; remember://<the web page url>::remember::<the title>::remember::<selection>
75 ;; or
77 ;; annotation://<the web page url>::remember::<the title>
79 ;; The url, title and selection (if present) will be url-hex-encoded.
82 ;;======================================================================
84 ;; Here are the pieces you'll need, to set up the bits outside emacs.
87 ;; The javascript code for the two bookmarklets:
89 ;;----------------------------------------------------------------------
90 ;; javascript:location.href='remember://' + location.href + '::remember::' + escape(document.title) + '::remember::' + escape(window.getSelection())
91 ;;----------------------------------------------------------------------
92 ;; javascript:location.href='annotation://' + location.href + '::remember::' + escape(document.title)
93 ;;----------------------------------------------------------------------
96 ;; The shell script that the handlers execute:
98 ;;----------------------------------------------------------------------
99 ;; #!/bin/sh
100 ;; # org-annotation-helper -- pass a {remember,annotation}-url to emacs
101 ;; #
102 ;; # Author: Geert Kloosterman <g.j.kloosterman@gmail.com>
103 ;; # Date: Sat Nov 19 22:33:18 2005
105 ;; if [ -z "$1" ]; then
106 ;; echo "$0: Error: no arguments given!" 1>&2
107 ;; exit 1
108 ;; fi
110 ;; # To test uncomment following line
111 ;; #echo $1 >> /tmp/remember.out
113 ;; emacsclient --eval "(progn (bzg/org-annotation-helper \"$1\" ) nil)"
114 ;;----------------------------------------------------------------------
117 ;;======================================================================
119 ;; Installation.
121 ;; Step 0: Install this module.
123 ;; * Install this file and require it in your .emacs:
125 ;; (require 'org-annotation-helper)
127 ;; * Add the following line to your .emacs if it's not there already:
129 ;; (server-start)
132 ;; Step 1: Install the org-annotation-helper shell script and add
133 ;; a remember template.
135 ;; * Save the shell script in a file in some directory in your $PATH,
136 ;; and make sure it is executable. In the following, it is assumed
137 ;; that the file name is "org-annotation-helper".
139 ;; * Add a ?w `remember template' to org-remember-templates. You can
140 ;; start by using this template:
142 ;; (?w "* %u %c \n\n%:region" "~/working/trunk/org/bookmarks.org" "Web links")
144 ;; See section 9.2 of the Org manual for information about
145 ;; `remember templates'.
147 ;; "%u" will be replaced by a timestamp, "%c" will be replaced with
148 ;; the link to the page and labelled with the title of the page, and
149 ;; "%:region" will be replaced with the selected text from the
150 ;; browser. By default, the new remember notes are placed in the
151 ;; bookmarks.org file under the "Web links" section, but that can be
152 ;; easily overriden with C-u C-c C-c.
154 ;; * Try the setup so far:
156 ;; Make sure emacs is running and you have started its server
157 ;; mode: ``M-x server-start<RET>'' should do it.
159 ;; Run this command from the command line:
161 ;; org-annotation-helper 'remember://http%3A//orgmode.org/::remember::Org-Mode%20Homepage::remember::Notes'
163 ;; Assuming you used the template above, you should be looking at
164 ;; a *Remember* buffer that looks like this (minor variations are
165 ;; possible because of local customizations - the last three lines
166 ;; of the output are the important one and should be identical):
168 ;; ## Filing location: Select interactively, default, or last used:
169 ;; ## C-u C-c C-c to select file and header location interactively.
170 ;; ## C-c C-c "~/working/trunk/org/bookmarks.org" -> "* Web links"
171 ;; ## C-u C-u C-c C-c "~/working/trunk/org/bookmarks.org" -> "* Web links"
172 ;; ## To switch templates, use `C-c r'. To abort use `C-c C-k'.
174 ;; * [2008-05-21 Wed] [[http://orgmode.org/][Org-Mode Homepage]]
176 ;; Notes
178 ;; Assuming that everything is OK, the script and emacs side of the setup are done.
181 ;; Step 2: Browser set-up - add two bookmarklets.
183 ;; Note: see the file org-annotation-helper-faq.html for a simpler way to add
184 ;; these bookmarklets
186 ;; [Firefox specific]
188 ;; * Create a new bookmark, e.g by selecting Bookmarks/Organize bookmarks... and clicking
189 ;; on "New Bookmark". In the "Properties" pop-up, give it a unique name.
190 ;; * In the "Location" field, fill in the first line of javascript code above.
191 ;; * Make sure "Load this bookmark in the sidebar" is deselected and click "OK".
193 ;; * Lather, rinse, repeat for the second line of javascript code.
195 ;; Try the two bookmarklets. You should get error pop-ups about
196 ;; unknown protocols "remember" or "annotation", because your browser
197 ;; will not know what do to with them yet (but see the Firefox 3
198 ;; section below, if you are running that browser).
200 ;; You can also look at org-annotation-helper.html for a simple way to add both.
202 ;; Step 3: Browser set-up - add the protocol handlers for the
203 ;; "remember://" and "annotation://" URIs.
205 ;; [Firefox]
207 ;; To add a protocol handler (eg: remember://) in Firefox, take the
208 ;; following steps:
210 ;; * For Firefox 2, type "about:config" in the location bar, right
211 ;; click to get the pop-up menu, select New --> String, and in the
212 ;; name field, enter "network.protocol-handler.app.remember".
214 ;; In Firefox 3, when you first click on the button associated with
215 ;; the bookmarklet, you should get a pop-up asking if you'd like to
216 ;; associate the bookmarklet with a particular file. Use the
217 ;; file-select process to navigate to the org-annotation-helper
218 ;; script and select it. You can still edit the about:config
219 ;; list directly as in Firefox 2.
221 ;; * the value should be the name of the file containing the shell
222 ;; script, e.g. in Step 1, we called it "org-annotation-helper".
223 ;; At least under Linux this does not need to be the full path to
224 ;; the script.
227 ;; * Lather, rinse, repeat for the annotation protocol. The string to
228 ;; add is, in this case, "network.protocol-handler.app.annotation",
229 ;; and the script is the same as
231 ;; You should have two new entries like this:
233 ;; network.protocol-handler.app.annotation user set string <path>
234 ;; network.protocol-handler.app.remember user set string <path>
236 ;; where <path> is the location where org-annotation-helper is
237 ;; for example, in my case it is /home/dmg/bin/org-annotation-helper
239 ;; See http://kb.mozillazine.org/Register_protocol for more details.
241 ;; [Opera]
243 ;; In Opera add the protocol in the Preferences->Advanced->Programs
244 ;; dialog.
247 ;; Step 4: At this point, activating the bookmarklets should invoke
248 ;; the shell script, which will invoke the
249 ;; bzg/org-annotation-helper function (below), which will do one of
250 ;; two things: for a remember:// URL, it will bring up a *Remember*
251 ;; buffer; for an annotation:// URL, it will squirrel away a link
252 ;; that you can use with C-c C-l.
255 ;; Debugging notes: if there are problems, it might be useful to run
256 ;; the shell script from the command line (see Step 1 above); it might
257 ;; also be useful to uncomment the "echo" line in the shell
258 ;; script. That will dump the script's argument in /tmp/remember.out,
259 ;; so you can figure out if the browser is passing the right stuff to
260 ;; the script. If it does pass the right stuff, then the emacs side
261 ;; probably has a problem; if not, then the browser side is the likely
262 ;; suspect.
264 (require 'url)
266 (autoload 'url-unhex-string "url")
268 (defun bzg/org-annotation-helper (info)
269 "Process an externally passed remember:// style url.
271 URLSTRING consists of a protocol part and a url and title,
272 separated by ::remember::
274 The protocol types currently recognized are:
276 remember:// start `remember' with the url, title and selection (if any).
277 annotation:// squirrel away a link of the form [[url][title]] that can
278 be used later with \\[org-insert-link]."
279 (interactive)
280 (let ((remember-annotation-functions nil))
281 ;; The `parse-url' functions break on the embedded url,
282 ;; since our format is fixed we'll split the url ourselves.
283 (if (string-match "^\\([^:]*\\):\\(/*\\)\\(.*\\)" info)
284 (let* ((b (get-buffer-create "*org-ann*"))
285 (proto (match-string 1 info))
286 (url_title_region (match-string 3 info))
287 (splitparts (split-string url_title_region "::remember::"))
288 (url (url-unhex-string (car splitparts)))
289 (type (if (string-match "^\\([a-z]+\\):" url)
290 (match-string 1 url)))
291 (title (cadr splitparts))
292 (region (url-unhex-string (caddr splitparts)))
293 orglink)
294 (setq title (if (> (length title) 0) (url-unhex-string title)))
295 (setq orglink (org-make-link-string url title))
296 (org-store-link-props :type type
297 :link url
298 :region region
299 :description title)
300 (setq org-stored-links
301 (cons (list url title) org-stored-links))
302 ;; FIXME can't access %a in the template -- how to set annotation?
303 (raise-frame)
304 (cond ((equal proto "remember")
305 (kill-new orglink)
306 (set-buffer b)
307 (set-mark (point))
308 (insert region)
309 (exchange-point-and-mark t) ;; activate region.. not always on by default
310 (org-remember nil ?w)
311 (kill-buffer b)
313 ((equal proto "annotation")
314 (message "Copied '%s' to the kill-ring." orglink)
315 (kill-new orglink))
316 (t (error "unrecognized org-helper protocol"))))
317 (error "could not parse argument")))
321 (provide 'org-annotation-helper)