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)})()