I have a simple need: I’d like to generate an html documentation from my code. What options do we have ?
I searched for “documentation tool” on Quickdocs: http://quickdocs.org/search?q=documentation%20tool, from which I remove old ones (clod, qbook, manifest).
I had two pure Lisp solutions working out of the box, two more are of interest, and there’s another non-Lisp of interest.
update: just found out that qbook (github mirror)is used for the documentation of Fiveam, which is pretty nice: https://common-lisp.net/project/fiveam/docs/index.html It can produce html and latex. It uses docstrings and comments that start with 4 commas to structure the page (exple in source that gives this). Running it has a lot of asdf deprecation warnings and it did not work out of the box for me (“The slot IT.BESE.QBOOK::GENERATOR is unbound in the object”).
Codex produces nice html but isn’t automatic.
- https://github.com/CommonDoc/codex (by @eudoxia)
- example: https://commondoc.github.io/codex/docs/tutorial.html
- input fromat: scriba by default. No more format it seems.
- output: multiple html files.
- rendering: modern, colored, light, TOC on the side
- granularity: good
- link to CLHS: yes
- totally automatic: no (one needs to create the documentation structure in
- used in the wild: yes
Getting started: write a simple
Am I mistaking ? It’s exclusively manual. We must supply every
function/generic function/method/class/macro to document in
Coo is a new tool in town, it works out of the box and it is actively developed !
- input: docstrings in
- output: multiple html
- rendering: black & white, no TOC (active development)
- links to CLHS: yes, since yesterday :)
- granularity: doesn’t show class slots, doesn’t show generic functions.
- used in the wild: coo no, more probably cl-docutils.
Based on cl-docutils.
Displays the functions’ documentation following their order in source (or not ? I saw exceptions).
and it produces html into
Staple (doesn’t work on Debian’s SBCL 1.2.4)
You may be familiar with Staple since it’s used by Shinmera in all his projects.
- output: html. The documentation string is plain text (no markup, rendered in a
- can use a template.
- more features than listed here.
It doesn’t support SBCL 1.2.4, so my tests fell short (upgrading isn’t 100% smooth here). If you’re on SBCL >= 1.4.8 Staple is a good option.
Declt has higher goals than “quick and easy” documentation generator.
- output: a
.texifile, that we can render into other formats (html, pdf).
- cross-references: yes
It didn’t work out of the box (and had no explicit error information) and it’s also too involved for my use case.
Documentation-tool (not for general use)
It’s the template used for Edi Weitz software, like Hunchentoot.
- output: one html file
It works, but it thinks you publish an edicl software and has some hardcoded “http://weitz.de/files/…" urls.
I liked the output, but it didn’t work (asdf-related error), and it’s unmaintained (authors’ words).
- output: html
Another excellent option is 40ants’ cldomain, which builds on Python’s proven Sphinx:
CLDomain is an extension for the Sphinx documentation generation tool that allow sphinx to generate documentation for Common Lisp libraries. Documentation is extracted from the various entity’s documentation strings, loaded from ASDF systems and associated internal packages.
They use it for they new projects since around 3 years now.
- input: rst
- output: many html
- HyperSpec links: yes
- requirements: Python, pip
udate 2019-01-22: extended example.
An example from cl-hamcrest:
we reference Lisp functions/methods/macros with RST directives:
Object matchers =============== This kind of matchers checks some sort of properties on an object, etc. .. cl:package:: hamcrest/matchers .. cl:macro:: has-plist-entries
they have RST docstrings, also with RST directives to include code blocks:
(def-has-macro has-plist-entries "Matches plist entries: .. code-block:: common-lisp-repl TEST> (let ((obj '(:foo :bar))) (assert-that obj (has-plist-entries :foo \"bar\" :blah \"minor\"))) × Key :FOO has :BAR value, but \"bar\" was expected This way you can test any number of plist's entries." :check-obj-type (check-if-list object) :get-key-value (let ((key-value (getf object key 'absent))) (when (eql key-value 'absent) …
- this produces a nice output (here):
I’ll use and watch Coo !