Org-Protocol
Org-protocol is an extension to Org Mode that allows you to send information to Emacs from web browsers. You can use it to save a bookmark in Org Mode, save a selected text as a note, or insert a link to the current web page. This post describes how to configure org-protocol to accomplish those tasks from Chrome.
Configuring org-protocol
Org-protocol is installed as part of org layer of Spacemacs, but it is not enabled by default. To enable org-protocol, add org-protocol to org-modules variable.
Integration with the desktop
You also have to add a scheme handler to your desktop environment. This subsection describes an instruction for Cinnamon.
Add ~/.local/share/applications/emacsclient.desktop file with the following content:
[Desktop Entry]
Name=Emacsclient
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol
Add the following entry to Default Applications section in your ~/.local/share/applications/mimeapps.list:
x-scheme-handler/org-protocol=emacsclient.desktop
Run update-desktop-database program.
I automated this process as an Ansible role. My org-protocol role consists of the following files:
- A meta file containing dependencies which installs emacsclient.desktop file
- A task to add an entry to mimeapps.list
- A handler to run update-desktop-database
For other desktop environments, follow a corresponding section in the documentation.
Org-capture templates
I configured the following org-capture templates for org-protocol:
- A quote from the web page via org-protocol: Select text in the web page, and add it to my Org file for notes
- A bookmark via org-protocol: Add a bookmark of the web page to an Org file
Add the following entries to org-capture-templates variable:
("Pn" "(Protocol quote)" entry (file+headline my/captured-notes-file "Notes from the web")
"* %:description\nCaptured at %u\n%c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n%?")
("Pb" "(Protocol bookmark)" entry (file+datetree my/browser-bookmarks-file)
"* %:description \nCaptured at %U\n[[%:link][%:description]]\n%?\n")
The file names in the templates are defined as constants:
(defconst my/captured-notes-file "~/org/todo/NotesInbox.org")
(defconst my/browser-bookmarks-file "~/org/seq/BrowserBookmarks.org")
Browser integration
To create a bookmark, add a note, or store a link, you have to somehow generate links under org-protocol scheme in your browser. In Chrome (Chromium), there are the following solutions for this task:
- Create custom bookmarklets to invoke org-protocol
- Use org-capture extension from the Chrome web store
- Use a Chrome extension to run custom JavaScript
org-capture extension seems to be rather limited, so I have decided to install a Chrome extension that can run any user JavaScript. I found an extension named ShortKeys, which runs custom JavaScript with a shortcut key. For mouse operations, I also created bookmarklets for some of the operations.
Storing a link
Add a shortcut to ShortKeys with the following JavaScript:
location.href ='org-protocol://store-link?url=' +encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title);
Shortcut keys configured by ShortKeys do not work on some web pages, e.g. Chrome Web Store. Even in such situations, you can still use a bookmarklet instead. Create a bookmark with the following URL:
javascript:location.href ='org-protocol://store-link?url=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title);
The default handler does not raise the Emacs frame. You probably want to insert the stored link immediately, so add the following advice to your init.el:
(defun my-org-protocol-store-link-advice (orig &rest args)
(raise-frame)
(apply orig args))
(advice-add 'org-protocol-store-link :around
#'my-org-protocol-store-link-advice)
You can use either the shortcut key or the bookmarklet to store a link to the current web page via org-protocol. Then you can use org-insert-last-stored-link (C-c M-l) or helm-kill-ring to insert the stored link.
Creating a bookmark
ShortKeys:
location.href = 'org-protocol://capture?template=Pb&url='+
encodeURIComponent(location.href) + '&title=' +
encodeURIComponent(document.title)
Bookmarklet:
javascript:location.href = 'org-protocol://capture?template=Pb&url='+
encodeURIComponent(location.href) + '&title=' +
encodeURIComponent(document.title)
Quoting text as a note
ShortKeys:
var selText = getSelection().toString();
if (selText) {
location.href = 'org-protocol://capture?template=Pn&url='+
encodeURIComponent(location.href) + '&title=' +
encodeURIComponent(document.title) + '&body=' +
encodeURIComponent(selText);
} else {
alert("To add a quote, select a range in the web page.");
}
I haven’t created a bookmarklet for this task.
Wrapping up
Now you can store a link, create a bookmark, or quote a web page in Org Mode from the Chrome web browser. It is quite convenient.