org-protocol
How I make a quick post from from Chrome via org-protocol.
Set up org-protocol
Follow the
org-protocol
install instructions. In addition to the Emacs and Gnome setup
sections, I followed these instructions
to get xdg-open
working. I had to hack xdg-open
because of
this bug.
I copied the existing one to ~/bin/
and added a couple lines based on
this hack
diff -u /usr/bin/xdg-open ~/bin/xdg-open --- /usr/bin/xdg-open 2011-10-03 21:49:38.000000000 -0700 +++ /home/foo/bin/xdg-open 2013-03-04 15:26:38.399395783 -0800 @@ -358,10 +358,16 @@ open_gnome() { - if gvfs-open --help 2>/dev/null 1>&2; then - gvfs-open "$1" - else - gnome-open "$1" + # Handle org-protocol + if (echo "$1" | grep -q '^org-protocol://'); then + echo "emacsclient $1" + emacsclient "$1" + else + if gvfs-open --help 2>/dev/null 1>&2; then + gvfs-open "$1" + else + gnome-open "$1" + fi fi if [ $? -eq 0 ]; then @@ -411,5 +417,11 @@ open_generic() { + # Handle org-protocol + if (echo "$1" | grep -q '^org-protocol://'); then + emacsclient "$1" + exit_success + fi + # Paths or file:// URLs if (echo "$1" | grep -q '^file://' || ! echo "$1" | egrep -q '^[a-zA-Z+\.\-]+:'); then
Set up chrome.
I tested with the store-link
sub-protocol that everyone seems to
use. Once that's known to work, we can add our own version that
creates a new post.
Add a custom sub-protocol to create a new post.
(defun mumblr-create-post-from-link () "Create a new post from a link passed in via org-protocol.") (defun org-protocol-remember2 (info) (if (and (boundp 'org-stored-links) (fboundp 'org-remember)) (let* ((parts (org-protocol-split-data info t)) (template (or (and (= 1 (length (car parts))) (pop parts)) org-protocol-default-template-key)) (url (org-protocol-sanitize-uri (car parts))) (type (if (string-match "^\\([a-z]+\\):" url) (match-string 1 url))) (title (or (cadr parts) "")) (region (or (caddr parts) "sfsfsf")) (orglink (org-make-link-string url (if (string-match "[^[:space:]]" title) title url))) remember-annotation-functions) (setq org-stored-links (cons (list url title) org-stored-links)) (kill-new orglink) (org-store-link-props :type type :link url :description title :region region) ;;(raise-frame) (select-frame-set-input-focus (selected-frame)) (org-remember nil (string-to-char template)) (lower-frame) ;;(delete-frame) ; uncomment this if you use -c in the call to emacsclient ) (message "Org-mode not loaded.")) nil) (defun org-protocol-outlook (info) (if (and (boundp 'org-stored-links) (or (fboundp org-outlook-capture)) (org-protocol-do-outlook-capture info org-outlook-capture)) (message "Org-mode not loaded.")) nil) (setq org-stored-links '()) (defun org-protocol-do-outlook-capture (info capture-func) "Support `org-capture' and `org-remember' alike. CAPTURE-FUNC is either the symbol `org-remember' or `org-capture'." (let* ((parts (org-protocol-split-data info t)) (template (or (and (= 1 (length (car parts))) (pop parts)) org-outlook-protocol-default-template-key)) (url (concat "outlook:" (org-protocol-sanitize-uri (car parts)))) (type (if (string-match "^\\([a-z]+\\):" url) (match-string 1 url))) (title (or (cadr parts) "")) (sender (or (caddr parts) "")) (sender-email (or (cadddr parts) "")) (region "") (orglink (org-make-link-string url (if (string-match "[^[:space:]]" (format "%s (%s)" title sender)) (format "%s (%s)" title sender) url))) (org-capture-link-is-already-stored t) ;; avoid call to org-store-link remember-annotation-functions) ;(with-temp-buffer ; (clipboard-yank) ; (setq region (buffer-substring (point-min) (point-max)))) (setq org-stored-links (cons (list url title) org-stored-links)) (kill-new orglink) (org-store-link-props :type type :link url :sender sender :sender-email sender-email :description title :title title :annotation orglink ;:initial region ) (raise-frame) (funcall capture-func nil template))) (add-to-list 'org-protocol-protocol-alist '(("mumblr-post" :protocol "mumblr" :function mumblr-create-post-from-link)))
Add a bookmarklet for the new sub-protocol
I simplified this JS for getting the selection HTML to something small but Chrome-only.
(All on one line)
javascript:location.href='org-protocol://image-post://'+ encodeURIComponent(location.href)+'/'+ encodeURIComponent(document.title)+'/'+ encodeURIComponent(window.getSelection()) javascript:(function() { var html = ''; var sel = window.getSelection(); if (sel.rangeCount > 0) { var range = sel.getRangeAt(0); var clone = range.cloneContents(); var div = document.createElement('div'); div.appendChild(clone); html = div.innerHTML; } location.href='org-protocol://image-post://'+ encodeURIComponent(location.href)+'/'+ encodeURIComponent(document.title)+'/'+ encodeURIComponent(html); }()) javascript:(function(){function%20R(w){try{var%20d=w.document,j,i,t,T,N,b,r=1,C;for(j=0;t=["object","embed","applet","iframe"][j];++j){T=d.getElementsByTagName(t);for(i=T.length-1;(i+1)&&(N=T[i]);--i)if(j!=3||!R((C=N.contentWindow)?C:N.contentDocument.defaultView)){b=d.createElement("div");b.style.width=N.width;%20b.style.height=N.height;b.innerHTML="%3Cdel%3E"+(j==3?"third-party%20"+t:t)+"%3C/del%3E";N.parentNode.replaceChild(b,N);}}}catch(E){r=0}return%20r}R(self);var%20i,x;for(i=0;x=frames[i];++i)R(x)})()