ocamlweb: a literate programming tool |
Literate programming has been introduced by D. E. Knuth in 1984. The main idea is to put the code and its documentation in the same file and to produce from it a document which is readable by a human, and not only by a machine. Although ocamlweb borrows a lot of ideas from Knuth’s original tool (called WEB), there are big differences between them. First, WEB allows you to present the pieces of your code in any order, and this is quite useful when using poorly structured languages, like Pascal or C. But Objective Caml is already highly structured, and this is no more useful. Moreover, WEB requires the use of a tool to produce the code from the WEB file, which greatly complicates the use of your favorite source-based tools (dependencies generator, debugger, emacs mode, etc.). When using ocamlweb, the documentation is inserted in the code as comments (in the Caml sense), and your code is not linked to the existence of ocamlweb in any way.
Currently, the task of ocamlweb may be seen as:
Documentation is inserted into Caml files as comments. Thus your files may compile as usual, whether you use ocamlweb or not. ocamlweb presupposes that the given Caml files are well-formed (at least lexically, but also syntactically if you want the cross references to be correct). ocamlweb understands each Caml file as a sequence of paragraphs, each paragraph being either a piece of code or a piece of documentation. Documentation starts and ends with Caml comment’s delimiters (* and *), and is a regular LATEX text. Code starts with any characters sequence other than (* and ends with an empty line.
Two styles are available for the final document:
The first feature you will require is the ability to quote code inside documentation and conversely. The latter, namely documentation inside code, is simply obtained by normal Caml comments filled in with a LATEX contents. The former is obtained by quoting code between the delimiters [ and ]. Square brackets may be nested, the inner ones being understood as being part of the quoted code (thus you can quote a list expression like [1;2;3] by writing [[1;2;3]]). Inside quotations, the code is pretty-printed in the same way as it is in code parts.
In addition to the default behavior of ocamlweb, you can control it through a small set of commands, which are comments of a particular shape. These commands are the following:
Starts a new section. (Meaningless in LATEX style.)
Ignores all the text between those two delimiters. Such “comments” cannot be nested but any Caml code and comments may appear between them, included nested Caml comments. You can use those delimiters to enclose a comment that shouldn’t appear in the document, but also to hide some Caml code, putting it between (*i*) and (*i*) in such a way that your code still compiles but is ignored by ocamlweb. (Notice that if you use the delimiters (*i and i*) directly, the text enclosed is commented for both Caml and ocamlweb.)
Tells ocamlweb that this is a real Caml comment an not a documentation text. Mainly useful is you want to insert comments after empty lines. However, this is not the spirit of ocamlweb, and you are encouraged to put the documentation in separate LATEX paragraphs and not in traditional Caml comments.
Justifies an end-of-line comment on the right margin.
Insert some material in the LATEX preamble. See also command line
option -p
.
ocamlweb uses different faces for identifiers and keywords, and use mathematical symbols for some Caml tokens. Here are the correspondences.
-> | → | <- | ← | * | × | |||
<= | ≤ | >= | ≥ | ~- | − | |||
<> | ≠ | == | ≡ | != | ≢ | |||
or , || | ∨ | & , && | ∧ | not | ¬ |
Integers and floating-point literals are pretty-printed like this:
123 | → | 123 |
0b010011 | → | 0100112 |
0o466 | → | 4668 |
0x3fff | → | 3fff16 |
1.2e6 | → | 1.2· 106 |
1e-4 | → | 10−4 |
Characters strings are pretty-printed in fixed-width font.
ocamlweb is rather robust, in the sense that it will always succeed in producing a document, as soon as the Caml files are lexically correct. However, you may find the result rather ugly if so were your source files. Here are some style hints to get a pretty document.
First, ocamlweb is not a real code pretty-printer: it does not
indent your code, and it
does not even cut your code lines when they are too long. The code
will always appear formatted as it is in the source files. The
indentation at the beggining of each line is output as a proportional
space (tabulations are correctly translated). In particular, if you
want your pattern-matchings to be aligned, you have to put a ‘|
’
also in front of the first pattern. Here is the difference:
|
|
ocamlweb is invoked on a shell command line as follows:
ocamlweb <options and files> |
Any command line argument which is not an option is considered to be a
file (even if it starts with a -
). Caml files are identified
by the suffixes .ml
and .mli
, and LATEX files by the
suffix .tex
. The latter will be copied ‘as is’ in the final
document. The order of files on the command line is kept in the final
document.
Redirects the output into the file ‘file’.
In that case, there are no sections à la WEB, and the user
structurates his document directly through LATEX commands, like
for instance \section
, \subsection
, etc. There is
still an index, in the usual LATEX sense. (Therefore, if you have
introduced LATEX sections and subsections, their numbers will
appear in the index.)
Do not insert titles for the files. The default behavior is to insert a title like “Module Foo” or “Interface for module Foo” for each file.
Do not output the index.
Output in DVI format, instead of LATEX format. (You need latex to be installed and present in your path.)
Output in PostScript format, instead of LATEX format. (You need both latex and dvips to be installed and present in your path.)
Output in HTML format, instead of LATEX format. (You need both latex and hevea to be installed and present in your path.)
Passes the given option to hevea (to be used with the --html option). It is mainly useful to specify where the file ocamlweb.sty is to be found, when not installed in the hevea library directory, using --hevea-option "-I dir".
Keeps the external definitions in the index i.e. the identifiers which are not defined in any part of the code. (The default behavior is to suppress them from the index, even if they are used somewhere in the code.)
Does not skip the header of Caml files. The default behavior is to skip them, since there are usually made of copyright and license informations, which you do not want to see in the final document. Headers are identified as comments right at the beginning of the Caml file, and are stopped by any character other then a space outside a comment or by an empty line.
Suppresses the header and trailer of the final document. Thus, you can insert the resulting document into a larger one.
Insert some material in the LATEX preamble, right before
\begin{document}
. See also the control (*p.
Sets the LATEX document class options; it defaults to 12pt
.
Passes the given option the LATEX package ocamlweb.sty.
Uses the old version of the LATEX fullpage package, i.e. with no option. Otherwise option headings is used.
Considers the file ‘file’ respectively as a .ml
file, a
.mli
file or a .tex
file.
Read file names to process in file ‘file’ as if they were given on the command line. Useful for program sources splitted in several directories. See FAQ.
Disable use of greek letters for single-letter type variables. For
example, the declaration of List.hd
is displayed as
List.hd : α list → α
but with this option, it will be displayed as
List.hd : ’a list → ’a
Be quiet. Do not print anything on standard error output except errors.
Gives a short summary of the options and exits.
Prints the version and exits.
In case you choose to produce a document without the default LATEX
preamble (by using option --no-preamble
), then you must insert
into your own preamble the command
\usepackage[
options]{ocamlweb}
Alternatively, you may also pass these options with the
--latex-options
option of the ocamlweb
command.
The options that you may pass to the package are the following:
Tells ocamlweb.sty
that the document was generated with the
--noweb
option so that no WEB sections are used, and
the index was generated by referencing the LATEX sections,
subsections, etc.
By default, spaces in strings of CAML code parts are output as . They will be output as real spaces if you select this option.
When not in WEB sectioning style, these options specify whether the index must refer to page numbers or section numbers. bypages is the default. In WEB sectioning style, this option has no effect.
Additionally, you may alter the rendering of the document by redefining some macros:
The one-argument macros to typeset keywords, base types (such
as int
, string
, etc.), uppercase identifiers (type
constructors, exception names, module names), lowercase identifiers
and type variables respectively. Defaults are sans-serif for
keywords and italic for all others. Some of the single-letter type
variables are displayed by default as greek letters, but this
behaviour can be selected by the --no-greek
option.
For example, if you would like a slanted font for base types, you may insert
\renewcommand{\ocwbt}[1]{\textsl{#1}}
anywhere between \usepackage{ocamlweb}
and
\begin{document}
.
Analogous macros as above, to typeset lex keywords, lex identifiers, yacc keywords and yacc identifiers respectively.
One-argument macros for typesetting the title of a .mli
file,
the title of a .ml
file, the interface part of a .ml
file and the code part of a .ml
file, respectively. Defaults
are is
\newcommand{\ocwinterface}[1]{\section*{Interface for module #1}} \newcommand{\ocwmodule}[1]{\section*{Module #1}} \newcommand{\ocwinterfacepart}{\subsection*{Interface}} \newcommand{\ocwcodepart}{\subsection*{Code}}
and you may redefine them using \renewcommand
.
Use hevea, the LATEX to HTML translator written by Luc Maranget (freely available at http://pauillac.inria.fr/hevea/), with the following command-line:
hevea ocamlweb.sty file.tex |
where file.tex is the document produced by ocamlweb. The package ocamlweb.sty contains the necessary support for hevea.
You can redefine some of the LATEX macros of the
ocamlweb.sty
style file. See
Section 5. We do not recommend to modify
the ocamlweb.sty
file directly, since you would not be able to
update easily to future versions. You should rather redefine the
macros using \renewcommand
. If you want to customize other
parameters that are not currently customizable, please contact the
developers.
Use the option -p or the corresponding control (*p.
If you really want a different LATEX preamble, for instance to use
a LATEX class other than article, then
use the option --no-preamble and catenate the result with your
own header and trailer (or use a \input
or \include
command to insert the file generated by ocamlweb in your main
LATEX file.)
There is no escape sequence for the moment. But there is an easy
solution to this problem: define macros for your LATEX notations
involving square brackets and put them in the preamble or in a
.tex
file that you will provide on the ocamlweb command
line. Then, there is no longer square brackets in your source
comments, but only calls to these macros.
There is support for ocamllex lexers and ocamlyacc
parsers since version 0.9. They are recognized by their suffix on
the command line (do not use option --impl
anymore).
No, it is not, since ocamlweb uses proportional fonts. But you can still align your pattern-matching in your source files, since ocamlweb converts multiple spaces into single ones.
First alternative: you can run an ocamlweb command in each
directories, producing a documentation for each library. If you want
to have the documentations alltogether in the same TeX file, run
each ocamlweb commands with option --no-preamble to avoid
generation of the LATEX preamble, build by hand a master document
file with the preamble you want, without forgetting the
\usepackage{ocamlweb}
, and input each file in each directory
with the \input
or the \include
macro.
Second alternative: the main problem with the first alternative is
that you will have an separate index for each libraries. If you want
a global index, you need the run only one ocamlweb
command.
If you don’t want to put all source file names on one single command
line, you can use the --files
option which allows you to read
the source file names from a file. Example :
ocamlweb --files lib1/source-files --files lib2/source-files
will produce documentation for files in lib1
and lib2
provided that the files source-files
in each directory
contain the name of the documented source files.
This document was translated from LATEX by HEVEA.