Documentation-Utils
Author: Nicolas Hafner <shinmera@tymoon.eu>
Description: A few simple tools to help you with documenting your library.

## About documentation-utils

This is a small library to help you with managing the docstrings for your library.

## How To

The central element is the `define-docs` macro. It takes a body of expressions to define the documentation. In the simplest form, this looks like so:

    (docs:define-docs
      (my-function "Some documentation"))

If you need a different type of documentation, or want to be explicit, prepend its type to the expression.

    (docs:define-docs
      (function my-function "Some documentation")
      (variable *my-variable* "Something else"))

In order to make things look more homely, aliases exist that can be used instead:

    (docs:define-docs
      (defun my-function
        "Some documentation")
      (defvar *my-variable*
        "Something else"))

Aliases exist for most of the `def*` expressions. Some expressions can take multiple arguments for the specifier, but the last in the expression is always the docstring:

    (docs:define-docs
      (defmethod foo :append ((num integer) other)
        "stuff"))

You can also extend this system for your own documentation translators. If you need more complex behaviour than the default of `(documentation specifier type)`, see `define-documentation-translator`. If you are defining a new documentation type, you should also add a `documentation-test` to ensure that `check` can verify that you actually did set a documentation.

## Custom Documentation Syntax

In case you would like to use a richer markup than plaintext within your documentation, you can use the `formatter` facility. Formatters take the last expression in a documentation definition expression and translate it to a docstring. This means that, with the right formatter, you can use a format other than plain docstrings, or even hook this into another documentation processing system in order to emit richer text while staying compatible to the standard `cl:documentation` facility.

In order to switch the formatter, you can use the `define-docs` options like so:

    (docs:define-docs
      :formatter my-formatter
      (function my-function
        (:arguments (a "Something about this"
                     b "Something about that")
         :return-value "Nothing useful"
         :summary "This function does something, though I don't know what.")))

Aside from the `:formatter` option, you can pass an arbitrary number of other options as well, which will be used as initargs for the formatter instance. Note that this is all done at macroexpansion-time, and the initarg values are thus used as literals.

The formatter presented above is just an example and is not provided by documentation-utils. Since I can't anticipate people's overall preferences in documentation style, it is up to you to write something more complicated to extend documentation-utils capabilities. Doing so should just be a matter of subclassing `formatter` and adding a method to `format-documentation`, though. As an example, the above could be done as follows:

    (defclass my-formatter (formatter) ())

    (defmethod format-documentation ((formatter my-formatter) type var docs)
      (format NIL "~a~@[

    Arguments:~{
      ~a: ~a~}~]~@[

    Return value:
      ~a~]"
              (getf docs :summary)
              (getf docs :arguments)
              (getf docs :return-value)))

I'm sure you can imagine your own way of doing things.

## Copyright

documentation-utils is licensed under the Artistic license. © Nicolas Hafner <shinmera@tymoon.eu> . This library can be obtained on https://github.com/Shinmera/documentation-utils.

## Package Index

- ### DOCUMENTATION-UTILS (ORG.SHIRAKUMO.DOCUMENTATION-UTILS DOCS)

  - special

    #### `*DOCUMENTATION-TESTS*`

        Holds an alist of documentation types to test functions.

        The function should take one argument, the specifier, and
        return non-NIL if the symbol is bound for the given type.

  - special

    #### `*DOCUMENTATION-TRANSLATORS*`

        Holds an alist of documentation types to translator functions.

        The function should take one argument, the specifier expression, and
        return a documentation form suitable to access the documentation
        for the given type.

  - class

    #### `DOCUMENTATION-FORMATTER`

        Base class for all documentation formatters.

        A documentation formatter is responsible for translating user-defined
        documentation expressions into docstrings usable by the underlying
        documentation storage. This can also be used to hook it into other systems
        that access documentation and may enrich it with further styling or
        information.

        The only relevant function for this class is FORMAT-DOCUMENTATION, which
        is used to perform the translation.

        See FORMAT-DOCUMENTATION

  - class

    #### `FORMATTER`

        Base class for all documentation formatters.

        A documentation formatter is responsible for translating user-defined
        documentation expressions into docstrings usable by the underlying
        documentation storage. This can also be used to hook it into other systems
        that access documentation and may enrich it with further styling or
        information.

        The only relevant function for this class is FORMAT-DOCUMENTATION, which
        is used to perform the translation.

        See FORMAT-DOCUMENTATION

  - accessor `(`

    #### `DOCUMENTATION-TEST`

    `` `TYPE``)`

        Access the documentation test function for the given type.

        See *DOCUMENTATION-TESTS*

  - accessor `(`

    #### `DOCUMENTATION-TRANSLATOR`

    `` `TYPE``)`

        Access the documentation translator function for the given type.

        See *DOCUMENTATION-TRANSLATORS*

  - function `(`

    #### `CHECK`

    `` `&KEY (PACKAGE *PACKAGE*) (INTERNAL T)``)`

        Checks whether all symbols have documentation for all known types.

        If documentation is not set for a given symbol and type combination, a
        warning is signalled.

        See *DOCUMENTATION-TESTS*

  - function `(`

    #### `REMOVE-DOCUMENTATION-TEST`

    `` `TYPE``)`

        Remove the documentation test function for the given type.

        See *DOCUMENTATION-TESTS*

  - function `(`

    #### `REMOVE-DOCUMENTATION-TRANSLATOR`

    `` `TYPE``)`

        Remove the documentation translator function for the given type.

        See *DOCUMENTATION-TRANSLATORS*

  - generic `(`

    #### `FORMAT-DOCUMENTATION`

    `` `FORMATTER TYPE VAR DOCUMENTATION``)`

        Processes the documentation string according to the formatter's rules.

        Passed along are the three values that make up a documentation definition:

        - The fundamental type of the definition as used in DOCUMENTATION.
        - An additional set of variants used to distinguish more complicated
          definitions. For instance, for methods this would be the method qualifiers.
        - The expression used for the actual documentation. This is always the last
          expression within a documentation definition expression.

        The function should either error on an invalid documentation expression, or
        return a string to be passed to the underlying documentation storage.

        You may use this function to store the documentation expression elsewhere
        so that it may be processed into different formats using additional markup
        than is appropriate for plain strings.

        See DOCUMENTATION-FORMATTER

  - macro `(`

    #### `DEFINE-DOCS`

    `` `&BODY EXPRESSIONS``)`

        Allows you to comfortably and easily set the documentation for your library.

        Each expression in the body can either take a two or many argument structure.
        In the two argument structure, the type is implicitly assumed to be
        FUNCTION. The first argument is then the specifier, and the second the
        documentation. In the many argument structure the first argument is the
        type, the last is the documentation, and everything in between the specifier.

        The expansion of the documentation accessor --and thus the structure of
        the specifier-- is dependant on the applicable documentation translator.
        By default, the expansion is simply (CL:DOCUMENTATION SPECIFIER TYPE).

        In addition to the actual documentation expressions, the docs definition may
        begin with a set of keyword-value pairs. These options supply initargs for
        the documentation formatter. By default, the formatter is PLAIN-FORMATTER,
        but a formatter class of your own can be selected with the :FORMATTER option.
        This formatter will then translate the documentation expression at compile time
        to reduce it into a docstring as expected by the underlying documentation
        storage. Note that the initarg values are used at macroexpansion time, and so
        are used as literals.

        See *DOCUMENTATION-TRANSLATORS*
        See FORMAT-DOCUMENTATION
        See PLAIN-FORMATTER

  - macro `(`

    #### `DEFINE-DOCUMENTATION-ALIAS`

    `` `ALIAS TYPE``)`

        Shorthand to define an alias to a translator.

        This simply sets a delegating function that refers to the given type.

        See *DOCUMENTATION-TRANSLATORS*

  - macro `(`

    #### `DEFINE-DOCUMENTATION-TEST`

    `` `TYPE ARGS &BODY BODY``)`

        Shorthand to define a documentation test function.

        See *DOCUMENTATION-TESTS*

  - macro `(`

    #### `DEFINE-DOCUMENTATION-TRANSLATOR`

    `` `TYPE ARGS &BODY BODY``)`

        Shorthand to define a documentation translator function.

        See *DOCUMENTATION-TRANSLATORS*