% macros for the LWEB system by DCB -*- Mode: TeX; Syntax: Common-lisp; Package: LWEB -*-

% setup
\catcode`\@=11

% fonts
\def\LWnormalfont {\rm}
\def\LWcommentfont {\it}
\def\LWpuncfont {\tt}
\def\LWcodefont {\rm}
\def\LWcodepuncfont {\tt}
\def\slantedcode {%
  \font\sltt=amsltt10
  \def\LWcodefont{\sl}%
  \def\LWcodepuncfont{\sltt}}
\def\boldcode {%
  \def\LWcodefont{\bf}%
  \def\LWcodepuncfont{\tt}}

% delimiters
\newdimen\LWparenkern   \LWparenkern=.1pt
\newdimen\LWcommentkern \LWcommentkern=1pt
\newdimen\LWspacewidth  \LWspacewidth=.45em
\def\LWop/{{\rm(\kern\LWparenkern}}
\def\LWcp/{\/{\rm\kern\LWparenkern)}}
\def\LWobrace/{{$\{$\kern\LWparenkern}}
\def\LWcbrace/{\/{\kern\LWparenkern$\}$}}
\def\LWquot/{\raise.3ex\hbox{\LWpuncfont\char`\"}}
\def\LWstar/{\lower.05ex\hbox{\LWpuncfont\char`\*}}
\def\LWchr {\LWpuncfont\char}
\def\LWsetpwidth {\setbox\z@=\hbox{\LWop/}\LWpwidth=\wd\z@}
\newdimen\LWpwidth      \LWsetpwidth

% indentations
\def\LWpi/{\kern\LWpwidth}              % increment for plus1
\def\LWpii/{\kern 2\LWspacewidth}       % increment for plus2
\def\LWpiv/{\kern 4\LWspacewidth}       % increment for plus4
\def\LWks #1{\kern #1\LWspacewidth}     % kern a number of space widths


% boxes
\newbox\LWbox
\newdimen\LWboxw
\def\LWsb {\setbox\LWbox=\hbox}         % start a box
\def\LWdb/{\box\LWbox}                  % dump out a box
\def\LWbb {\LWboxw=\wd\LWbox            % output a box and backspace over it
           \box\LWbox
           \kern-\LWboxw}

% markers
\def\LWsm #1{\xdef#1{\the\wd\LWbox}%    % set a mark register
             \box\LWbox}
\def\LWkr #1{\kern #1\relax}            % kern a register
\def\LWkm {\LWbb\LWkr}                  % kern to a marked position

% modules

% keep track of position in file: top, after module, before module
\newif\iffirstmodule \firstmoduletrue
\newif\ifmodule

% incrementally number modules
\newcount\modulecount

% normal modules
\def\LWbeginmodule/{%
  \iffirstmodule \firstmodulefalse
  \else          \LWfilbreak \bigskip \fi
  \advance\modulecount\@ne
  \LWmarkmodule
  \begingroup \LWmoduledefs
  \noindent {\bf \number\modulecount.}\enspace \ignorespaces}

\def\LWendmodule/{%
  \endgraf
  \endgroup
  \moduletrue}

\def\LWmarkmodule {}

\def\LWmoduledefs {\def\par{\endgraf\nobreak}\LWsetpwidth}

% star modules
\def\LWbeginstarmodule #1{%
  \iffirstmodule \firstmodulefalse
  \else          \vfil \eject \fi
  \advance\modulecount\@ne
  \LWmarkstarmodule{#1}%
  \begingroup \LWmoduledefs
  \noindent {\bf \number\modulecount. \ignorespaces #1\par}
  \nobreak \smallskip \noindent \ignorespaces}

\def\LWmarkstarmodule {\message{*\number\modulecount}\mark}

% spacing and layout
\def\LWfilbreak {\vfil\penalty-200\vfilneg}
\def\LWfilnobreak {\vfil\penalty9999\vfilneg}
\parindent=2em
\interlinepenalty=10000                         % forbid page breaks in modules

% code in module text
\def\LWbcode/{\begingroup \LWcodefont \LWcodedefs \let\LWpuncfont=\LWcodepuncfont}
\def\LWecode/{\/\endgroup}

% code
\def\LWbeginlisp/{%
  \iffirstmodule \beginmodule \endmodule \fi
  \ifmodule \modulefalse \LWfilnobreak \bigskip
  \else     \LWfilnobreak \medskip \fi
  \vbox\bgroup \LWnormalfont \LWcodedefs}

\def\LWendlisp/{%
  \egroup}

\def\LWcodedefs {%
  \spaceskip=\LWspacewidth
  \xspaceskip=\LWspacewidth
  \LWsetpwidth}

% module text in code
\def\LWcommentdefs {\spaceskip=\z@ \xspaceskip=\z@ \LWcommentfont \LWsetpwidth}
\def\LWbcom/{\begingroup \LWcommentdefs {\rm;\kern\LWcommentkern}}
\def\LWecom/{\endgroup}

% miscellany
\ifx\lisp\undefined
  \def\lisp {Lisp}
  \let\LISP=\lisp
  \let\Lisp=\lisp
\fi
\def\lweb {LWEB}
\let\LWEB=\lweb

% cleanup
\catcode`\@=12