vendredi 4 septembre 2015

org-mode live html export preview in the browser

Using the MozRepl Firefox extension along with Emacs moz.el package you can export your current org document to html on each buffer change or on each save. There's a bunch of JS code to make Firefox resuse existing tabs instead of opening new ones. Run M-x toggle-live-preview or M-x toggle-preview-on-save depending on what you want.
(defvar moz-useful-functions "
function find_tab_with_url(url) {
    var bs = gBrowser.browsers
    for (var i = 0; i < bs.length; i++) {
 try {
     if (bs[i].currentURI.spec == url)
  return i
 } catch (e) {}
    }
    return -1
}

function select_tab(t) {
    if (gBrowser.selectedTab != t)
        gBrowser.selectedTab = t
}

function add_or_reload_url (url) {
    var i = find_tab_with_url(url)
    var t = ''
    if (i < 0) {
 t = gBrowser.addTab(url)
    } else {
 gBrowser.browsers[i].reload()
        t = gBrowser.tabs[i]
    }
    select_tab(t) 
}
")

(defun preview-buffer-in-firefox ()
  (interactive)
  (require 'moz)
  (moz-send-string moz-useful-functions)
  (let ((fn (org-html-export-to-html)))
    (moz-send-string (concat "add_or_reload_url(\"file://" (expand-file-name fn) "\");\n"))))

(defun live-preview (&optional beg end len)
  (when (or (not (and beg end len)) (and beg end len (/= (1+ (- end beg)) len)))
    (message "%s: update!" (format-time-string "%r"))
    (preview-buffer-in-firefox)))

(defun toggle-live-preview ()
  (interactive)
  (if (memq 'live-preview first-change-hook)
      (remove-hook 'first-change-hook 'live-preview 'buffer-local)
    (add-hook 'first-change-hook 'live-preview nil 'buffer-local)))

(defun toggle-preview-on-save ()
  (interactive)
  (if (memq 'live-preview after-save-hook)
      (remove-hook 'after-save-hook 'live-preview 'buffer-local)
    (add-hook 'after-save-hook 'live-preview nil 'buffer-local)))