setup-lisp/docs/source/docs.lisp

169 lines
6 KiB
Common Lisp
Raw Normal View History

2021-02-06 09:41:50 +00:00
(defpackage #:example-docs/docs
(:nicknames #:example-docs)
(:use #:cl)
(:import-from #:mgl-pax
#:section
#:defsection)
(:import-from #:example/app
#:@app)
(:import-from #:example/utils
#:@utils)
(:export
#:build-docs))
(in-package example-docs/docs)
(defsection @index (:title "Example of MGL-PAX Common Lisp Documentation Builder")
"
This is 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
[MGL-PAX](http://melisgl.github.io/mgl-pax/) documentation builder.
This repository is part of the <https://github.com/cl-doc-systems> organization,
created to compare different Common Lisp documentation systems.
The goal is make it easier for CL software developers to choose proper
documentation system and to improve docs in their software!
Resulting documentation can be viewed here:
<https://cl-doc-systems.github.io/mgl-pax/>
The repository can be used as a template for new libraries if you've choosen `MGL-PAX`
for documenting your library.
Let's review features, provided by `MGL-PAX`.
"
(@pros-n-cons section)
(@how-to-build section)
(@handwritten section)
(@autogenerated section)
(@packages section))
(defsection @pros-n-cons (:title "Pros & Cons of PAX")
(@pros section)
(@cons section))
(defsection @pros (:title "Pros")
"
* Markdown is widely used markup format and PAX uses it everywhere.
* Cross-referencing works like a charm and you can reference different
types of objects using [Locatives](http://melisgl.github.io/mgl-pax/#x-28MGL-PAX-3A-40MGL-PAX-LOCATIVES-AND-REFERENCES-20MGL-PAX-3ASECTION-29).
* New types of documentation objects can be defined in Common Lisp using CLOS.
Here is [an example](http://melisgl.github.io/mgl-pax/#x-28MGL-PAX-3AREFERENCE-LOCATIVE-20-28MGL-PAX-3AREADER-20MGL-PAX-3AREFERENCE-29-29).
* Emacs/SLIME integration and ability to jump to a xref objects using M-.
* Ability to generate Markdown README files as well as HTML.
* It is possible to link documentation and sources on the GitHub.
* Docstrings deindentation allows to format code nicely.
* You can generation docs for a multiple ASDF systems with cross-referencing.
* Autoexports all documented symbols. No need to enumerate them in `defpackage` form.
* There is a nice default HTML theme.
* No external tools like Sphinx. Everything is in Common Lisp.
")
(defsection @cons (:title "Cons")
"
* Markdown format may be somewhat limited and probably it can be non-trivial or not possible
to extend it in some rare cases.
* The recommended way to mix documentation section with code leads to
the runtime dependency from PAX and all it's dependencies. But you
might define documentation as a separate ASDF system.
* PAX does not notifies you if some references are missing or there are unused sections.
These mistakes can be catched automatically.
* It is inconvenient to write Markdown in docstrings. Is there any way
to teach Emacs to use markdown minor mode for documentation strings?
* There is no magically autogenerated reference API. See @AUTOGENERATED.
But if you prefer another way, it should be easy to write a function which
will collect external symbols and generate a MGL-PAX:SECTION object for them.
")
(defsection @how-to-build (:title "How to build the documentation")
"
MGL-PAX has a number of ways for generation of the docs. But most probably,
you'll need only toplevel helpers described in it's section
[Generating Documentation](http://melisgl.github.io/mgl-pax/#toc-7-generating-documentation).
These helpers is able to generate README and HTML docs for an ASDF system.
This example defines it's own wrapper EXAMPLE-DOCS:BUILD-DOCS:
"
(build-docs function)
"
It is as simple, as:
```
(defun build-docs ()
(mgl-pax:update-asdf-system-readmes @index :example)
(mgl-pax:update-asdf-system-html-docs @index :example
:target-dir \"docs/build/\"))
```
This function is used by docs/scripts/build.ros file to generate documentation from GitHub Actions.
Or can be called from the REPL.
")
(defsection @handwritten (:title "Handwritten Documentation")
"
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 the FOO function, I can reference it like this
`[example/app:foo][function]` and it will appear in the code as
the link [example/app:foo]. In most cases you can omit square brakets and just
capitalize symbol name.
Comparing MGL-PAX to Coo (here is it's [example project](https://cl-doc-systems.github.io/coo/),
I'd prefer the PAX, because it's ability to mix handwriten sections with documentation extracted
from docstrings.
")
(defsection @autogenerated (:title "Autogenerated API Reference")
"
There is no magically autogenerated reference API. Idea of PAX is that you
write docs manually and reference documented symbols. They are automatically
exported and this way you library's external API should be documented.
But if you prefer another way, it should be easy to write a function which
will collect external symbols and generate a MGL-PAX:SECTION object for them.
")
(defsection @packages (:title "Packages")
(@app section)
(@utils section))
(defun build-docs ()
(mgl-pax:update-asdf-system-readmes @index :example)
(mgl-pax:update-asdf-system-html-docs
@index :example
:target-dir "docs/build/"
:pages `((:objects (,example-docs:@index)
:source-uri-fn ,(pax:make-github-source-uri-fn
:example
"https://github.com/cl-doc-systems/mgl-pax")))))