An alternative approach to including org-source in blog posts

| categories: orgmode | tags:

When you publish a Matlab m-file to HTML, Matlab includes the m-file source as an html comment in the output. They also provide a nice function called grabcode that will take a url, and open the source code in the editor. Today, we try a similar approach for org-mode.

This post is not totally self-contained. I have my own emacs-lisp module that converts org-mode to blogofile posts, and so far I have not made it broadly available. This is also a super exploratory idea, so I am just going to show the changes I need to make to my setup to get to the evaluation of the idea.

The idea is pretty simple, we just insert the current buffer string into an HTML comment. I just modify the bf-get-post-html function lightly to do that. This is a somewhat pathological example since there are html comments in the post! So, we will encode all the dashes to get around that.

(require 'browse-url)
(defun bf-get-post-html ()
  "Return a string containing the YAML header, the post html, my
copyright line, and a link to the org-source code."
  (interactive)
  (let ((org-source (buffer-string))
        (url-to-org (bf-get-url-to-org-source))
        (yaml (bf-get-YAML-heading))
        (body (bf-get-HTML)))

    (with-temp-buffer
      (insert yaml)
      (insert body)
      (insert
       (format "<p>Copyright (C) %s by John Kitchin. See the <a href=\"/copying.html\">License</a> for information about copying.<p>"
               (format-time-string "%Y")))
      (insert (format "<p><a href=\"%s\">org-mode source</a><p>"
                      url-to-org))
      (insert (format "<p>Org-mode version = %s</p>" (org-version)))
      ;; this is the only new code we need to add.
      (insert (format "
<!--
  ##### SOURCE BEGIN #####
%s
##### SOURCE END #####
-->" (browse-url-url-encode-chars org-source "[-]")))
      ;; return value
      (buffer-string))))

By itself, that has limited value to me. So, let's also create a grab-org-source function to get the embedded source and open it in a buffer. This might be a naive approach, we just use a regexp to find the source boundaries and open it in a new buffer. We have to unescape the dashes, which appear as %2D in the comments. Here is our function.

(defun grab-org-source (url)
  "Extract org-source from URL to a buffer named *grab-org-source*."
  (interactive "sURL: ")
  (switch-to-buffer (get-buffer-create "*grab-org-source*"))
  (erase-buffer)
  (org-mode)
  (insert
   (with-current-buffer
       (url-retrieve-synchronously url)
     (let (start)
       (re-search-forward
        "
<!--
  ##### SOURCE BEGIN #####
" nil t)
       (setq start (point))
       (re-search-forward "##### SOURCE END #####
-->" nil t)
       (buffer-substring start (match-beginning 0)))))
  (goto-char (point-min))
  (while (search-forward "%2D" nil t)
    (replace-match "-"))
  (goto-char (point-min)))

This concludes my basic proof of concept. I think there is a general escaping challenge in this approach, because it isn't clear if you can put really arbitrary stuff in an html comment, e.g. you cannot put –>! I am going to try incorporating this into my posts and see what other issues come up in the future.

Copyright (C) 2015 by John Kitchin. See the License for information about copying.

org-mode source

Org-mode version = 8.2.10

Discuss on Twitter