This section includes some details for writing proper documentation in lpdoc, improving the layout of manuals, usage tips, and troubleshooting advice.
While lpdoc can produce useful documentation from the interface of the source file, the quality of the documentation generated can be greatly enhanced by including within the program text:
Assertions are declarations which are included in the source program and provide the compiler with information regarding properties of the code. Typical assertions include type declarations, modes, computational properties (such as nonfailure or determinacy), many compiler directives (such as dynamic/1, op/3, meta_predicate/1...), etc. When documenting a module, lpdoc will use the assertions associated with the module interface to construct a textual description of this interface. In principle, only the exported predicates are documented, although any predicate can be included in the documentation by explicitly requesting it (see the documentation for the doc/2 declaration). Judicious use of these assertions allows at the same time documenting the program code, documenting the external use of the module, and greatly improving program debugging and allowing program verification. The latter is possible because the assertions provide the compiler with information on the intended meaning or behaviour of the program (i.e., the specification) which can be checked at compile-time (by a suitable preprocessor/static analyzer) and/or at run-time (via checks inserted by a preprocessor). See The Ciao assertion language for more details.
Machine-readable comments are also declarations included in the source program which contain additional information intended to be read by humans (i.e., this is an instantiation of the literate programming style of Knuth [Knu84]). Typical such comments include title, author(s), summary, bugs, changelog, etc. Judicious use of these comments allows enhancing at the same time the documentation of the program text and the manuals generated from it. See Documentation mark-up language and doc declarations for more details. These declarations can also be writtten in wiki (mark-down) style -- see doccomments.
lpdoc requires these assertions and machine-readable comments to be written using the Ciao assertion language. While Ciao has core support for this language, it is however quite straightforward in most Prolog and (C)LP systems to define a library with dummy declarations so that the assertions and comments meant for lpdoc are simply ignored by the compiler, making it possible to compile programs documented using assertions and comments in such systems and at the same time generate documentation using lpdoc (as well as making other uses of the assertions such as checking tehm statically and/or dynamically).
Writing and generating more complex manuals involves writing a documentation configuration (doccfg) file (e.g, SETTINGS.pl) with this basic structure:
:- module(_, [], [doccfg]). doc_structure := '<MAIN MODULE>'-[ '<COMP1>', ... '<COMPn>' ].
The first line indicates that this is a module implementing a doccfg. The second line defines through doc_structure/1 the document structure, specifying in a tree the main file and (optional) component files. When documenting complex manuals with more than one source files, the main file is the one that will provide the general title, author, date, summary, and the introduction. The component files will appear as separate chapters.
Any option not directly specified will use the default values indicated in doccfg. You may however want to change several of these:
See doccfg for other options.
This section contains additional suggestions on the use of lpdoc.
For each a .pl file, lpdoc tries to determine whether it is a library or an application (exporting main/0 or main/1), and documents it accordingly.
The generated documentation for libraries will contain information on the interface (e.g., the predicates exported by the file, the name of the module and usage if it is a module, etc.), in addition to any other machine readable comments included in the file. The interface information is omitted in for applications by default.
Any combination of libraries and/or main files of applications can be used arbitrarily as components or main files of a lpdoc manual. Some typical combinations are:
Sometimes it is difficult for lpdoc to distinguish include files and Ciao packages from normal user files (i.e., normal code files but which are not modules). The distinction is important because the former are quite different in their form of use (they are loaded via include/1 or use_package/1 declarations instead of ensure_loaded/1) and effect (since they are included, they 'export' operators, declarations, etc.), and should typically be documented differently. There is a special doc/2 declaration (:- doc(filetype,...).) which provides a way of defining the intended use of the file. This declaration is normally not needed in modules, include files, or packages, but should be added in user files (i.e., those meant to be loaded using ensure_loaded/1). Adding this declaration will, for example, avoid spurious documentation of the declarations in the assertions package themselves when this package is included in a user file.
In large documents, it is sometimes convenient to build a super-structure of parts, each of which groups several components. There is a special value of the second argument of the :- doc(filetype,...). declaration mentioned above designed for this purpose. The special filetype value part can be used to flag that the file in which it appears should be documented as the start of one of the major parts in a large document. In order to introduce such a part, a .pl file with a declaration :- doc(filetype,part). should be inserted in the sequence of files that make up the components variable of the documentation configuration file at each point in which a major part starts. The :- doc(title,"..."). declaration of this file will be used as the part title, and the :- doc(module,"..."). declaration text will be used as the introduction to the part.
Reexported predicates, i.e., predicates which are exported by a module m1 but defined in another module m2 which is used by m1, are normally not documented in the original module, but instead a simple reference is included to the module in which it is defined. This can be changed, so that the documentation is included in the original module, by using a doc/2 declaration with doinclude in the first argument (see the comments library). This is often useful when documenting a library made of several components. For a simple user's manual, it is often sufficient to include in the documentation configuration file the principal module, which is the one which users will do a use_module/1 of, in the manual. This module typically exports or reexports all the predicates which define the library's user interface. Note, however, that currently, due to limitations in the implementation, only the comments inside assertions (but not those in doc/2 declarations) are included for reexported predicates.
Sometimes one would not like to include long introductory comments in the module itself but would rather have them in a different file. This can be done quite simply by using the @include command. For example, the following declaration:
:- doc(module,"@@include{Intro.lpdoc}").
will include the contents of the file Intro.lpdoc as the module description.
Alternatively, sometimes one may want to generate the documentation from a completely different file. Assuming that the original module is mod.pl, this can be done by calling the module containing the documentation mod_doc.pl. This mod_doc.pl file is the one that will be included in the documentation configuration file, instead of mod.pl. lpdoc recognizes and treats such _doc files specially so that the name without the _doc part is used in the different parts of the documentation, in the same way as if the documentation were placed in file mod.
Using lpdoc it is often possible to use a common source for documentation text which should appear in several places. For example, assume a file INSTALLATION.lpdoc contains text describing an application. This text can be included in a section of the main file documentation as follows:
:- doc(module," ... @@section{Installation instructions} @@include{INSTALLATION.lpdoc} ... ").
At the same time, this text can be used to generate a nicely formatted INSTALLATION file in ascii, which can perhaps be included in the top level of the source directory of the application. To this end, an INSTALL.pl file as follows can be constructed:
:- use_package([assertions]). :- doc(filetype, application). %% forces file to be documented as an application :- doc(title,"Installation instructions"). :- doc(module,"@@include{INSTALLATION.lpdoc}").
Then, the ascii INSTALLATION file can be generated by simply running lpdoc -t ascii INSTALLATION.pl.
lpdoc supports version comments (:- doc(version(...), "...").) to document the list of version/patch changes (CHANGELOGs) of a particular software. These can be included as part of the manual or translated to plain text (Generating README files).
Version numbers in comments specify a major, minor, and patch number. As a common convention, patch changes (e.g.,1.1#2 to 1.1#3) are reserved for internal changes, such as bug fixes and backward-compatible changes whose detailed description may not be relevant for the user. More general changes (including the summary of internal changes when appropriate) are documented with changes in the major and minor numbers (e.g., 1.1#2 to 1.2#0).
Selecting the appropriate options in lpdoc (e.g., no_patch in doc_mainopts), it is possible to include in the manual the version changes but not the patch changes (which might on the other hand be included in an internals manual). This is useful, for example, to document separatelly internal from general changes.
Due to limitations in texinfo and GNU info, it is sometimes a little tricky to get things to work uniformly for all formats. The following recommendations are intended to help in achieving useful manuals in texinfo-based formats, as well as some common errors and their usual fix:
! No room for a new @write .while converting from .texi to .dvi (i.e., while running tex). These messages are tex's way of saying that an internal area (typically for an index) is full. This is normally because more indices were selected in the index/1 option of the documentation configuration file than the maximum number supported by the installed version of tex/texinfo installations, as mentioned in Generating and accessing manuals. The easiest fix is to reduce the number of indices generated. Alternatively, it may be possible to recompile your local tex/texinfo installation with a higher number of indices.