[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] Programmers, use org to write your doc strings...

From: Paul Sexton
Subject: [Orgmode] Programmers, use org to write your doc strings...
Date: Wed, 3 Mar 2010 00:03:48 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)


I think org is a good platform for writing documentation for
source code.  The "babel" module is one approach, but it presumes
that org is the dominant major mode, and the actual source code
is divided into snippets here and there.

I wanted to look into another way of doing it: the source  code's
mode is dominant, with snippets of org mode here and there. Babel
in reverse if you will.

I have used mmm-mode, which is part of nXhtml mode, which  you
can download at:


I have managed to get it working for common lisp. Users of  other
programming languages should easily be able to achieve the same
effect by modifying the elisp code below.

In a lisp buffer, documentation strings use org mode as their
major mode, while the rest of the file uses lisp-mode. All the
fontification works, as does formatting of bulleted lists
etc. Hyperlink overlays don't work (you see [[the whole][link]]
rather than the short form), but the links themselves work.

We define a docstring as:
1. A string which emacs has fontified using the font lock 
   docstring face
2. A string that comes after '(:documentation '
3. A string whose first three characters are ### 

MMM-mode sometimes seems to need a bit of a poke to recognise new
docstrings.  If it's not recognising things that it should, press
ctrl-` to refresh it.

My motivation is that I have written a "doxygen"-like program for
common lisp, called CLOD, whose output is an org mode file. You
can use org mode markup in common lisp docstrings, and the markup
will be understood when the docstrings are read by CLOD. Now, I
can edit those docstrings within the lisp source file and get all
org's fontification, at formatting of bulleted lists, hyperlinks,
etc. All without leaving emacs.


---------contents of .emacs follows---------------------------

(add-to-list 'load-path "/path/to/mmm-mode"))
(require 'mmm-auto)
(setq mmm-global-mode 'maybe)
(mmm-add-mode-ext-class 'lisp-mode  nil  'org-submode)
(mmm-add-mode-ext-class 'slime-mode  nil  'org-submode)
;; The above, using major mode symbols, didn't seem to work for 
;; me so I also added these line (regexp uses same format as 
;; major-mode-alist):
(mmm-add-mode-ext-class nil  "\\.lisp$"  'org-submode)
(mmm-add-mode-ext-class nil  "\\.asd$"  'org-submode)
(setq mmm-submode-decoration-level 2)

;; This prevents transient loss of fontification on first
;; calling `mmm-ify-by-class'
(defadvice mmm-ify-by-class (after refontify-after-mmm 
                             activate compile)

;; bind control-backquote to "refresh" MMM-mode in current buffer.
(global-set-key [?\C-`] (lambda () (interactive)
                          (mmm-ify-by-class 'org-submode)))

;; And the definition of 'org-submode
(mmm-add-group 'org-submode
                  :submode org-mode
                  ;; This face supplies a background colour for org
                  ;; parts of the buffer. Customizable.
                  :face mmm-declaration-submode-face
                  :front "\""
                  :back "[^\\]\""
                  :back-offset 1
                  :front-verify check-docstring-match
                  :end-not-begin t)
                  :submode org-mode
                  :face mmm-declaration-submode-face
                  ;; Match '(:documentation "...")' docstrings
                  :front "(:documentation[\t\n ]+\""
                  :back "[^\\]\""
                  :back-offset 1
                  :end-not-begin t)))

(defun face-at (pos)
    (goto-char pos)

(defun check-docstring-match ()
  (let ((beg (match-beginning 0))
        (end (match-end 0)))
   ;; Docstring if emacs has fontified it in 'docstring' face
   ((eql (face-at end) 'font-lock-doc-face)
   ;; Docstring if the first three characters after the opening
   ;; quote are "###"
   ((string= (buffer-substring end (+ 3 end)) "###")

reply via email to

[Prev in Thread] Current Thread [Next in Thread]