Literate programming can be a lot of fun (at least if you like to write prose), but typesetting the resulting document isn't the most enjoyable task in the world. Most source code doesn't typeset well, and marking it up manually misses the whole point of literate programming. There are a few tools that convert source files to TEX sources, but most are rather cumbersome, and, besides, they use LaTEX rather than plain TEX.
lambdaTEX is a tool written entirely in TEX which typesets a literate Haskell 98 script directly, without resorting to any preprocessors. The source code is typeset with proper syntax highlighting for different lexical elements, and common ASCII art is replaced with appropriate mathematical symbols. For example, lambdaTEX will typeset the following nonsense code:
fun :: T1 -> Int -> Int -> Int fun alpha beta gamma = case alpha of Alt1 -> beta^2 Alt2 -> if beta <= gamma then beta else gamma _ -> undefined
as:
fun :: T1 → Int → Int → Int fun α β γ = case α of ALT1 → β↑2 ALT2 → if β ≤ γ then β else γ _ → ⊥
(the above HTML code is displayed correctly by Mozilla; other browsers will probably choke on its heavy use of HTML4 Unicode extensions.)
The default style has been borrowed from Chris Okasaki's book Purely Functional Data Structures, but lambdaTeX can be reconfigured easily enough if required.
lambdaTEX does its magic using an almost-complete Haskell lexical analyzer, written in over 1000 lines of TeX code. The only information that it cannot retrieve from the Haskell source code itself is the distinction between function names and other variables (variables are typeset in italic, which is not appropriate for functions.) Therefore, the Haskell source code must be annotated using constructs of the form:
\functions (funA,!funB,funC)
which specifies that “funA
” and “funC
”
are functions, but “funB
” is not. The “!
”
notation usually is not needed, but lambdaTEX
knows about all standard prelude functions, so, if you redefine
“lines
” as a variable (why would you?), you can typeset
your program correctly by saying “\functions(!lines)
”.
lambdaTEX supports Bird-style literate scripts, as well as an inline Haskell mode for including short fragments of code within sentences, math expressions, etc.
The inline mode is used to typeset a short fragment of Haskell code
in the middle of a paragraph, for example when referring to a variable
defined within the program, simply by enclosing it in a pair of ASCII
quotation mark ("
) characters. The mode is entered by the
quotation character. The lexical analyzer exits when it encounters another
quotation mark. Newlines are treated as simple whitespace, and comments are
illegal. Because the quotation mark character is reserved, strings cannot
appear in the inline mode.
The Bird mode is used to process Bird-style literate scripts. The mode
is entered by the greater-than (“>
”) character. Note that
this is a hack, since, in Haskell, “>
” designates literate
code only when it appears as the first character on a line. The mode exits
when it encounters a blank line. The text is typeset as a separate
paragraph, indented by “\hsleftskip
” on the left and
“\hsrightskip
” on the right. The “\beforehs
”
macro is inserted before the fragment of code and “\afterhs
”
is inserted after it. The “>
” character itself is not
displayed.
In both modes, the “\everyhs
” macro is inserted immediately
after entering the Haskell mode.
Finally, because we've already confiscated “>
” as
an active character, I have decided to grab “<
”, too.
In lambdaTEX,
“<
...>
” typesets “...” in an italic font.
Of course, the meaning of “<
” and “>
” is
restored within math formulas.
More documentation will follow in the future. For now, let the source guide you.
To see lambdaTEX in action, download
“Example.pdf
”. It has been generated
by running
pdftex Example.lhs
To install lambdaTEX, simply download
“lambdaTeX.tex
” and put it
somewhere in your TEXINPUTS
path. It should work with both plain
TEX and LaTEX,
although I have tested it only with plain
TEX.
Note that, if you are going to use lambdaTEX,
you may want to grab the latest version from time time, as I am releasing bug
fixes and improvement rather frequently in response to the numerous feedback
that I have received from the Haskell community. In particular, version 2,
which will align declarations under the “::
” and
“=
” symbols, comments under “--
” and so on,
should be ready before Christmas.
If you have any comments, suggestions, bug reports or bug fixes, I wouldn't mind hearing them. In particular, I'd like to hear of any experiences (good or bad) of using lambdaTEX with LaTEX and with your coding style.
By the way, lambdaTEX is free software covered by a BSDish licence, but, if you use it for typesetting a publication, I would really appreciate if you could drop me a note so I can get an idea of how widely used it is. I would also appreciate an acknowledgment in your publication, but certainly do not require this as a licence condition.
Overful \hbox (91.3397pt too wide) in Haskell code at line 10
\overfullrule
”, which
defaults to 1ex in plain TEX and 0pt in
LaTEX.
--
”) comments.