summaryrefslogtreecommitdiff
path: root/contrib/scripts/org-docco.org
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/scripts/org-docco.org')
-rw-r--r--contrib/scripts/org-docco.org206
1 files changed, 206 insertions, 0 deletions
diff --git a/contrib/scripts/org-docco.org b/contrib/scripts/org-docco.org
new file mode 100644
index 0000000..d846aa3
--- /dev/null
+++ b/contrib/scripts/org-docco.org
@@ -0,0 +1,206 @@
+#+Title: Org-Docco
+#+Author: Eric Schulte
+#+Style: <link rel="stylesheet" href="docco.css" type="text/css">
+#+Property: tangle yes
+
+The =docco= tool (see http://jashkenas.github.com/docco/) generates
+HTML from JavaScript source code providing an attractive side-by-side
+display of source code and comments. This file (see [[http://orgmode.org/w/?p=org-mode.git;a=blob_plain;f=contrib/scripts/org-docco.org;hb=HEAD][org-docco.org]])
+generates the same type of output from Org-mode documents with code
+embedded in code blocks.
+
+The way this works is an Org-mode document with embedded code blocks
+is exported to html using the standard Org-mode export functions.
+This file defines a new function named =org-docco-buffer= which, when
+added to the =org-export-html-final-hook=, will be run automatically
+as part of the Org-mod export process doccoizing your Org-mode
+document.
+
+A pure source code file can be extracted (or "/tangled/") from the
+Org-mode document using the normal =org-babel-tangle= function. See
+[[http://orgmode.org/manual/Working-With-Source-Code.html][Working With Source Code]] chapter of the Org-mode manual for more
+information on using code blocks in Org-mode files.
+
+*Disclaimer*: this currently only works on /very/ simple Org-mode
+files which have no headings but rather are just a collection of
+alternating text and code blocks. It wouldn't be difficult to
+generalize the following code so that it could be run in particular
+sub-trees but I simply don't have the time to do so myself, and this
+version perfectly satisfies my own limit needs. I make no promises to
+support this code moving forward. /Caveat Emptor/
+
+#+begin_src emacs-lisp :padline no
+;;; org-docco.el --- docco type html generation from Org-mode
+
+;; Copyright (C) 2012 Eric Schulte
+
+;; Author: Eric Schulte
+;; Keywords: org-mode, literate programming, html
+;; Homepage: http://orgmode.org/worg/org-contrib/org-mime.php
+;; Version: 0.01
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; <- look over there
+#+end_src
+
+The =cl= package provides all of the state-changing functions used
+below e.g., =push= and =incf=. It looks like a namespace-safe version
+of =cl= may soon be permissible for use in official Emacs packages.
+#+begin_src emacs-lisp
+;;; Code:
+(require 'cl)
+#+end_src
+
+This is a function which returns the buffer positions of matching
+regular expressions. It has two special features...
+1. It only counts matched instances of =beg-re= and =end-re= which are
+ properly nested, so for example if =beg-re= and =end-re= are set to
+ =(= and =)= respectively and we run this against the following,
+ : 1 2 3 4 5 6
+ : | | | | | |
+ : v v v v v v
+ : (foo (bar baz) (qux) quux)
+ it will return 1 and 6 rather than 1 and 3.
+2. It uses [[www.gnu.org/s/emacs/manual/html_node/elisp/Markers.html][markers]] which save their position in a buffer even as the
+ buffer is changed (e.g., by me adding in extra HTML text).
+#+begin_src emacs-lisp
+(defun org-docco-balanced-re (beg-re end-re)
+ "Return the beginning and of a balanced regexp."
+ (save-excursion
+ (save-match-data
+ (let ((both-re (concat "\\(" beg-re "\\|" end-re "\\)"))
+ (beg-count 0) (end-count 0)
+ beg end)
+ (when (re-search-forward beg-re nil t)
+ (goto-char (match-beginning 0))
+ (setq beg (point-marker))
+ (incf beg-count)
+ (goto-char (match-end 0))
+ (while (and (not end) (re-search-forward both-re nil t))
+ (goto-char (match-beginning 0))
+ (cond ((looking-at beg-re) (incf beg-count))
+ ((looking-at end-re) (incf end-count))
+ (:otherwise (error "miss-matched")))
+ (goto-char (match-end 0))
+ (when (= beg-count end-count) (setq end (point-marker))))
+ (when end (cons beg end)))))))
+#+end_src
+
+This ugly large function does the actual conversion. It wraps the
+entire main content =div= of the exported Org-mode html into a single
+large table. Each row of the table has documentation on the left side
+and code on the right side. This function has two parts.
+1. We use =(org-docco-balanced-re "<div" "</div>")= to find the
+ beginning and end of the main content div. We then break up this
+ div at =<pre></pre>= boundaries with multiple calls to
+ =(org-docco-balanced-re "<pre class\"src" "</pre>")=.
+2. With all documentation/code boundaries in hand we step through the
+ buffer inserting the table html code at boundary locations.
+#+begin_src emacs-lisp
+(defun org-docco-buffer ()
+ "Call from within an HTML buffer to doccoize it."
+ (interactive)
+ (let ((table-start "<table>\n")
+ (doc-row-start "<tr><th class=\"docs\">\n") (doc-row-end "</th>\n")
+ (code-row-start " <td class=\"code\">\n") (code-row-end "</td></tr>\n")
+ (table-end "</table>" )
+ pair transition-points next)
+ (save-excursion
+ (save-match-data
+ (goto-char (point-min))
+ (when (re-search-forward "<div id=\"content\">" nil t)
+ (goto-char (match-end 0))
+ (push (point-marker) transition-points)
+ (goto-char (match-beginning 0))
+ (setq pair (org-docco-balanced-re "<div" "</div>"))
+ (while (setq next (org-docco-balanced-re "<pre class=\"src" "</pre>"))
+ (goto-char (cdr next))
+ (push (car next) transition-points)
+ (push (cdr next) transition-points))
+ (goto-char (cdr pair))
+ (push (and (re-search-backward "</div>" nil t) (point-marker))
+ transition-points)
+ ;; collected transitions, so build the table
+ (setq transition-points (nreverse transition-points))
+ (goto-char (pop transition-points))
+ (insert table-start doc-row-start)
+ (while (> (length transition-points) 1)
+ (goto-char (pop transition-points))
+ (insert doc-row-end code-row-start)
+ (goto-char (pop transition-points))
+ (insert code-row-end doc-row-start))
+ (goto-char (pop transition-points))
+ (insert code-row-end table-end)
+ (unless (null transition-points)
+ (error "leftover points")))))))
+#+end_src
+
+We'll use Emacs [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html][File Local Variables]] and the
+=org-export-html-final-hook= to control which buffers have
+=org-docco-buffer= run as part of their export process.
+#+begin_src emacs-lisp
+ (defvar org-docco-doccoize-me nil
+ "File local variable controlling if html export should be doccoized.")
+ (make-local-variable 'org-docco-doccoize-me)
+#+end_src
+
+A simple function will conditionally process HTML output based on the
+value of this variable.
+#+begin_src emacs-lisp
+ (defun org-docco-buffer-maybe ()
+ (when org-docco-doccoize-me (org-docco-buffer)))
+#+end_src
+
+Finally this function is added to the =org-export-html-final-hook=.
+#+begin_src emacs-lisp
+ (add-hook 'org-export-html-final-hook #'org-docco-buffer-maybe)
+#+end_src
+
+That's it. To use this simply;
+1. Checkout this file from https://github.com/eschulte/org-docco,
+ : git clone git://github.com/eschulte/org-docco.git
+ and open it using Emacs.
+2. Tangle =org-docco.el= out of this file by calling
+ =org-babel-tangle= or =C-c C-v t=.
+3. Load the resulting Emacs Lisp file.
+4. Execute the following in any Org-mode buffer to add file local
+ variable declarations which will enable post-processed with
+ =org-docco-buffer=.
+ : (add-file-local-variable 'org-export-html-postamble nil)
+ : (add-file-local-variable 'org-export-html-style-include-default nil)
+ : (add-file-local-variable 'org-docco-doccoize-me t)
+ And add the following style declaration to make use of the
+ =docco.css= style sheet taken directly from
+ https://github.com/jashkenas/docco.
+ : #+Style: <link rel="stylesheet" href="docco.css" type="text/css">
+
+#+begin_src emacs-lisp
+(provide 'org-docco)
+;;; org-docco.el ends here
+#+end_src
+
+# Local Variables:
+# org-export-html-postamble: nil
+# org-export-html-style-include-default: nil
+# org-docco-doccoize-me: t
+# End: