miércoles, 9 de enero de 2013

Parsing elisp code with elisp

Today, in Reddit there was this guy presenting a utility library for elisp.


In the comments, there was a discussion about generating documentation
from an elisp file. The approach there is fine: parsing the file via
regexen and asking for the documentation to the elisp system itself.

Here's another version I wrote that walks through the code looking for
defuns and defmacros.  The code parses a buffer, and picks the
docstring from the code itself, so it catches it even if the methods
haven't been evaluated.  It's not a real advantage as you won't
probably try to document a code you aren't evaluating, but just for
the sake of the exmple, I think it's a good learning exercice.

So here's the code:

 (defun fetch-defuns (buffer)
   (interactive)
   (save-excursion
     (goto-char (point-min))
     (let (sexp
          (defuns nil)
          (defmacros nil))
       (condition-case nil
          (while t
            (setq sexp (read buffer))
            (when (listp sexp)
              (case (car sexp)
                (defun (push (cons (cadr sexp) (doc-if-any sexp)) defuns))
                (defmacro (push (cons (cadr sexp) (doc-if-any sexp)) defmacros)))))
        (error nil))
       (generate-docs defuns))))
 
 (defun doc-if-any (sexp)
   "search for the doc"
   (when (stringp (cadddr sexp))
     (cadddr sexp)))
 
 (defun generate-docs (defuns)
   "generate a simple org with the docs"
   (mapconcat (lambda (x) (format "* %s
   %s" (car x) (or (cdr x) "-undocumented-"))) defuns "\n\n"))

M-: (fetch-defuns (current-buffer)) will return a minimal org-file skeleton with the function names and their docs.

The cool way to ask for the documentation of a function, however, is just (documentation 'name-of-fun). try it. It's great.

Happy emacs hacking!