This is yet another CL documentation generator by Ryan Pavlik. It’s interesting features are:
- Markdown support out of the box.
- New markups can be easily added.
- Code from snippets can be linked to CLHS.
As always, I’ve prepared an example project for you:
https://cl-doc-systems.github.io/cl-gendoc/
You’ll find there a full list of cl-gendoc
’s pros and cons.
Here is a short example of library documentation builder. It includes a few markdown sections and an autogenerated API spec for two packages:
(defun build ()
(let ((output-filename "docs/build/index.html"))
(ensure-directories-exist output-filename)
(gendoc:gendoc (:output-filename output-filename
:css "simple.css")
(:markdown-file "docs/source/index.md")
(:markdown-file "docs/source/pros-and-cons.md")
(:markdown-file "docs/source/handwritten.md")
(:markdown-file "docs/source/reference.md")
(:apiref :example/app
:example/utils))))
The cl-gendoc
has an interesting macro define-gendoc-load-op
. It forces
documentation build after the asdf:load-system
call. Here is how it can
be used:
(defsystem example-docs
:class :package-inferred-system
:defsystem-depends-on ("cl-gendoc")
:pathname "docs/scripts/"
:depends-on ("example-docs/builder"))
(gendoc:define-gendoc-load-op :example-docs
:example-docs/builder 'build)
The macro call will expand into:
(progn
(defmethod asdf/action:perform :after ((o asdf/lisp-action:load-op)
(c (eql (asdf/system:find-system
:example-docs))))
(let ((fn
(find-symbol (symbol-name 'build)
(find-package :example-docs/builder))))
(funcall gendoc::fn)))
;; This method makes ASDF think that load-system wasn't successful
;; and subsequent call will build documentation again.
(defmethod asdf/action:operation-done-p ((o asdf/lisp-action:load-op)
(c (eql (asdf/system:find-system
:example-docs))))
nil))
Personally, I’m don’t like this hack. But I’m sure there should be the
more correct way to use asdf:make
to build docs. If you know how to do
this, please, let me know in the comments.