This is a small library includes a few functions with docstrings and a documentation for the system and all included packages.
The purpose is to demonstrate core features of the Geneva documentation system.
The repository can be used as a template for new libraries if you've choosen Geneva
for documenting your library.
Let's review features, provided by Geneva
.
Geneva
separates phases of the document construction and rendering. Documents can be written in many formats and all you need is a parser which will return the documennt as a nested list structure like:((:SECTION ("First section") ((:PARAGRAPH ("Foo bar")) (:PARAGRAPH ("Blah minor")))) (:SECTION ("Second section") ((:PARAGRAPH ((:BOLD "Hello World!"))))))
Geneva
includes mk2 markup format which is very strange. To use Markdown or reStructured text you'll need to write a separate parser.geneva.cl:api-document
.geneva.cl:api-document
works with packages and it will be hard to use it for building documentation for a package infrerred ASDF system.(defun render-content (content level) "Render CONTENT as HTML." (case (content-type content) (:paragraph (render-paragraph content)) (:listing (render-listing content)) (:table (render-table content)) (:media (render-media content)) (:plaintext (render-plaintext content)) (:section (render-section content level)) (t (error "Invalid content type in CONTENT: ~S." (content-type content)))))
I think the ability to write a large pieces of documentation which aren't bound to a function, class or module is an important feature. This way you can tell the user about some toplevel abstractions and give a bird eye view on the library or system.
For example, handwritten parts of the documentation can provide some code snippets to demonstrate the ways, how to use the library:
(loop repeat 42 collect (foo "bar" 100500))
And when you are talking about some function or class, you can reference it. For example, if I'm talking about foo
function, I want to be able to reference it.
But Geneva
does not support cross referencing. And you have to write links manually: [example/app:foo](example/app.html#section-1-1)
and it will appear in the code as the link example/app:foo
Geneva
consists of usual functions and can't be easily hacked around. However, you can do some document processing before the rendering.
Geneva
provides a function geneva.cl:api-document
to create a document for a Lisp package. For example, it is used by this example project to build docs for two subpackages:
(flet ((document-package (package) (check-type package keyword) (let ((filename (format nil "docs/build/~A.html" (string-downcase package)))) (ensure-directories-exist filename) (uiop:with-output-file (s filename :if-exists :supersede) (geneva.html:render-html (geneva.cl:api-document package) :stream s))))) (document-package :example/app) (document-package :example/utils))
Here is the results:
For a package infrred ASDF system a function can be written, which will discover all subpackages.