From: donc@isi.edu (Don Cohen)
Newsgroups: comp.lang.lisp
Subject: Re: Lisp WEB
Date: 5 Nov 92 17:55:12 GMT
Reply-To: donc@isi.edu (Don Cohen)
Distribution: world
Organization: USC Information Sciences Institute
Keywords: Lisp, annotating programmes, WEB, TeX

> What do Lisp programmers do if they want to annotate and publish their
> codes? ...

As far as I can tell, most lisp programmers don't use anything like
WEB.  After I read about literate programming (in CACM programming
pearls?) I started using a very simple approximation for lisp code.
This is described below.  I'd be interested in hearing what other
people out there think of it.  I'll be happy to discuss this and
alternative solutions.

Basically I maintain "the" source as a lisp file, i.e., it can be
loaded into lisp without change.  (I tend to read files into lisp a
lot more often than latex.)  The documentation is all inside #|...|#.
In order to compile it as a latex file there is a very small amount of
preprocessing needed.  Basically you just have to delete all
occurrences of lisp balanced comment delimiters (#| and |#).  I also
replace tabs with spaces, since I use tabs in the lisp source and
latex doesn't seem to understand them.  (I still have mode lines in my
source, so I also get rid of those.)

Here's a shell script:
# file lisp-tex:
# lisp-tex foo reads foo.lisp and writes foo.tex
# removes 1st line (mode line), deletes all #|'s and |#'s,
# expands tabs (for tex)
#
# echo adds a cr - sed throws out anything after the last cr
#
(tail +2 $1.lisp; echo "") | sed 's/#|//g\
s/|#//g' | expand > $1.tex

The result is meant to be included in a larger document, which defines
(among other things) the comment and code macros.  Comment is useful
for including stuff in the source that is not included in the latex
output.  (Is that sacrilege?  I don't do it very often.)  Code is used
for formatting code.  Typically several such files will be included as
chapters of the same latex document.  Here are the macro definitions I
currently use:

\newcommand{\comment}[1]{}

% --- all this is tricky stuff for the code command ---
\def\uncatcodespecials{\def\do##1{\catcode`##1=12 } \dospecials}
\def\setupverbatim{\tt \spaceskip=0pt	% Make sure we get fixed tt spacing
    \obeylines \uncatcodespecials
    \obeyspaces \verbatimdefs}
% This macro turns on verbatim mode until \endverbatim is seen.
\def\xverbatim{\begingroup \setupverbatim \catcode`\{=1\catcode`\}=2
  \parskip=0pt plus .05\baselineskip \parindent=0pt
   \catcode`\ =13 \catcode`\^^M=13  \catcode`\\=0}
{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }}
  \gdef\verbatimgobble#1^^M{}}
% This defines \xendverbatim to end the group which begins with \xverbatim
\let\xendverbatim=\endgroup
\newcommand{\code}[0]{\xverbatim\footnotesize\tt\helpcode}
\def\helpcode#1{#1\xendverbatim}

I got someone else to write \code - I'm not a tex hacker.  I've adjusted
it so that on my normal size page I can get 80 columns of code.  I'm not
all that interested in formatting the code beyond the usual indentation.
The code macro does permit latex commands inside it, which is sometimes
nice, but on the other hand it means you have to watch out for backslashes
in your code.  (Also braces.)  Fortunately these don't appear very often 
in lisp code.

The issue of presenting things in a different order to the reader and
the compiler seems less serious in lisp than in other languages.
However I have on occasion wanted to do that.  I don't have a good
solution.  I guess you could always define some area of the text as a
latex macro and then put a call to it where you want it to appear in
the documentation.  I have not actually done that.  I've also found it
very helpful to tell my editor (gnu emacs) to treat braces as matching
delimiters in lisp mode.  (I generally edit these files in lisp mode.)

Here's what my source files look like:
;;; -*- Mode: LISP; Package: (FOO); Syntax: Common-Lisp -*-

#|
\comment{
This is a lisp source file which is translated into source for a
document preparation system by ... [standard explanation]
}

This is the latex documentation.
Here's some code:

\code{|#
(in-package "FOO")
(defun foo (x)
  (list 1 x))
#|}

Here's some more documentation.
Here's some more code:

\code{|#
(defun bar (x)
  (list 2 x))
#|}

Those lines separating the code from documentation are a little
painful to maintain - it would certainly be easier if they were
single characters (no chance of accidentally corrupting them).
However that would make the result harder to load into lisp.
(I know, I could use read macros, but that would be another 
requirement imposed on the lisp environment.  This way the file
can be read into any standard lisp environment.)  On the other
hand, it's occasionally useful to exclude some of the code from
the documentation, and that can be done by using the word comment
instead of code.  (I know, that could be another single character.)
The only other thing is that you have to end the file with an end 
of comment delimiter, like so:
#|
Newsgroups: comp.lang.lisp