scmdoc

Automatically generate documentation from comments in R7RS Scheme code

git clone https://git.8pit.net/scmdoc.git

  1## Demo
  2
  3A sample documentation for [chibi parse][chibi parse] is available: https://files.8pit.net/scmdoc-demo/
  4
  5## Motivation
  6
  7Tooling for inline source code documentation of Scheme code is rare.
  8Existing tools like [chibi-doc][chibi-doc source] actually interpret/load the code and thus do not work if, for example, some utilized libraries are not available for `chibi-scheme`.
  9To overcome this limitation `scmdoc` takes a different approach were the code is not interpreted and only parsed.
 10This allows `scmdoc` to be applicable to different R⁷RS implementations ([CHICKEN][chicken web], [Guile][guile web], [Gambit][gambit web], [Racket][racket r7rs], …) as long as the input is syntactically valid R⁷RS.
 11Pattern matching is then performed on parsed S-expressions to format them nicely in the generated documentation (e.g. matching for procedure definitions, library definitions, …).
 12In its essence, `scmdoc` is therefore a glorified pattern matcher for S-expressions.
 13
 14## Status
 15
 16This is currently a proof-of-concept.
 17The R7RS parser should support the majority of the standard but is not well tested.
 18A HTML generation backend is available and several R7RS expressions are formatted at the moment, including more complex ones like record type definitions.
 19
 20## Installation
 21
 22This software is known to compile with GHC 9.4.4 and can be installed by running the following commands inside the repository:
 23
 24    $ cabal install
 25
 26## Tests
 27
 28Unit tests are available and can be invoked using the following command:
 29
 30    $ cabal test
 31
 32Furthermore, integration tests are available.
 33These tests require the `scmdoc` binary to be available in your `$PATH`.
 34Furthermore, they require [Tidy][tidy web] to be installed.
 35If these prerequisites are satisfied run the following command to execute these tests:
 36
 37    $ ./golden/run.sh
 38
 39## Approach
 40
 41The `scmdoc` tool is structured around R7RS Scheme libraries.
 42For a given Scheme source file, it extracts all library declaration which are prefixed by a doc comment.
 43Contrary to a normal Scheme comment, a doc comment has the form `;;>`.
 44As such, `scmdoc` would for example recognize the following library declaration:
 45
 46    ;;> My awesome scheme library
 47    (define-library (sample-library)
 48        …)
 49
 50For each recognized library, `scmdoc` expands all includes in the declaration and then extracts all exported and documented expressions from the library.
 51The recognized expressions are then further processed by high-level formatters which recognize S-expressions constituting Scheme procedure definitions et cetera.
 52These formatters are available in `src/SchemeDoc/Format` and essentially perform pattern matching on arbitrary S-expressions.
 53For example, the formatter for Scheme procedure definitions roughly looks as follows:
 54
 55    mkProcedure :: Sexp -> Maybe Procedure
 56    mkProcedure (List ((Id "define"):(List ((Id defid):arglst)):bodylst)) =
 57        -- Convert the S-expression into an algebraic data structure
 58        -- which represents Scheme Procedure definitions and can be
 59        -- formated.
 60    mkProcedure _ = Nothing
 61
 62In the future, it should be possible to also supply custom formatters to, for example, to generate documentation for definitions defined using custom macros.
 63Apart from formatters, `scmdoc` also has a WiP concept of "expanders" which perform primitive comment-preserving macro expansion.
 64This feature is presently used to expand record type definitions (`define-record-type`) to primitive procedure definitions which are then formatted using the procedure formatter.
 65
 66## Usage
 67
 68The `scmdoc` tool generates HTML from a Scheme input defining a R7RS library.
 69As described above, only documented S-expressions for which a documentation formatter is available are included in the generated documentation.
 70In order to demonstrate generation of HTML documentation consider the following input file called `library.scm`:
 71
 72    ;;> This is my documented library.
 73    (define-library (math arithmetic)
 74      (export my-proc my-magic-constant)
 75
 76      ;; This is a normal comment which is not considered by scmdoc.
 77      (begin
 78        ;;> this is a hidden helper function which is not exported.
 79        (define my-mult *)
 80
 81        ;;> my-proc multiplies the given value with two.
 82        (define (my-proc x)
 83          (my-mult x 2))
 84
 85        ;;> A magic constant.
 86        (define my-magic-constant 42)))
 87
 88In order to generate HTML documentation, using `scmdoc`, for this library run the following command:
 89
 90    $ scmdoc library.scm
 91
 92Within documentation comments, it is possible to use Markdown markup.
 93
 94### Section Comments
 95
 96Due to the lack of type information, it is difficult to meaningfully group Scheme program components.
 97For this reason, `scmdoc` relies on manually inserted *section comments* for grouping.
 98A section comment is a documentation comment which starts with a `|` character and is followed by an empty line and a normal documentation comment.
 99The section comment corresponds to the section title, the documentation comment following it functions as the section description.
100For example:
101
102    ;;>| Multiplication Procedures
103    ;;>
104    ;;> Procedures for performing multiplication.
105
106    ;;> Multiply two signed values.
107    (define (multS x y) …)
108
109    ;;> Multiply two unsigned values.
110    (define (multU x y) …)
111
112This will group the procedure `multS` and `multU` into the section *“Multiplication Procedures”*.
113Every section comment consists of a section title (as indicated by `;;>|`) and a mandatory section description.
114Each documented Scheme library *should* contain at least one section comment.
115If the Scheme library doesn't contain any section comments, then everything is grouped under an arbitrary “Declarations” section.
116
117### Look and Feel
118
119The HTML generated by `scmdoc` should be compatible with any [classless CSS framework][cssbed web].
120By default, the [water.css][water.css web] dark theme is used.
121A custom CSS stylesheet can be specified using the `--stylesheet` command-line.
122For more information on classless CSS frameworks refer to [this blog post][greenfield classless].
123
124## Related Work
125
126A loose, incomplete collection of similar work on the documentation of Scheme code:
127
128* [Scribble][scribble web]: The documentation tool used by the Racket programming language
129* [chibi-doc][chibi-doc source]: The documentation tool used by chibi-scheme (inspired by Scribble)
130* [SchemeDoc][schemedoc web]: Extract documentation from Scheme comments using [LAML][laml web]
131* MOLE: [Scheme Program Source Code as a Semistructured Data][mole paper]
132* [`l2t`][l2t web] (aka. LiSP2TeX): A literate programming utility for inserting Scheme into TeX files
133* [schemeweb][schemeweb ctan]: Simple literate programming for Scheme with LaTeX
134
135## Development
136
137Please format all code with [fourmolu](https://github.com/fourmolu/fourmolu).
138For convince, a pre-commit Git hook for checking if files are properly formated is provided in `.githooks`.
139It can be activated using:
140
141    $ git config --local core.hooksPath .githooks
142
143## License
144
145This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.
146Furthermore, this code presently includes the Scheme number parser from [Husk Scheme][husk-scheme github] which is licensed under MIT.
147
148[chicken web]: https://call-cc.org
149[guile web]: https://www.gnu.org/software/guile/
150[gambit web]: https://www.gambitscheme.org/
151[racket r7rs]: https://pkgs.racket-lang.org/package/r7rs
152[chibi-doc source]: https://github.com/ashinn/chibi-scheme/blob/master/tools/chibi-doc
153[husk-scheme github]: https://github.com/justinethier/husk-scheme
154[schemedoc web]: https://people.cs.aau.dk/~normark/schemedoc/
155[schemeweb ctan]: https://ctan.org/pkg/schemeweb
156[mole paper]: http://www.schemeworkshop.org/2001/lisovsky.pdf
157[laml web]: http://people.cs.aau.dk/~normark/laml-distributions/laml/
158[l2t web]: https://christian.queinnec.org/WWW/l2t.html
159[scribble web]: https://docs.racket-lang.org/scribble/index.html
160[cssbed web]: https://www.cssbed.com/
161[greenfield classless]: https://ubershmekel.medium.com/the-next-css-frontier-classless-5e66f3f25fdd
162[water.css web]: https://watercss.kognise.dev/
163[chibi parse]: https://synthcode.com/scheme/chibi/lib/chibi/parse.html
164[tidy web]: https://www.html-tidy.org