;;;; Currently [[hs:sym]] --> HyperSpecRoot/sym but this will not work as
;;;; hyperspec pages are unfortunately not named according to the symbol they
+;;;; * table of slots at beginning of each class def
+;;;; * reverse auto-doc:
+;;;; CLOD annotates org file to 'mark up' doc strings for each
+;;;; CLOD can then READ an org file and LOAD docstrings into entities.
+;;;; Write initial docs in lisp (optional)
+;;;; Run CLOD, produce org file
+;;;; Later, after changes in source:
+;;;; Suck org file back into clod, then re-export to org again. The org
+;;;; file will contain updated doc string markers.
-;;;; todo table of slots at beginning of each class def
;;;; Generate documentation for this package with:
;;;; (clod:document-package :clod "~/lisp/clod/doc/clod-doc.org"
'Description'. However, if you don't want this to happen, but rather want
the docstring to define its own heading names, make sure that the very first
thing in the docstring is a heading (straight after the opening quote).
+ (Note for mmm-mode users (see below): if the docstring starts with '###'
+ to signal that it is in fact a docstring, CLOD will skip the hashes before
+ looking to see if the string starts with a heading.)
+ So '=\"###* Arguments ...\"=' will work in that case.
- Some symbol names used by common lisp can conflict with the markup used
by org mode. For example, =*global-variable*=: asterisks are interpreted
by org mode as signifying bold text. CLOD catches these in headings and
semicolons =;;;= are assumed to be example lisp source code. The first 3
semicolons are removed and the rest of the line is syntax highlighted.
+* Combining org mode and common lisp mode in a single Emacs buffer
+You can use org mode markup within docstrings, but you can't see the effects of
+the markup until you export the documentation to org using CLOD. You also don't
+get access to org's support for automatic formatting of bulleted lists as you
+write, or the fantastic support for writing tables, or hyperlinks that you can
+click with the mouse, or ....
-Here is the docstring for [[document-package]].
+What if you could use all the goodness of Org, while editing docstrings in your
+lisp source code? You can. This section explains how.
+1. Download and install nXhtml, an emacs package that contains code allowing
+ multiple major modes to be active in a single buffer.
+2. Add the code in `mmm-clod.el' to your .emacs file. Make sure you change
+ the mmm-mode directory to the directory where you installed mmm-mode.
+3. Restart emacs. Load a lisp source file. All documentation strings should
+ appear with a coloured background, and when you move the cursor inside them,
+ you will see 'Lisp[Org]' on the modeline.
+4. If not everything is highlighting correctly, or if you write a new docstring
+ and org does not activate within it, press control-` to 'refresh' mmm-mode.
+Not everything works: expanding and collapsing headings fails, and
+clicking the mouse elsewhere within the doc string often causes problems. But
+overall the two modes work together surprisingly well.
+MMM-mode recognises the following things as doc strings:
+1. Any string that emacs fontifies using 'font-lock-doc-face'. (in other words,
+ font-lock mode must be active.)
+2. Any string inside the form '=(:documentation STRING)='.
+3. Finally, any string whose first three characters are '###'. Since lines
+ beginning with a hash are interpreted as comments by org mode, these
+ characters will disappear when you export your document to HTML or other
+Here is the docstring for [[document-package]]. It illustrates the use of
+headings, bulleted lists, definition lists, =code=, *bold* and /italic/
+markup, hyperlinks to other definitions, and syntax highlighting of lisp source
: - PKG :: A package name or package object.
: sections, just like functions and generic functions. Most people put
: 'method' documentation in the docstrings of their generic functions, but
: if you set docstrings for individual methods then set this to nil.
-: - =STYLE-SHEET= specifies the name of a Cascading Style Sheet (.CSS) file
+: - =STYLE-SHEET= specifies the name of a Cascading Style Sheet (.CSS) file
: which will be used as the style for the document if you export it
(for line = (read-line in))
+ ;; Regex matches 'heading' lines
(format nil "^([~A]+)([ \t]+)(.*)$"
(format nil "~C" *heading-char*)))
+ ;; Regex matches first part of "[[...][...]]" long-form
+ ;; hyperlinks. Ensures first part of hyperlink is
(setf str (regex-replace-all "\\[\\[([^]]*)\\]\\["
(lambda (match match1 &rest matches)
+ ;; Regex matches all [[...]] short-form hyperlinks.
+ ;; Ensures html safety.
(setf str (regex-replace-all "\\[\\[([^]]*)\\]\\]"
(lambda (match match1 &rest matches)
(defun write-docstring-section (title docstr)
"Writes the documentation string DOCSTR within its own subsection."
+ ((string-starts-with? docstr (format nil "###~C" #\newline))
+ (setf docstr (subseq docstr 4)))
+ ((string-starts-with? docstr (format nil "###~C~C" #\return #\newline))
+ (setf docstr (subseq docstr 5)))
+ ((string-starts-with? docstr (format nil "###" #\return #\newline))
+ (setf docstr (subseq docstr 3))))
(if (and (stringp docstr)
(eql 0 (search (format nil "~C " *heading-char*) docstr)))
(let ((*heading-level* (1+ *heading-level*)))