├── .gitattributes ├── README.md ├── package.lisp ├── multilang-documentation-utils.asd ├── documentation-utils.asd ├── LICENSE ├── multilang.lisp ├── documentation.lisp ├── toolkit.lisp └── docs └── index.html /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | doc/ linguist-vendored 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository has [moved](https://shinmera.com/projects/documentation-utils)! 2 | Due to Microsoft's continued enshittification of the platform this repository has been moved to [Codeberg](https://shinmera.com/projects/documentation-utils) in August of 2025. It will not receive further updates or patches. **Issues and pull requests will not be looked at here either**, please submit your patches and issue tickets on Codeberg, or send them directly via good old email patches to [shirakumo@tymoon.eu](mailto:shirakumo@tymoon.eu). 3 | 4 | Thanks. -------------------------------------------------------------------------------- /package.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:cl-user) 2 | (defpackage #:documentation-utils 3 | (:nicknames #:docs #:org.shirakumo.documentation-utils) 4 | (:use #:cl) 5 | (:export 6 | #:*documentation-tests* 7 | #:documentation-test 8 | #:remove-documentation-test 9 | #:define-documentation-test 10 | #:*documentation-translators* 11 | #:documentation-translator 12 | #:remove-documentation-translator 13 | #:define-documentation-translator 14 | #:define-documentation-alias 15 | #:check 16 | #:*default-formatter* 17 | #:documentation-formatter 18 | #:format-documentation 19 | #:basic-formatter 20 | #:define-docs)) 21 | -------------------------------------------------------------------------------- /multilang-documentation-utils.asd: -------------------------------------------------------------------------------- 1 | (asdf:defsystem multilang-documentation-utils 2 | :version "1.1.0" 3 | :license "zlib" 4 | :author "Yukari Hafner " 5 | :maintainer "Yukari Hafner " 6 | :description "Multiple-languages support for documentation-utils." 7 | :homepage "https://shinmera.com/docs/documentation-utils/" 8 | :bug-tracker "https://shinmera.com/project/documentation-utils/issues" 9 | :source-control (:git "https://shinmera.com/project/documentation-utils.git") 10 | :serial T 11 | :components ((:file "multilang")) 12 | :depends-on (:documentation-utils 13 | :multilang-documentation)) 14 | -------------------------------------------------------------------------------- /documentation-utils.asd: -------------------------------------------------------------------------------- 1 | (asdf:defsystem documentation-utils 2 | :version "1.2.0" 3 | :license "zlib" 4 | :author "Yukari Hafner " 5 | :maintainer "Yukari Hafner " 6 | :description "A few simple tools to help you with documenting your library." 7 | :homepage "https://shinmera.com/docs/documentation-utils/" 8 | :bug-tracker "https://shinmera.com/project/documentation-utils/issues" 9 | :source-control (:git "https://shinmera.com/project/documentation-utils.git") 10 | :serial T 11 | :components ((:file "package") 12 | (:file "toolkit") 13 | (:file "documentation")) 14 | :depends-on (:trivial-indent)) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Yukari Hafner 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /multilang.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.documentation-utils) 2 | 3 | (eval-when (:compile-toplevel :load-toplevel :execute) 4 | (defclass multilang-formatter (documentation-formatter) 5 | ()) 6 | 7 | (defmethod format-documentation ((formatter multilang-formatter) type var documentation) 8 | (let* ((documentation (etypecase documentation 9 | (string (list (multilang-documentation:identifier multilang-documentation:*language*) 10 | documentation)) 11 | (cons documentation))) 12 | (docform (funcall (documentation-translator type) var)) 13 | (default (loop for (lang docstring) on documentation by #'cddr 14 | do (when (eq (multilang-documentation:language lang) 15 | multilang-documentation:*language*) 16 | (return docstring)) 17 | finally (return (second docstring))))) 18 | (cond ((eq (first docform) 'documentation) 19 | `(progn 20 | ,@(loop for (lang docstring) on documentation by #'cddr 21 | collect `(setf (multilang-documentation:documentation ,@(rest docform) :lang ',lang) 22 | ,docstring)) 23 | ,default)) 24 | (T 25 | (warn "Don't know how to deal with ~s. Can't expand to multilang definition." docform) 26 | default)))) 27 | 28 | (export 'multilang-formatter)) 29 | 30 | (define-docs 31 | :formatter docs:multilang-formatter 32 | (type multilang-formatter 33 | (:en "This formatter allows specifying docstrings for multiple languages at once. 34 | 35 | The docstring should be either just a single string like 36 | always, in which case it is used for the default language, 37 | or it should be a plist of languages and docstrings. 38 | 39 | See DOCUMENTATION-FORMATTER 40 | See MULTILANG-DOCUMENTATION:*LANGUAGE* 41 | See MULTILANG-DOCUMENTATION:DOCUMENTATION" 42 | :jp "このformatterは複数の語のdocstring許します。 43 | 44 | DOCUMENTATION-FORMATTER を参照 45 | MULTILANG-DOCUMENTATION:*LANGUAGE* を参照 46 | MULTILANG-DOCUMENTATION:DOCUMENTATION を参照"))) 47 | 48 | -------------------------------------------------------------------------------- /documentation.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.documentation-utils) 2 | 3 | (docs:define-docs 4 | (variable *documentation-tests* 5 | "Holds an alist of documentation types to test functions. 6 | 7 | The function should take one argument, the specifier, and 8 | return non-NIL if the symbol is bound for the given type.") 9 | 10 | (function documentation-test 11 | "Access the documentation test function for the given type. 12 | 13 | See *DOCUMENTATION-TESTS*") 14 | 15 | (function remove-documentation-test 16 | "Remove the documentation test function for the given type. 17 | 18 | See *DOCUMENTATION-TESTS*") 19 | 20 | (function define-documentation-test 21 | "Shorthand to define a documentation test function. 22 | 23 | See *DOCUMENTATION-TESTS*") 24 | 25 | (variable *documentation-translators* 26 | "Holds an alist of documentation types to translator functions. 27 | 28 | The function should take one argument, the specifier expression, and 29 | return a documentation form suitable to access the documentation 30 | for the given type.") 31 | 32 | (function documentation-translator 33 | "Access the documentation translator function for the given type. 34 | 35 | See *DOCUMENTATION-TRANSLATORS*") 36 | 37 | (function remove-documentation-translator 38 | "Remove the documentation translator function for the given type. 39 | 40 | See *DOCUMENTATION-TRANSLATORS*") 41 | 42 | (function define-documentation-translator 43 | "Shorthand to define a documentation translator function. 44 | 45 | See *DOCUMENTATION-TRANSLATORS*") 46 | 47 | (function define-documentation-alias 48 | "Shorthand to define an alias to a translator. 49 | 50 | This simply sets a delegating function that refers to the given type. 51 | 52 | See *DOCUMENTATION-TRANSLATORS*") 53 | 54 | (function check 55 | "Checks whether all symbols have documentation for all known types. 56 | 57 | If documentation is not set for a given symbol and type combination, a 58 | warning is signalled. 59 | 60 | See *DOCUMENTATION-TESTS*") 61 | 62 | (variable *default-formatter* 63 | "Variable for the default formatter to use. 64 | 65 | This should be either a DOCUMENTATION-FORMATTER instance, or a symbol 66 | naming the class of one. 67 | 68 | By default this value is an instance of PLAIN-FORMATTER. 69 | 70 | See DOCUMENTATION-FORMATTER 71 | See PLAIN-FORMATTER 72 | See DEFINE-DOCS") 73 | 74 | (type documentation-formatter 75 | "Base class for all documentation formatters. 76 | 77 | A documentation formatter is responsible for translating user-defined 78 | documentation expressions into docstrings usable by the underlying 79 | documentation storage. This can also be used to hook it into other systems 80 | that access documentation and may enrich it with further styling or 81 | information. 82 | 83 | The only relevant function for this class is FORMAT-DOCUMENTATION, which 84 | is used to perform the translation. 85 | 86 | See FORMAT-DOCUMENTATION") 87 | 88 | (function format-documentation 89 | "Processes the documentation string according to the formatter's rules. 90 | 91 | Passed along are the three values that make up a documentation definition: 92 | 93 | - The fundamental type of the definition as used in DOCUMENTATION. 94 | - An additional set of variants used to distinguish more complicated 95 | definitions. For instance, for methods this would be the method qualifiers. 96 | - The expression used for the actual documentation. This is always the last 97 | expression within a documentation definition expression. 98 | 99 | The function should either error on an invalid documentation expression, or 100 | return a string to be passed to the underlying documentation storage. 101 | 102 | You may use this function to store the documentation expression elsewhere 103 | so that it may be processed into different formats using additional markup 104 | than is appropriate for plain strings. 105 | 106 | See DOCUMENTATION-FORMATTER") 107 | 108 | (type plain-formatter 109 | "A formatter that only allows strings and emits them verbatim. 110 | 111 | This is the default formatter. 112 | 113 | See DOCUMENTATION-FORMATTER") 114 | 115 | (function split-body-options 116 | "Splits the body of expressions into two parts, a plist, and a body. 117 | 118 | Returned are two values: a plist, and a body. The plist is composed of 119 | all keyword-value pairs found at the beginning of the body. The returned 120 | body is all the remaining expressions.") 121 | 122 | (function removef 123 | "Removes the given set of keys from the plist and returns a fresh copy.") 124 | 125 | (function define-docs 126 | "Allows you to comfortably and easily set the documentation for your library. 127 | 128 | Each expression in the body can either take a two or many argument structure. 129 | In the two argument structure, the type is implicitly assumed to be 130 | FUNCTION. The first argument is then the specifier, and the second the 131 | documentation. In the many argument structure the first argument is the 132 | type, the last is the documentation, and everything in between the specifier. 133 | 134 | The expansion of the documentation accessor --and thus the structure of 135 | the specifier-- is dependant on the applicable documentation translator. 136 | By default, the expansion is simply (CL:DOCUMENTATION SPECIFIER TYPE). 137 | 138 | In addition to the actual documentation expressions, the docs definition may 139 | begin with a set of keyword-value pairs. These options supply initargs for 140 | the documentation formatter. By default, the formatter is *DEFAULT-FORMATTER*, 141 | but a formatter class of your own can be selected with the :FORMATTER option. 142 | This formatter will then translate the documentation expression at compile time 143 | to reduce it into a docstring as expected by the underlying documentation 144 | storage. Note that the initarg values are used at macroexpansion time, and so 145 | are used as literals. If the chosen formatter is already a formatter instance, 146 | the initargs are used with REINITIALIZE-INSTANCE. Otherwise if the formatter 147 | is a symbol, MAKE-INSTANCE Is used. 148 | 149 | See *DOCUMENTATION-TRANSLATORS* 150 | See FORMAT-DOCUMENTATION 151 | See *DEFAULT-FORMATTER*")) 152 | -------------------------------------------------------------------------------- /toolkit.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.documentation-utils) 2 | 3 | (defvar *documentation-tests* ()) 4 | 5 | (defun documentation-test (type) 6 | (cdr (assoc type *documentation-tests*))) 7 | 8 | (defun (setf documentation-test) (test type) 9 | (if (assoc type *documentation-tests*) 10 | (setf (cdr (assoc type *documentation-tests*)) test) 11 | (push (cons type test) *documentation-tests*))) 12 | 13 | (defun remove-documentation-test (type) 14 | (setf *documentation-tests* 15 | (remove type *documentation-tests* :key #'car))) 16 | 17 | (defmacro define-documentation-test (type args &body body) 18 | `(setf (documentation-test ',type) 19 | (lambda ,args ,@body))) 20 | 21 | (defvar *documentation-translators* ()) 22 | 23 | (defun documentation-translator (type) 24 | (or (cdr (assoc type *documentation-translators*)) 25 | (lambda (form) 26 | `(documentation ',(if (listp form) (first form) form) ',type)))) 27 | 28 | (defun (setf documentation-translator) (translator type) 29 | (if (assoc type *documentation-translators*) 30 | (setf (cdr (assoc type *documentation-translators*)) translator) 31 | (push (cons type translator) *documentation-translators*))) 32 | 33 | (defun remove-documentation-translator (type) 34 | (setf *documentation-translators* 35 | (remove type *documentation-translators* :key #'car))) 36 | 37 | (defmacro define-documentation-translator (type args &body body) 38 | `(setf (documentation-translator ',type) 39 | (lambda ,args ,@body))) 40 | 41 | (defmacro define-documentation-alias (alias type) 42 | `(setf (documentation-translator ',alias) 43 | (lambda (form) (funcall (documentation-translator ',type) form)))) 44 | 45 | (defun list-symbols (package &key (internal T)) 46 | (let ((symbs ()) 47 | (package (find-package package))) 48 | (do-symbols (symb package (sort symbs #'string<)) 49 | (when (and (eql (symbol-package symb) package) 50 | (or internal (eql :external (nth-value 1 (find-symbol (string symb) package))))) 51 | (push symb symbs))))) 52 | 53 | (defun check (&key (package *package*) (internal T)) 54 | (loop for (type . test) in (sort (copy-list *documentation-tests*) 55 | #'string< :key #'car) 56 | do (dolist (symb (list-symbols package :internal internal)) 57 | (when (and (funcall test symb) (not (handler-bind ((warning #'muffle-warning)) (documentation symb type)))) 58 | (warn "No documentation for ~(~a~) ~a." type symb))))) 59 | 60 | (defclass documentation-formatter () 61 | ()) 62 | 63 | (defgeneric format-documentation (formatter type var documentation)) 64 | 65 | (defclass plain-formatter (documentation-formatter) 66 | ()) 67 | 68 | (defmethod format-documentation ((formatter plain-formatter) type var documentation) 69 | (declare (ignorable type var)) 70 | (check-type documentation string) 71 | documentation) 72 | 73 | (defun split-body-options (body) 74 | (values (loop for list = body then rest 75 | for (key val . rest) = list 76 | while (and (cdr list) (keywordp key)) 77 | collect key collect val 78 | finally (setf body list)) 79 | body)) 80 | 81 | (defun removef (plist &rest keys) 82 | (loop for (key val) on plist by #'cddr 83 | for test = (find key keys) 84 | unless test collect key 85 | unless test collect val)) 86 | 87 | (defvar *default-formatter* (make-instance 'plain-formatter)) 88 | 89 | (defmacro define-docs (&body expressions) 90 | (multiple-value-bind (options expressions) (split-body-options expressions) 91 | (let* ((formatter (or (getf options :formatter) 92 | *default-formatter*)) 93 | (formatter (apply (etypecase formatter 94 | (documentation-formatter #'reinitialize-instance) 95 | (symbol #'make-instance)) 96 | formatter (removef options :formatter)))) 97 | `(progn 98 | ,@(loop for expr in expressions 99 | for length = (length expr) 100 | for type = (if (< 2 length) (first expr) 'function) 101 | for var = (if (< 2 length) (rest (butlast expr)) (butlast expr)) 102 | for doc = (car (last expr)) 103 | collect `(setf ,(funcall (documentation-translator type) var) 104 | ,(format-documentation formatter type var doc))))))) 105 | 106 | (trivial-indent:define-indentation define-docs (&rest (&whole 2 0 &body))) 107 | 108 | (setf (documentation-test 'function) #'fboundp) 109 | (setf (documentation-test 'variable) #'boundp) 110 | (setf (documentation-test 'compiler-macro) #'compiler-macro-function) 111 | (setf (documentation-test 'package) #'find-package) 112 | 113 | (define-documentation-test type (symb) 114 | (find-class symb NIL)) 115 | 116 | (define-documentation-translator method (expr) 117 | (destructuring-bind (func &rest quals-specs) expr 118 | (let* ((qualifiers (butlast quals-specs)) 119 | (specializers (car (last quals-specs))) 120 | (clean-specs (loop for arg in specializers 121 | until (find arg lambda-list-keywords) 122 | collect (if (listp arg) (second arg) T)))) 123 | `(documentation (find-method #',func ',qualifiers ',(mapcar #'find-class clean-specs)) 't)))) 124 | 125 | (define-documentation-alias defun function) 126 | (define-documentation-alias defmacro function) 127 | (define-documentation-alias defgeneric function) 128 | (define-documentation-alias defmethod method) 129 | (define-documentation-alias defvar variable) 130 | (define-documentation-alias defparameter variable) 131 | (define-documentation-alias defconstant variable) 132 | (define-documentation-alias defclass type) 133 | (define-documentation-alias defstruct type) 134 | (define-documentation-alias define-condition type) 135 | (define-documentation-alias deftype type) 136 | (define-documentation-alias define-method-combination method-combination) 137 | (define-documentation-alias define-compiler-macro compiler-macro) 138 | (define-documentation-alias defpackage package) 139 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Documentation Utils

documentation utils

1.2.0

A few simple tools to help you with documenting your library.

Table of Contents

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
  2 |   (my-function "Some documentation"))
  3 | 

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

(docs:define-docs
  4 |   (function my-function "Some documentation")
  5 |   (variable *my-variable* "Something else"))
  6 | 

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

(docs:define-docs
  7 |   (defun my-function
  8 |     "Some documentation")
  9 |   (defvar *my-variable*
 10 |     "Something else"))
 11 | 

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
 12 |   (defmethod foo :append ((num integer) other)
 13 |     "stuff"))
 14 | 

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
 15 |   :formatter my-formatter
 16 |   (function my-function
 17 |     (:arguments (a "Something about this"
 18 |                  b "Something about that")
 19 |      :return-value "Nothing useful"
 20 |      :summary "This function does something, though I don't know what.")))
 21 | 

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) ())
 22 | 
 23 | (defmethod format-documentation ((formatter my-formatter) type var docs)
 24 |   (format NIL "~a~@[
 25 | 
 26 | Arguments:~{
 27 |   ~a: ~a~}~]~@[
 28 | 
 29 | Return value:
 30 |   ~a~]"
 31 |           (getf docs :summary)
 32 |           (getf docs :arguments)
 33 |           (getf docs :return-value)))
 34 | 

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

Multiple Language Support

If you would like to provide documentation for your system in multiple languages, you can use the multilang-documentation-utils system, which relies on multilang-documentation. You can then use a plist of languages and docstrings as the docstring in a definition.

Note that this uses the formatter mechanism to do its work. If you want to use a custom formatter in addition, you'll need to change it to output the appropriate docstrings to multilang-documentation:documentation.

(docs:define-docs
 35 |   :formatter docs:multilang-formatter
 36 |   (function foo
 37 |     (:en "Does some fooey"
 38 |      :de "Macht einen Quatsch"
 39 |      :ja "出鱈目をします。")))
 40 | 

System Information

1.2.0
Yukari Hafner
zlib

Definition Index

  • DOCUMENTATION-UTILS

    • DOCS
    • ORG.SHIRAKUMO.DOCUMENTATION-UTILS
    No documentation provided.
    • EXTERNAL SPECIAL-VARIABLE

      *DOCUMENTATION-TESTS*

          Source
          Holds an alist of documentation types to test functions.
           50 | 
           51 | The function should take one argument, the specifier, and
           52 | return non-NIL if the symbol is bound for the given type.
        • EXTERNAL SPECIAL-VARIABLE

          *DOCUMENTATION-TRANSLATORS*

              Source
              Holds an alist of documentation types to translator functions.
               53 | 
               54 | The function should take one argument, the specifier expression, and
               55 | return a documentation form suitable to access the documentation
               56 | for the given type.
            • EXTERNAL CLASS

              DOCUMENTATION-FORMATTER

                  Source
                  Base class for all documentation formatters.
                   57 | 
                   58 | A documentation formatter is responsible for translating user-defined
                   59 | documentation expressions into docstrings usable by the underlying
                   60 | documentation storage. This can also be used to hook it into other systems
                   61 | that access documentation and may enrich it with further styling or
                   62 | information.
                   63 | 
                   64 | The only relevant function for this class is FORMAT-DOCUMENTATION, which
                   65 | is used to perform the translation.
                   66 | 
                   67 | See FORMAT-DOCUMENTATION
                • EXTERNAL FUNCTION

                  CHECK

                    • &KEY
                    • PACKAGE
                    • INTERNAL
                    • &REST
                    Source
                    Checks whether all symbols have documentation for all known types.
                     68 | 
                     69 | If documentation is not set for a given symbol and type combination, a
                     70 | warning is signalled.
                     71 | 
                     72 | See *DOCUMENTATION-TESTS*
                  • EXTERNAL GENERIC-FUNCTION

                    FORMAT-DOCUMENTATION

                      • FORMATTER
                      • TYPE
                      • VAR
                      • DOCUMENTATION
                      • &REST
                      Source
                      Processes the documentation string according to the formatter's rules.
                       81 | 
                       82 | Passed along are the three values that make up a documentation definition:
                       83 | 
                       84 | - The fundamental type of the definition as used in DOCUMENTATION.
                       85 | - An additional set of variants used to distinguish more complicated
                       86 |   definitions. For instance, for methods this would be the method qualifiers.
                       87 | - The expression used for the actual documentation. This is always the last
                       88 |   expression within a documentation definition expression.
                       89 | 
                       90 | The function should either error on an invalid documentation expression, or
                       91 | return a string to be passed to the underlying documentation storage.
                       92 | 
                       93 | You may use this function to store the documentation expression elsewhere
                       94 | so that it may be processed into different formats using additional markup
                       95 | than is appropriate for plain strings.
                       96 | 
                       97 | See DOCUMENTATION-FORMATTER
                    • EXTERNAL MACRO

                      DEFINE-DOCS

                        • &BODY
                        • EXPRESSIONS
                        • &REST
                        Source
                        Allows you to comfortably and easily set the documentation for your library.
                         98 | 
                         99 | Each expression in the body can either take a two or many argument structure.
                        100 | In the two argument structure, the type is implicitly assumed to be 
                        101 | FUNCTION. The first argument is then the specifier, and the second the
                        102 | documentation. In the many argument structure the first argument is the
                        103 | type, the last is the documentation, and everything in between the specifier.
                        104 | 
                        105 | The expansion of the documentation accessor --and thus the structure of
                        106 | the specifier-- is dependant on the applicable documentation translator.
                        107 | By default, the expansion is simply (CL:DOCUMENTATION SPECIFIER TYPE).
                        108 | 
                        109 | In addition to the actual documentation expressions, the docs definition may
                        110 | begin with a set of keyword-value pairs. These options supply initargs for
                        111 | the documentation formatter. By default, the formatter is *DEFAULT-FORMATTER*,
                        112 | but a formatter class of your own can be selected with the :FORMATTER option.
                        113 | This formatter will then translate the documentation expression at compile time
                        114 | to reduce it into a docstring as expected by the underlying documentation
                        115 | storage. Note that the initarg values are used at macroexpansion time, and so
                        116 | are used as literals. If the chosen formatter is already a formatter instance,
                        117 | the initargs are used with REINITIALIZE-INSTANCE. Otherwise if the formatter
                        118 | is a symbol, MAKE-INSTANCE Is used.
                        119 | 
                        120 | See *DOCUMENTATION-TRANSLATORS*
                        121 | See FORMAT-DOCUMENTATION
                        122 | See *DEFAULT-FORMATTER*
                    --------------------------------------------------------------------------------