summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Schulte <eric.schulte@gmx.com>2012-04-20 12:21:50 -0400
committerEric Schulte <eric.schulte@gmx.com>2012-04-20 12:21:50 -0400
commit66ae794a669a0d4839ed2b5f03a0f4346191ce75 (patch)
tree6f5689d3df1d16dfc3047732230ce473f103aa18
parent3f427d92c89a979b6948782ee133a85b8c167660 (diff)
downloadorg-mode-66ae794a669a0d4839ed2b5f03a0f4346191ce75.tar.gz
contrib/org-docco.org -- docco side-by-side HTML export of annotated source code
for an example of the code output see http://eschulte.github.com/org-docco/org-docco.html
-rw-r--r--contrib/scripts/docco.css185
-rw-r--r--contrib/scripts/org-docco.org206
2 files changed, 391 insertions, 0 deletions
diff --git a/contrib/scripts/docco.css b/contrib/scripts/docco.css
new file mode 100644
index 0000000..9030b6c
--- /dev/null
+++ b/contrib/scripts/docco.css
@@ -0,0 +1,185 @@
+/*--------------------- Layout and Typography ----------------------------*/
+body {
+ font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+ font-size: 15px;
+ line-height: 22px;
+ color: #252519;
+ margin: 0; padding: 0;
+}
+a {
+ color: #261a3b;
+}
+ a:visited {
+ color: #261a3b;
+ }
+p {
+ margin: 0 0 15px 0;
+}
+h1, h2, h3, h4, h5, h6 {
+ margin: 0px 0 15px 0;
+}
+ h1 {
+ margin-top: 40px;
+ }
+#container {
+ position: relative;
+}
+#background {
+ position: fixed;
+ top: 0; left: 525px; right: 0; bottom: 0;
+ background: #f5f5ff;
+ border-left: 1px solid #e5e5ee;
+ z-index: -1;
+}
+#jump_to, #jump_page {
+ background: white;
+ -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
+ -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
+ font: 10px Arial;
+ text-transform: uppercase;
+ cursor: pointer;
+ text-align: right;
+}
+#jump_to, #jump_wrapper {
+ position: fixed;
+ right: 0; top: 0;
+ padding: 5px 10px;
+}
+ #jump_wrapper {
+ padding: 0;
+ display: none;
+ }
+ #jump_to:hover #jump_wrapper {
+ display: block;
+ }
+ #jump_page {
+ padding: 5px 0 3px;
+ margin: 0 0 25px 25px;
+ }
+ #jump_page .source {
+ display: block;
+ padding: 5px 10px;
+ text-decoration: none;
+ border-top: 1px solid #eee;
+ }
+ #jump_page .source:hover {
+ background: #f5f5ff;
+ }
+ #jump_page .source:first-child {
+ }
+table td {
+ border: 0;
+ outline: 0;
+}
+ td.docs, th.docs {
+ max-width: 450px;
+ min-width: 450px;
+ min-height: 5px;
+ padding: 10px 25px 1px 50px;
+ overflow-x: hidden;
+ vertical-align: top;
+ text-align: left;
+ }
+ .docs pre {
+ margin: 15px 0 15px;
+ padding-left: 15px;
+ }
+ .docs p tt, .docs p code {
+ background: #f8f8ff;
+ border: 1px solid #dedede;
+ font-size: 12px;
+ padding: 0 0.2em;
+ }
+ .pilwrap {
+ position: relative;
+ }
+ .pilcrow {
+ font: 12px Arial;
+ text-decoration: none;
+ color: #454545;
+ position: absolute;
+ top: 3px; left: -20px;
+ padding: 1px 2px;
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ }
+ td.docs:hover .pilcrow {
+ opacity: 1;
+ }
+ td.code, th.code {
+ padding: 14px 15px 16px 25px;
+ width: 100%;
+ vertical-align: top;
+ border-left: 1px solid #e5e5ee;
+ }
+ pre, tt, code {
+ font-size: 12px; line-height: 18px;
+ font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
+ margin: 0; padding: 0;
+ }
+
+
+/*---------------------- Syntax Highlighting -----------------------------*/
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
+body .hll { background-color: #ffffcc }
+body .c { color: #408080; font-style: italic } /* Comment */
+body .err { border: 1px solid #FF0000 } /* Error */
+body .k { color: #954121 } /* Keyword */
+body .o { color: #666666 } /* Operator */
+body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
+body .cp { color: #BC7A00 } /* Comment.Preproc */
+body .c1 { color: #408080; font-style: italic } /* Comment.Single */
+body .cs { color: #408080; font-style: italic } /* Comment.Special */
+body .gd { color: #A00000 } /* Generic.Deleted */
+body .ge { font-style: italic } /* Generic.Emph */
+body .gr { color: #FF0000 } /* Generic.Error */
+body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+body .gi { color: #00A000 } /* Generic.Inserted */
+body .go { color: #808080 } /* Generic.Output */
+body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+body .gs { font-weight: bold } /* Generic.Strong */
+body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+body .gt { color: #0040D0 } /* Generic.Traceback */
+body .kc { color: #954121 } /* Keyword.Constant */
+body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
+body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
+body .kp { color: #954121 } /* Keyword.Pseudo */
+body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
+body .kt { color: #B00040 } /* Keyword.Type */
+body .m { color: #666666 } /* Literal.Number */
+body .s { color: #219161 } /* Literal.String */
+body .na { color: #7D9029 } /* Name.Attribute */
+body .nb { color: #954121 } /* Name.Builtin */
+body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
+body .no { color: #880000 } /* Name.Constant */
+body .nd { color: #AA22FF } /* Name.Decorator */
+body .ni { color: #999999; font-weight: bold } /* Name.Entity */
+body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+body .nf { color: #0000FF } /* Name.Function */
+body .nl { color: #A0A000 } /* Name.Label */
+body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+body .nt { color: #954121; font-weight: bold } /* Name.Tag */
+body .nv { color: #19469D } /* Name.Variable */
+body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+body .w { color: #bbbbbb } /* Text.Whitespace */
+body .mf { color: #666666 } /* Literal.Number.Float */
+body .mh { color: #666666 } /* Literal.Number.Hex */
+body .mi { color: #666666 } /* Literal.Number.Integer */
+body .mo { color: #666666 } /* Literal.Number.Oct */
+body .sb { color: #219161 } /* Literal.String.Backtick */
+body .sc { color: #219161 } /* Literal.String.Char */
+body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
+body .s2 { color: #219161 } /* Literal.String.Double */
+body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+body .sh { color: #219161 } /* Literal.String.Heredoc */
+body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+body .sx { color: #954121 } /* Literal.String.Other */
+body .sr { color: #BB6688 } /* Literal.String.Regex */
+body .s1 { color: #219161 } /* Literal.String.Single */
+body .ss { color: #19469D } /* Literal.String.Symbol */
+body .bp { color: #954121 } /* Name.Builtin.Pseudo */
+body .vc { color: #19469D } /* Name.Variable.Class */
+body .vg { color: #19469D } /* Name.Variable.Global */
+body .vi { color: #19469D } /* Name.Variable.Instance */
+body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file
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: