% \iffalse meta-comment
%
% This is LGrind.DTX. This was written by:
%
% -  Van Jacobson, Lawrence Berkeley Laboratory (based on
%    vgrind by Dave Presotto & William Joy of UC Berkeley),
%    the original written for \TeX.
%
% -  Jerry Leichter of Yale University, modifications for \LaTeX.
%
% -  George V. Reilly of Brown University, renamed to lgrind
%
% -  Michael Piefel, Humboldt-University Of Berlin, for \LaTeXe
%
% \fi
% \iffalse
%% Based on Van Jacobson's ``tgrindmac'', a macro package for TeX grinding
%% Our job here is to simplify it quite a bit and make it conform to LaTeX
%%
%% Modified, 8-Oct-87 by Jerry Leichter to work with various changes made
%% while adapting to VMS.  Made all the internal variables contain an "@".
%%
%% Modified, 17-Jan-87 by Jerry Leichter. Many changes to correspond to
%% modifications in tgrind.exe.
%%
%% Modified, 6-Sep-91 by George Reilly. Changed the name from tgrind to
%% lgrind. Minor changes to get rid of superfluous spaces.
%%
%% Modified, 3-Oct-95 by Michael Piefel. Made it work with \LaTeXe, intro-
%% duced package options and reintroduced Proc...
%%
%% LaTeX lgrind environment
%
%<*dtx>
          \ProvidesFile{lgrind.dtx}
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}[1994/12/01]
%<package>\ProvidesPackage{lgrind}
% \fi
%         \ProvidesFile{lgrind.dtx}
          [1995/11/12 v3.1 LGrind environment and supporting stuff]
%
% \iffalse
%<*driver>
\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\documentclass{ltxdoc}
\CodelineIndex
\RecordChanges
\DocInput{lgrind.dtx}
\end{document}
%</driver>
% \fi
%
% \newcommand{\LG}{\textsf{LGrind}}
% \newcommand{\NFSS}{\textsf{NFSS}}
% \frenchspacing
% 
% \GetFileInfo{lgrind.dtx}
% \begin{document}
% \title{The \LG{} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}}
% \author{Various Artists}
% \date{\filedate}
% \maketitle
% 
% \CheckSum{656}
% 
% \begin{abstract}
% The \LG{} package is a pretty printer for source
% code. It evolved from vgrind, supported \TeX{} (tgrind) and
% \LaTeX{} and now finally \LaTeXe, in particular \NFSS.
% \end{abstract}
% 
% \changes{v1.0}{1985/02/10}{Written}
% \changes{v2.0}{1991/09/06}{Upgrade to LaTeX209}
% \changes{v3.0}{1995/09/24}{Upgrade to LaTeX2e}
% 
% \section{Introduction}
% \subsection{What is it?}
% The \LG{} package consists of three files:
% \begin{itemize}
% \item \texttt{lgrind} or \texttt{lgrind.exe} is the executable. It will
% convert an \LaTeX-File with embedded listings or a source code file
% into a lot of macro-calls.
% \item \texttt{lgrind.sty} provides the environments and macros to make
% the produced mess readable.
% \item \texttt{lgrindefs} or \texttt{lgrindef} contains the information
% needed to tell keywords from comments, comments from strings \dots
% \end{itemize}
% 
% \subsection{Who is to blame?}
% \LG{} is not the work of a single one. The program is based on
% \textsf{vgrind} by Dave Presotto \& William Joy of UC Berkeley.
% 
% Van Jacobson wrote \textsf{tgrind} for \TeX. Jerry Leichter
% of Yale University modified it for \LaTeX. George V. Reilly of 
% Brown University changed the name to lgrind and added the
% program-text-within-comments and @-within-\LaTeX{} features.
% Matthias Eckermann added a short help text, and finally
% Michael Piefel of Humboldt-University Of Berlin converted it to
% work under \LaTeXe, i.\,e. with \NFSS, added |<|id|>| and |<|rb|>|
% capabilities and improved the documentation.
% 
% \section{\LG{} -- grind nice program listings}
% 
% \begin{tabbing}
% \texttt{lgrind} \= \texttt{[-e] [-i] [-] [-n] [-h }\meta{header}\texttt{] 
% [-d }\meta{description file}\texttt{]}\\
% \> \texttt{[-l }\meta{language}\texttt{]} \meta{name}
% \end{tabbing}
%
% \LG{} processes its input file(s) and writes the result to standard
% output. This output can be saved for later editting, inclusion in a
% larger document, etc.
% 
% The options are:
%
% \makebox[2em][l]{-e} process a \LaTeX-file for embedded text.
% 
% \makebox[2em][l]{-i} process for inclusion in a \LaTeX-document.
% 
% \makebox[2em][l]{-}  take input from standard input.
% 
% \makebox[2em][l]{-n} don't boldface keywords.
% 
% \makebox[2em][l]{-h} specifies text to go on the left side of every output 
% page (default is none).
% 
% \makebox[2em][l]{-d} specifies the language definitions file (the default is
% \texttt{/cs/lib/lgrindefs}
% 
% \makebox[2em][l]{} or whatever was |#DEFINED| during compile).
% 
% \makebox[2em][l]{-l} specifies the language to use. Currently known are
% \begin{itemize}\begin{itemize}
% \item C (-lc or the default),
% \item C++ (-lc++ or -lCC),
% \item Pascal (-lp or -lpascal),
% \item Modula-2 (-lm2),
% \item Fortran (-lf),
% \item RATFOR (-lr),
% \item Yacc (-ly),
% \item PostScript (-lps),
% \item Prolog (-lprolog),
% \item MLisp (-lmlisp),
% \item Icon (-lI),
% \item \TeX{} (-ltex),
% \item Metafont (-lmf),
% \item Perl (-lperl),
% \item CSH (-lcsh),
% \item Bourne Shell (-lsh)
% \item assembler (-lasm),
% \item 68000 assembler (-la68),
% \item asm68 (-lasm68),
% \item VMS assembler (-lvmsasm),
% \item ISP (-lisp),
% \item LDL (-lldl),
% \item Linda (-llinda),
% \item MODEL (-lm)\hspace{3em}and
% \item Russell (-lrussell).
% \end{itemize}\end{itemize}
% 
% If neither -e nor -i are specified, a complete \LaTeX-file is produced.
% 
% \subsection{Usage}
% For example, to include a C-file named \texttt{foo.c} into your 
% \LaTeX-document, first give the command:
% |lgrind -i -lc foo.c > foo.tex|
% 
% This will generate \texttt{foo.tex}, which will have the
% pretty-printed version of \texttt{foo.c} with a lot of \LaTeX-commands.
% Then include \texttt{lgrind.sty} as you include any other package,
% namely with |\usepackage{lgrind}| at
% the beginning of your \LaTeX-document. Having done this,
% within the document you can include \texttt{foo.tex} using one of the
% commands described in the next section.
% 
% Use |lgrind -ly bary.y > bary.tex| to produce a standalone \LaTeX-file
% from, say, a Yacc file.
% This uses Piet van Oostrum's \textsf{fancyheadings.sty} to make the
% headers and footers. BTW: You really should have this package. It's
% marvellous.
% 
% Finally, when you have a \LaTeX-file with embedded program listings,
% you can preprocess it:
% |lgrind -e pretty-sources.lg > even-prettier-sources.tex|
% and get a new \LaTeX-file which you then feed into \LaTeX.
% 
% \section{Using the \LG.sty-file}
% The \LG{} package is included via the |\usepackage| command.
% Currently the following options are supported:
% \begin{description}
% \item[procnames] prints the names of starting and, if nested
% procedures are allowed, continued procedures in the margin. Don't make the
% margin too small, or don't make the names too long \dots
% \item[noindent] cancels the indentation. Useful for long listings or listings
% within their own sections.
% \item[nolineno] doesn't print line numbers.\footnote{To be exact, prints line
% numbers every 50,000 lines. But source code should never get so long in a
% single file~-- that's over 3 MByte! If you really want no numbers,
% set $\backslash$\texttt{LGnuminterval} to zero; then you won't get procedure
% names, either.}
% \item[lineno5] prints line numbers every 5 lines. The default is 10.
% \item[leftnum] print line numbers in the left margin. Default is the right.
% \end{description}
% 
% \subsection{Stand-alone and included listings}
% After processing a source code file with \LG{} without the -e or -i
% options you get a \LaTeX-file which can be directly compiled.
% 
% When using -i \LG{} will produce a file which can be included with the
% following macros:
% 
% \DescribeMacro{\lgrindfile}
% The first is |\lgrindfile{|\meta{file}|}|, which will simply include 
% the file \meta{file} at that point of text, and will draw horizontal
% lines before and after the listing.
% 
% \DescribeMacro{\lagrind}
% The macro |\lagrind[|\meta{float}|]{|\meta{file}|}{|\meta{caption}%
% |}{|\meta{label}|}| will put the listing also within a figure
% environment, using the \meta{float} options (h, t, b or p), \meta{caption}
% and \meta{label} you gave. The starred form of |\lagrind| will also
% use the starred |figure*|.
% 
% \subsection{Formatting your source code}
% Well, \LG{} uses a different font for comments. This has as a consequence
% that functions you refer to are typeset differently in the program and
% in the comments, which is unsatisfactory. And, wouldn't it be great to
% use \LaTeX{} commands to produce e. g. `\copyright'?
% 
% The \texttt{lgrindefs}-file defines environments for exactly these
% purposes. They are usually defined as follows, but of course it is possible
% to use other strings if the standard collides with the syntax of the
% language in question.
% 
% \MakePercentIgnore
% \DescribeEnv{\%\% \%\%}Text which is surrounded by |%%| is directly
% passed to \LaTeX, a pair of curled braces around it. So the copyright
% symbol would be produced with |%%\copyright%%|.
% \DescribeEnv{\%\$ \$\%}The |%$|\meta{text}|$%| works much the same,
% except that \meta{text} is set in math mode.
% 
% \DeleteShortVerb{\|}\MakeShortVerb{\"}\MakePercentIgnore
% \DescribeEnv{\%| |\%}In "%|"\meta{text}"|%" a kind of verbatim
% environment is provided. \meta{Text} is typeset in typewriter.
% 
% \DescribeEnv{@ @}Program text within a comment is surrounded by "@". The text
% is processed exactly as if it wasn't a comment. To produce an at-sign
% you have to use "@@".
% 
% \subsection{Embedded programs within a \LaTeX-file}
% You don't have to process every single source file with \LG{}, only to
% include it your document. Within the text of your \LaTeX-file, you can
% mark groups of lines as program code, either text- or display-style to
% be specific. You can use several commands for controlling the inclusion
% of source code into your \LaTeX-file.
% 
% Write your text, don't forget to include \LG.sty. Use the following
% commands. You can `debug' your text without including the lengthy
% listings. As a last step (but one), you process your file with \LG{}
% and its option -e, which will provide you with your final \LaTeX{}
% source file.
% 
% The commands are similar to the math environments. \DescribeEnv{\%( )\%}
% With "%(" and "%)" you obtain code in text style, i. e. in the same line.
% \DescribeEnv{@ @}Surrounding the text with "@" is a short hand.
% \begin{verbatim}
% The expression
% \%(
% a + 3
% \%)
% produces 10.
% \end{verbatim}
% produces the same as "The expression @a + 3@ produces 10." The output
% will have `a + 3' set as a program.
% 
% \DescribeEnv{\%[ ]\%}As with math, the sqare bracket equivalent produces
% display style listings, i.\,e. indented text on an own line.
% 
% \DescribeEnv{\%=} You can insert your own code by using a line starting with
% "%=" in the program text. Whatever you enter after that is left in the output,
% exactly as you typed it. It will be executed in a strange environment, so
% doing anything fancy is very tricky. \DescribeMacro{\Line} A macro, "\Line",
% is provided to help you do simple things. For example,
% \begin{verbatim}
% \%[
% %=\Line{________\vdots}
%         a = 1;
% \%]
% \end{verbatim}
% produces:
% 
% \hspace*{4em}\vdots
% 
% \hspace*{4em}\textit{a}\textsf{ = 1;}
% 
% (Within the program text, \_ is active and expands to a
% fixed-width space.  A whole bunch of macros are also defined. If you
% understand how lgrind sets lines up, you can replace the 8 \_'s
% with a call to "\Tab" (but I'll let you hang yourself on that one.))
% 
% \DescribeEnv{\%<}The "%<"\meta{file} command includes \meta{file} as a
% program listing in your document. Before inclusion it will be pretty
% printed. This is the almost the same as \LG ing the \meta{file}
% separately and with -i and including it via "\lgrindfile", only that
% it's simpler for you. \DescribeEnv{\%!} With "%!"\meta{command} the
% input is taken from a shell command.
% 
% While you can specify the language used on the command line, this does
% not suffice for mixed-language programs (or projects). The command
% \DescribeEnv{\%\#}"%#"\meta{language} provides you a means to change
% the language on the fly whereever you want.
% 
% Important rules:
% \begin{itemize}\begin{itemize}
% \item "%" and the following character must be the first two characters on
% the line to be recognized.
% \item
% Put \emph{nothing} on the line after the "%" and the key character.
% If you do that, lgrind will provide a default environment that will
% produce an "\hbox" for "%( )%", and a "\vbox" for "%[ %]".
% If you put stuff on the line, lgrind assumes you want to control
% the format completely. Doing this requires understanding \emph{exactly}
% what the code lgrind produces is doing. (Sometimes I'm not sure I do!)
% \item
% "%)" and "%]" are, if I remember right, simply ignored outside
% of a code group, but any extra "%(" or "%[" produces a
% warning, so a missing "%)" or "%]" is usually caught.
% \item
% Remember that the code between "%("/"%[" and "%)"/"%]" is put into a
% single box. Expect the usual problems with long boxes!
% \end{itemize}\end{itemize}
% 
% \subsection{A final word}
% The output of lgrind always contains exactly one output line for each input
% line.  Hence, you can look up line numbers in \TeX{} error messages in your
% original file, rather than in the \LG ed (LGround?) file.  (Of course, if
% the problem is in the lgrind output....)
% 
% \emph{The environment that lgrind's output builds uses a \emph{lot} of
% stack space.  I found I had to build a \LaTeX-with a larger stack,
% but that's not always necessary (it depends on exactly how you
% nest stuff.)}
%  
% Many things are controllable by re-defining various macros.  You can
% change what fonts lgrind will use for various kinds of things, how
% much it indents the output, whether it adds line numbers, and if so at
% what interval it prints them and whether it sticks them on the left or
% right, and so on. This stuff is all described below,
% though probably not very well. The default settings produce output
% that looks reasonable to me, though I can't say I'm ecstatic about it.
% Doing a \emph{really} good job would require defining some special fonts.
% 
% \section{The \texttt{lgrindefs}-file}
% The \texttt{lgrindefs} file is \LG's language definition data base.
% It is here where \LG{} learns what are keywords, what comments, where
% are functions, how to distiguish plain comments from \LaTeX-commands etc.
% 
% The first field is just the language name (and any variants
% of it). Thus the C language could be specified to \LG{} as `c' or `C'.
% 
% \subsection{Capabilities}
% Capabilities are of two types: Boolean capabilities which indicate that
% the language has some particular feature and string capabilities which
% give a regular expression or keyword list.
% 
% Entries may continue onto multiple lines by giving a "\" as the last
% character of a line. Lines starting with "#" are comments.
% 
% The following table names and describes each capability.
% \begin{description}
% \item[ab] Regular expression for the start of an alternate form comment
% \item[ae] Regular expression for the end of an alternate form comment
% \item[bb] Regular expression for the start of a block
% \item[be] Regular expression for the end of a lexical block
% \item[cb] Regular expression for the start of a comment
% \item[ce] Regular expression for the end of a comment
% \item[cf] (Boolean) Use specialized routine for detecting C functions
% \changes{v3.1}{1995/11/12}{C functions are now detected much more reliably}
% \item[id] String giving characters other than letters and digits
% that may legally occur in identifiers (default `\_')
% \item[kw] A list of keywords separated by spaces
% \item[lb] Regular expression for the start of a character constant
% \item[le] Regular expression for the end of a character constant
% \item[mb] Regular expression for the start of \TeX{} math within a comment
% \item[me] Regular expression for the end of \TeX{} math within a comment
% \item[np] Regular expression for a line that does \emph{not} contain
% the start of a procedure (e.\,g. prototypes)
% \item[oc] (Boolean) Present means upper and lower case are equivalent
% \item[pb] Regular expression for start of a procedure
% \item[pl] (Boolean) Procedure definitions are constrained to the lexical
% level matched by the `px' capability
% \item[px] A match for this regular expression indicates that procedure
% definitions may occur at the next lexical level. Useful for lisp-like
% languages in which procedure definitions occur as subexpressions of defuns.
% \item[rb] Regular expression for the start of block outside the actual
% code.\footnote{I included this especially for the \texttt{objects} and
% \texttt{records} in Pascal and Modula-2. They \emph{end} (with the "<"be">"
% expression), but shouldn't have influence on the surrounding procedure.
% When defining \texttt{record} as normal block start, its \texttt{end} ends
% the procedure. Workaround: Make \texttt{record} itself a procedure start.
% But that prints a continuation mark when \textsf{procnames} is on.}
% \changes{v3.1}{1995/11/12}{Pascal objects now treated properly}
% \item[sb] Regular expression for the start of a string
% \item[se] Regular expression for the end of a string
% \item[tb] Regular expression for the start of \TeX{} text within a comment
% \item[tc] (String) Use the named language entry as a continuation of the
% current one
% \item[te] Regular expression for the end of \TeX{} text within a comment
% \item[tl] (Boolean) Present means procedures are only defined at the top
% lexical level
% \item[vb] Regular expression for the start of typewriter text within a
% comment
% \item[ve] Regular expression for the end of typewriter text within a comment
% \item[zb] Regular expression for the start of program text within a comment
% \item[ze] Regular expression for the end of program text within a comment
% \end{description}
% 
% \subsection{Regular Expressions}
% \texttt{lgrindefs} uses regular expressions similar to those of
% \textsf{ex} and \textsf{lex}. The characters `"^"', `"$"', `"|"', `:',
% and `"\"' are reserved characters and must be `quoted' with a preceding
% "\" if they are to be included as normal characters.
% 
% The metasymbols and their meanings are:
% \begin{description}
% \item[\$] The end of a line
% \item[\^] The beginning of a line
% \item[$\backslash$d] A delimiter (space, tab, newline, start of line)
% \item[$\backslash$a] Matches any string of symbols (like `.*' in lex)
% \item[$\backslash$p] Matches any identifier. In a procedure definition
% (the `pb' capability) the string that matches this symbol is used
% as the procedure name.
% \item[( )] Grouping
% \item[$|$] Alternation
% \item[?] Last item is optional
% \item[$\backslash$e] Preceding any string means that the string will not
% match an input string if the input string is preceded by an escape character
% ("\"). This is typically used for languages (like C) that can include the
% string delimiter in a string by escaping it.
% \end{description}
% 
% Unlike other regular expressions in the system, these match words and
% not characters. Hence something like `(tramp"|"steamer)flies?'
% would match `tramp', `steamer', `trampflies', or `steamerflies'.
% Contrary to some forms of regular expressions, \texttt{lgrindefs}
% alternation binds very tightly. Grouping parentheses are likely to
% be necessary in expressions involving alternation.
% 
% \subsection{Keyword List}
% The keyword list is just a list of keywords in the language separated
% by spaces. If the `oc' boolean is specified, indicating that upper
% and lower case are equivalent, then all the keywords should be specified
% in lower case.
% 
% \subsection{Configuration options}
% \changes{v3.1}{1995/11/07}{The \LaTeX-text put into the files is no longer
% hardcoded into the executable}
% In addition to the language definitions the \texttt{lgrindefs}-file
% contains various configuration data. When the entries do not exist,
% default values are used:
% \begin{description}
% \item[firstpreamble] is the (\LaTeX-)text that comes at the beginning of
% an stand alone file created by \textsf{LGrind} from source code.
% \item[filepreamble] is inserted before every processed source file in a
% stand alone \LaTeX-file.
% \item[configuration] follows the opening of the \texttt{lgrind}-environment.
% This is used for redefining the macros used within it, e.\,g. the fonts
% or the width of a space (the "\@ts" unit).
% \item[chartab] is a list of characters that will be substituted by a
% \LaTeX-string. This is useful when you do (or can) not use any of the fancy
% methods to persuade \LaTeX{} into using your extended ASCII-characters.
% The format is a two digit hex number (the ASCII- (or whatever) value of the
% character), an equal sign, and the according \LaTeX{}-string, ended with a
% colon. You have to escape certain characters (like the backslash). So if
% you, e.\,g., have IBM ASCII code page 437 input and use the
% \textsf{german}-package, you can have your \"a using \verb+84="a+. Note
% that the substituting string must contain more than one character;
% otherwise it will be ignored. To print a `b' instead of an `a' you can
% use \verb+61={b}+.
% \end{description}
%
% \StopEventually{\PrintChanges\PrintIndex}
%
% \section{The Implementation of \LG.sty}
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
% \setlength{\parindent}{0pt}
%
% \begin{macro}{\LGnuminterval}\begin{macro}{\lc@unt}\begin{macro}{\ln@xt}
% The counter "\LGnuminterval" represents the line numbering interval.
% Its default is 10, it is set by two options and can be changed everywhere
% you want to. "\lc@unt" counts the current line, "\ln@xt" contains the next
% line to get numbered.
%    \begin{macrocode}
\newcount\lc@unt
\newcount\ln@xt
\newcount\LGnuminterval
\LGnuminterval=10
\DeclareOption{nolineno}{\LGnuminterval=50000}
\DeclareOption{lineno5}{\LGnuminterval=5}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\LGleftnum}
% Line numbers are usually on the right. By setting "LGleftnum" to true
% or false this behaviour can be altered. When putting the numbers on the
% left, procedure names will occur on the line \emph{after} the start of
% the procedure; this is a bug. (Does anyone need it? Then tell me so.)
%    \begin{macrocode}
\newif\ifLGleftnum
\DeclareOption{leftnum}{\LGleftnumtrue}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\LGindent}
% "\LGindent" is the indentation for all display style listing lines.
%    \begin{macrocode}
\newskip\LGindent
\LGindent=1.6667\parindent
\DeclareOption{noindent}{\LGindent=0pt}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Proc}\begin{macro}{\ProcCont}
% There's a "\Proc{"\meta{ProcName}"}" at the start of each procedure.  If
% the language allows nested procedures (e.\,g. Pascal), there
% will be a "\ProcCont{"\meta{ProcName}"}" at the end of each inner procedure.
% (In this case, \meta{ProcName} is the name of the outer procedure. I.\,e.,
% "\ProcCont" marks the continuation of \meta{ProcName}).
%
% \begin{macro}{\DefaultProc}
% \changes{v3.0}{1995/09/24}{Reintroduced procedure names in the margins}
% \begin{macro}{\DefaultProcCont}
% Default is not to do anything with the name. Optionally the names are
% printed in the same margin as the line numbers. The name is put into a
% box which will be output whenever it is not empty.
%
%    \begin{macrocode}
\newcommand{\DefaultProc}{\@gobble}
\newcommand{\DefaultProcCont}{\@gobble}
\DeclareOption{procnames}{
\renewcommand{\DefaultProc}[1]{\renewcommand{\Procname}{#1}%
\global\setbox\procbox=\hbox{\PNsize #1}}
\renewcommand{\DefaultProcCont}[1]{\renewcommand\Procname{#1}
\global\setbox\procbox=\hbox{\PNsize\dots #1}}}
\newbox\procbox
\newcommand{\Procname}{}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% End of initialization, execute any options.
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
% \changes{v3.0}{1995/09/28}{Added package options}
%
% \begin{macro}{\BGfont}\begin{macro}{\CMfont}\begin{macro}{\NOfont}
% \changes{v3.1}{1995/11/12}{Numbers can now have an own style (i.\,e. font)}
% \begin{macro}{\KWfont}\begin{macro}{\STfont}\begin{macro}{\VRfont}
% \begin{macro}{\PNsize}\begin{macro}{\LGsize}\begin{macro}{\LGfsize}
% These are the fonts and sizes for background (everything that doesn't fit
% elsewhere), comments, numbers, keywords, strings, variables, the procedure
% names
% in the margins, displayed code ("%[ ]%"), and included code ("\lgrindfile"
% and "\lagrind"), respectively. Note that the suffixes `font' and `size'
% have been chosen solely for the author's intention; you can do anything
% you want, e.\,g. "\tiny" comments. You have to use, however, font changes
% which don't require an argument.
%    \begin{macrocode}
\def\BGfont{\sffamily}
\def\CMfont{\rmfamily\itshape}
\def\NOfont{\sffamily}
\def\KWfont{\rmfamily\bfseries}
\def\STfont{\ttfamily}
\def\VRfont{\rmfamily}
\def\PNsize{\BGfont\small}
\def\LGsize{\small}
\def\LGfsize{\footnotesize}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
% \end{macro}\end{macro}\end{macro}
% \end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\ifLGinline}\begin{macro}{\ifLGd@fault}
% \begin{macro}{\LGbegin}\begin{macro}{\LGend}
% The flag "LGinline" is true for in-line code. "\LGbegin" and "\LGend" are
% default commands to open and close a code example and use it to perform
% certain ops depending whether we're in-line or display style."\LGend" is
% a no-op unless "\LGbegin" (where "LGd@fault" is set true) was executed,
% so you can provide explicit open
% code on the "%[" or "%(" line without providing any special code on the
% matching "%]" or "%)" line.
%    \begin{macrocode}
\newif\ifLGinline
\newif\ifLGd@fault
\def\LGbegin{\ifLGinline$\hbox\else$$\vbox\fi\bgroup\LGd@faulttrue}
\def\LGend{\ifLGd@fault\egroup\ifLGinline$\else$$\fi\LGd@faultfalse\fi}
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\ifc@omment}\begin{macro}{\ifstr@ng}
% These two conditions indicate if we are setting a comment or maybe
% a string constant, respectively.
%    \begin{macrocode}
\newif\ifc@mment
\newif\ifstr@ng
%    \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\ifright@}
% To get decent quotes (opening and closing) within comments, we remember
% whether the next one is going to be `{}``'{} or, if true, `{}'''{}.
%    \begin{macrocode}
\newif\ifright@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ls@far}\begin{macro}{\tb@x}\begin{macro}{\TBw@d}
% These three are all for the sake of tabbing. "\ls@far" stores the
% ``line so far''. The tabwidth goes in "\TBw@d", whilst "\tb@x" is 
% merely a temporary variable for "\Tab" and setting "\@ts".
%    \begin{macrocode}
\newbox\ls@far
\newbox\tb@x
\newdimen\TBw@d
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}
%
% The underscore marks a point where the pre-processor wants a fixed-width
% space (of width "\@ts").
%    \begin{macrocode}
\newdimen\@ts
{\catcode`\_=\active \gdef\@setunder{\let_=\sp@ce}}
%    \end{macrocode}
%
% \begin{environment}{lgrind}
% Here you really should see "\newenvironment"\dots, but it works, and, you
% know, ``Never touch a running system!''. This is the environment that
% eventually defines all necessary macros for formatting.
%    \begin{macrocode}
\def\lgrind{%
%    \end{macrocode}
%
% \begin{macro}{\Line}
% The "\Line" macro is provided for use with "%=" in embedded listings.
% It's just there to hide the actual structure of this, for nobody 
% \emph{really} wants to know anyway.
%    \begin{macrocode}
\def\Line##1{\L{\LB{##1}}}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Head}\begin{macro}{\File}
% The next are primarily meant for stand-alone listings. One of my
% predecessors removed them, I put them back in. "\Head" doesn't do
% anything~-- it isn't even used anywhere. The "\Proc"s now get what
% was specified for them in the options section.
%    \begin{macrocode}
\let\Head=\@gobble%
\def\File##1,##2,##3{\message{(LGround: ##1)}}%
\let\Proc=\DefaultProc%
\let\ProcCont=\DefaultProcCont%
%    \end{macrocode}
% \end{macro}\end{macro}
%
% \begin{macro}{\NewPage}
% Each formfeed in the input is replaced by a "\NewPage" macro.  If
% you really want a page break here, define this as "\vfill\eject".
%    \begin{macrocode}
\def\NewPage{\filbreak\bigskip}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\L}
% Each line of displayed program text is enclosed by a "\L{"\dots"}". We 
% turn each line into an hbox. Firstly we look whether we are in-line.
% Every "\LGnuminterval" lines we output a 
% small line number in past the margin.
%    \begin{macrocode}
\ifLGinline
 \def\L##1{\setbox\ls@far\null{\CF\strut##1}\ignorespaces}%
%    \end{macrocode}
% \begin{macro}{\r@ghtlno}\begin{macro}{\l@ftlno}
% Things get more difficult for display style listings. Here we set
% "\r@ghtlno" and "\l@ftlno" to no-ops, only to redefine them shortly
% after.
%    \begin{macrocode}
\else
 \let\r@ghtlno\relax\let\l@ftlno\relax
 \ifnum\LGnuminterval>\z@
  \ifLGleftnum
%    \end{macrocode}
% If there was a procedure name somewhere, "\procbox" is not empty and
% thus ready to be printed. Otherwise we test "\lc@unt" against "\ln@ext"
% to determine whether or not to print a line number.
%    \begin{macrocode}
   \def\l@ftlno{\ifvoid\procbox\ifnum\lc@unt>\ln@xt
     \global\advance\ln@xt by\LGnuminterval
     \llap{{\normalfont\scriptsize\the\lc@unt\quad}}\fi
     \else\llap{\box\procbox\quad}\fi}%
%    \end{macrocode}
% And once again when the line number is meant to be on the right.
%    \begin{macrocode}
  \else
   \def\r@ghtlno{\ifvoid\procbox\ifnum\lc@unt>\ln@xt
     \global\advance\ln@xt by\LGnuminterval
     \rlap{{\normalfont\scriptsize\enspace\the\lc@unt}}\fi
     \else\rlap{\enspace\box\procbox}\fi}%
  \fi
 \fi
%    \end{macrocode}
% \end{macro}\end{macro}
% "\lc@unt" is incremented and everything is sqeezed into a "\hbox".
%    \begin{macrocode}
 \def\L##1{\@@par\setbox\ls@far=\null\strut
  \global\advance\lc@unt by1%
  \hbox to\hsize{\hskip\LGindent\l@ftlno ##1\egroup\hfil\r@ghtlno}%
  \ignorespaces}%
\fi
%    \end{macrocode}
% \end{macro}
%
% The initialization of "\lc@unt" and "\ln@xt". Every "lgrind"-environment
% starts over.
%    \begin{macrocode}
\lc@unt=0\ln@xt=\LGnuminterval\advance\ln@xt by-1%
%    \end{macrocode}
%
% \begin{macro}{\LB}\begin{macro}{\Tab}
% The following weirdness is to deal with tabs. ``Pieces'' of a line
% between tabs are output as "\LB{"\dots"}". E.\,g., a line with a tab at
% column 16 would be output as "\LB{xxx}\Tab{16}\LB{yyy}". (Actually, to
% reduce the number of characters in the ".tex" file the "\Tab" macro
% supplies the 2nd \& subsequent "\LB"s.) We accumulate the "\LB" stuff in 
% an "\hbox". When we see a "\Tab", we grab this hbox (using "\lastbox") 
% and turn it into a box that extends to the tab position.  We stash this 
% box in "\ls@far" \& stick it on in front of the next piece of the line.  
% (There must be a better way of doing tabs but I'm not enough of a \TeX 
% wizard to come up with it. Suggestions would be appreciated. Oh, well,
% this comment's been in here for a decade. I don't believe in Santa Claus.)
%    \begin{macrocode}
\def\LB{\hbox\bgroup\bgroup\box\ls@far\CF\let\next=}%
\def\Tab##1{\egroup\setbox\tb@x=\lastbox\TBw@d=\wd\tb@x%
 \advance\TBw@d by 1\@ts\ifdim\TBw@d>##1\@ts
  \setbox\ls@far=\hbox{\box\ls@far \box\tb@x \sp@ce}\else
  \setbox\ls@far=\hbox to ##1\@ts{\box\ls@far \box\tb@x \hfil}\fi\LB}%
%    \end{macrocode}
% \end{macro}\end{macro}
%
% A normal space is too thin for code listings.  We make spaces \& tabs
% be in "\@ts" units, which for displays are 80 \% the width of a ``0'' in the
% typewriter font. For inline stuff, on the other hand, we prefer a 
% somewhat smaller space -- actually, the same size as normal inter-word 
% spaces -- to help make the included stuff look like a unit.
%    \begin{macrocode}
\ifLGinline\def\sp@ce{\hskip .3333em}%
\else \setbox\tb@x=\hbox{\texttt{0}}%
      \@ts=0.8\wd\tb@x \def\sp@ce{\hskip 1\@ts}\fi
\catcode`\_=\active \@setunder
%    \end{macrocode}
%
% \begin{macro}{\CF}\begin{macro}{\N}\begin{macro}{\K}\begin{macro}{\V}
% \begin{macro}{\ic@r}
% \begin{macro}{\C}\begin{macro}{\CE}\begin{macro}{\S}\begin{macro}{\SE}
% Font changing. Since we are usually changing the font inside of a "\LB"
% macro, we remember the current font in "\CF" \& stick a "\CF" at the 
% start of each new box. Also, the characters ``\texttt{\char'042}'' and 
% ``"'"'' behave differently in comments than in code, and others behave 
% differently in strings than in code.
%
% "\N" is for numbers, "\K" marks keywords, "\V" variables, "\C" and "\CE"
% surround comments, "\S" and "\SE" strings. "\ic@r" inserts an optional "\/".
%    \begin{macrocode}
\def\CF{\ifc@mment\CMfont\else\ifstr@ng\STfont\fi\fi}
\def\N##1{{\NOfont ##1}\global\futurelet\next\ic@r}%
\def\K##1{{\KWfont ##1}\global\futurelet\next\ic@r}%
\def\V##1{{\VRfont ##1}\global\futurelet\next\ic@r}%
\def\ic@r{\let\@tempa\/\ifx.\next\let\@tempa\relax%
 \else\ifx,\next\let\@tempa\relax\fi\fi\@tempa}%
\def\C{\egroup\bgroup\CMfont \global\c@mmenttrue \global\right@false}%
\def\CE{\egroup\bgroup \global\c@mmentfalse}%
\def\S{\egroup\bgroup\STfont \global\str@ngtrue}%
\def\SE{\egroup\bgroup \global\str@ngfalse}%
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
% \end{macro}\end{macro}\end{macro}\end{macro}
%
% \begin{macro}{\,}\begin{macro}{\!}
% We need positive and negative thinspaces in both text and math modes, so
% we re-define "\," and "\!" here.  The definition for "\," isn't really 
% needed for \LaTeX, but we try to be more complete.  Note that in \LaTeX{}
% terms, the new definition isn't robust, like the old~-- but nothing we 
% produce here is likely to be robust --~or \emph{needs} to be!~-- anyway!
%    \begin{macrocode}
\def\,{\relax \ifmmode\mskip\thinmuskip \else\thinspace \fi}%
\def\!{\relax \ifmmode\mskip-\thinmuskip \else\negthinspace \fi}%
%    \end{macrocode}
% \end{macro}\end{macro}
%
% Special characters. "\CH" choses its first option alone in math mode;
% its second option in a string; and its third option, enclosed in "$"s,
% otherwise. (At the moment, nothing is ever set in math mode, but you
% never know \dots)
%    \begin{macrocode}
\def\CH##1##2##3{\relax\ifmmode ##1\relax
\else\ifstr@ng ##2\relax\else$##3$\fi\fi }%
\def\{{\CH\lbrace {\char'173}\lbrace }%
\def\}{\CH\rbrace {\char'175}\rbrace }%
\def\1{\CH///}%                                % /
\def\2{\CH\backslash {\char'134}\backslash }%  % \
\def\|{\CH|{\char'174}|}%
\def\<{\CH<<<}%
\def\>{\CH>>>}%
\def\*{\CH***}\relax %\relax for DOCSTY
\def\-{\CH---}%
\def\_{\ifstr@ng {\char'137}\else
  \leavevmode \kern.06em \vbox{\hrule width.35em}%
  \ifdim\fontdimen\@ne\font=\z@ \kern.06em \fi\fi }%
\def\&{\textsf{\char'046}}%
\def\#{{\STfont\char'043}}%
\def\%{{\char'045}}%
\def\~{{\char'176}}%
\def\3{\ifc@mment\ifright@ ''\global\right@false%
                      \else``\global\right@true \fi
   \else{\texttt{\char'042}}\fi}%
\def\4{\ifc@mment'\else {\texttt{\char'015}}\fi}%
\def\5{{\texttt{\char'136}}}%
\def\${{\ifmmode\slshape\else\ifdim\fontdimen\@ne\font>\z@\slshape\fi\fi
  \char'044}}% %No $ in \it, use \sl
%    \end{macrocode}
%
% Finally we don't want any indentation other than our own. We allow \LaTeX{}
% to stretch our listings a bit. Then we open a group, select the background
% font and (fanfare!) are ready to begin.
%    \begin{macrocode}
\parindent\z@\parskip\z@ plus 1pt\hsize\linewidth%
\bgroup\BGfont
}
%    \end{macrocode}
%
% This is the end of the "lgrind" environment. Rather short (in comparison!)
%    \begin{macrocode}
\def\endlgrind{\egroup\@@par}
%    \end{macrocode}
% \end{environment}
%
% The following are generated as part of opening and closing included
% code sequences.
%    \begin{macrocode}
\def\lgrinde{\ifLGinline\else\LGsize\fi\begin{lgrind}}
\def\endlgrinde{\end{lgrind}}
%    \end{macrocode}
%
% \begin{macro}{\lagrind}
% The "lagrind" environment is one of two for including files. It puts
% its argument inside a "figure" environment. It can be used without or
% with a star (first line), and with or without the usual floating
% arguments (second and third).
%    \begin{macrocode}
\def\lagrind{\@ifstar{\@slagrind}{\@lagrind}}

\def\@lagrind{\@ifnextchar[{\@@lagrind}{\@@lagrind[t]}}
\def\@slagrind{\@ifnextchar[{\@@slagrind}{\@@slagrind[t]}}
%    \end{macrocode}
%
% \begin{macro}{\@@lagrind}
% The unstarred version. Everything is pretty obvious, we open a "figure",
% put in a "minipage", input the file in question, make caption and label
% and that's it.
%    \begin{macrocode}
\def\@@lagrind[#1]#2#3#4{%
    \begin{figure}[#1]
\hrule
\vskip .5\baselineskip
\begin{minipage}\columnwidth\LGsize\LGindent\z@
    \begin{lgrind}
\input #2\relax
    \end{lgrind}
\end{minipage}
\vskip .5\baselineskip plus .5\baselineskip
\begingroup
    \setbox\z@=\hbox{#4}%
    \ifdim\wd\z@>\z@
\caption{#3}%
\label{#4}%
    \else
\captcont{#3}%
    \fi
\endgroup
\vskip 2pt
\hrule
    \end{figure}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@slagrind}
% D\'ej\`a vu? The starred version got an asterisk attached to "figure".
%    \begin{macrocode}
\def\@@slagrind[#1]#2#3#4{%
    \begin{figure*}[#1]
\hrule
\vskip .5\baselineskip
\begin{minipage}\textwidth\LGsize\LGindent\z@
    \begin{lgrind}
\input #2\relax
    \end{lgrind}
\end{minipage}
\vskip .5\baselineskip plus .5\baselineskip
\begingroup
    \setbox\z@=\hbox{#4}%
    \ifdim\wd\z@>\z@
\caption{#3}%
\label{#4}%
    \else
\captcont{#3}%
    \fi
\endgroup
\vskip 2pt
\hrule
    \end{figure*}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\lgrindfile}
% This is similar. We draw lines above and below, no "figure". But it can
% get longer than one page.
%    \begin{macrocode}
\def\lgrindfile#1{%
    \par\addvspace{0.1in}
    \hrule
    \vskip .5\baselineskip
    \begingroup\LGfsize\LGindent\z@
\begin{lgrind}
    \input #1\relax
\end{lgrind}
    \endgroup
    \vskip .5\baselineskip
    \hrule
    \addvspace{0.1in}
}
%    \end{macrocode}
% \end{macro}
%
% And now \dots
%    \begin{macrocode}
%</package>
%    \end{macrocode}
% That's it. Thank you for reading up to here.
%
% \vspace{4ex} Michael Piefel
%
% piefel@cs.tu-berlin.de
%
% \vspace{2ex}
% \hrule
% \vspace{2ex}
%
% \Finale
\endinput
