\documentstyle[noweb,twoside]{article}
\pagestyle{noweb}
\noweboptions{longchunks,smallcode}
\title{{\TeX} support for {\tt noweb}}
\author{Norman Ramsey}
\newcommand{\stylehook}{\marginpar{\raggedright\sl Style hook}}
\begin{document}
\maketitle
\tableofcontents
@ 
This document describes the {\TeX} code that supports {\tt noweave}
and {\tt noweb}.  Those interested in customizing their output should
focus on Section~\ref{section:sty}.  
Hooks you can easily use (apart from those provided by
[[\noweboptions]]) are indicated by marginal notes.
This file contains both plain {\TeX} and {\LaTeX} support:
<<nwmac.tex>>=
% nwmac.tex -- plain TeX support for noweb
% DON'T read or edit this file!  Use ...noweb-source/tex/support.nw instead.
<<noweb.sty>>=
% noweb.sty -- LaTeX support for noweb
% DON'T read or edit this file!  Use ...noweb-source/tex/support.nw instead.
@

\section{Basic {\TeX} support for {\tt noweb}}
This basic code is used for both {\TeX} and {\LaTeX}.
The first step is to define [[\codehsize]], which is the width in
which code is set, and [[\codemargin]], which is the amount by which
it is indented.\stylehook
<<kernel>>=
% make \hsize in code sufficient for 88 columns
\setbox0=\hbox{\tt m}
\newdimen\codehsize
\codehsize=91\wd0 % 88 columns wasn't enough; I don't know why
\newdimen\codemargin
\codemargin=0pt
@ %def \codehsize \codemargin
[[\defspace]] is the space we would like on the right of navigational info
that appears on definition lines, so that it lines up with the text above
and below.
<<kernel>>=
\newdimen\nwdefspace
\nwdefspace=\codehsize
\advance\nwdefspace by -\textwidth\relax
@
Most code is set in an environment in which [[\setupcode]] has been
executed.
In this environment, only [[\]], [[{]], and [[}]] have their usual
categories; every other character represents itself.
Appropriate [[\chardef]]s ensure that the special characters can be
escaped with a backslash.
<<kernel>>=
\chardef\other=12
\def\setupcode{%
  \chardef\\=`\\
  \chardef\{=`\{
  \chardef\}=`\}
  \catcode`\$=\other
  \catcode`\&=\other
  \catcode`\#=\other
  \catcode`\%=\other
  \catcode`\~=\other
  \catcode`\_=\other
  \catcode`\^=\other
  \obeyspaces\Tt
}
@ %def \setupcode 
[[\eatline]] is used to consume newlines that should be ignored,
for example, the newlines at the end of [[@ %def ]]{\em identifiers} lines.
I can't remember what [[\startline]] or [[\newlines]] are for; I don't
think {\tt noweave} ever emits them.
<<kernel>>=
{\catcode`\^^M=\active % make CR an active character
  \gdef\newlines{\catcode`\^^M=\active % make CR an active character
         \def^^M{\par\startline}}%
  \gdef\eatline#1^^M{\relax}%
}
%%% DON'T   \gdef^^M{\par\startline}}% in case ^^M appears in a \write
\def\startline{\noindent\hskip\parindent\ignorespaces}
\def\nwnewline{\ifvmode\else\hfil\break\fi}
@ %def \startline \eatline \nwnewline

Within a code environment, it may be necessary to restore the 
category codes in order to set a module (chunk) name.
<<kernel>>=
{\obeyspaces\global\let =\ } % from texbook, p 381
\def\setupmodname{%
  \catcode`\$=3
  \catcode`\&=4
  \catcode`\#=6
  \catcode`\%=14
  \catcode`\~=13
  \catcode`\_=8
  \catcode`\^=7
  \catcode`\ =10
  \catcode`\^^M=5
  \Rm}
@ %def \setupmodname
@ \sublabel{ref:fred}

{\tt noweave} brackets uses of chunk names with [[\LA]] and [[\RA]], which
handle the angle brackets, font, and environment.

As it stands, chunk names can be broken across lines (or pages).  This
could result in unnecessary page breaks in code
(c.f.~p.~\pageref{sec:pagebreaking}).  [[\let\\maybehbox=\mbox]] to
\stylehook
avoid breaking them
(or to make them work in math mode); this is done in code chunks, but could be done
in general.
<<kernel>>=
\def\LA{\begingroup\maybehbox\bgroup\setupmodname\It$\langle$}
\def\RA{\/$\rangle$\egroup\endgroup}
\def\code{\leavevmode\begingroup\setupcode\newlines}
\def\edoc{\endgroup}
\let\maybehbox\relax
@ %def \LA \RA \maybehbox

[[\equivbox]] and [[\plusequivbox]] are used to set the
``\unhcopy\equivbox''
and ``\unhcopy\plusequivbox'' that open a chunk definition or its
continuation.
{\tt noweave} brackets definitions of chunk names with [[\moddef]] and
either [[\endmoddef]] or [[\plusendmoddef]].
<<kernel>>=
\newbox\equivbox
\setbox\equivbox=\hbox{$\equiv$}
\newbox\plusequivbox
\setbox\plusequivbox=\hbox{$\mathord{+}\mathord{\equiv}$}
% \moddef can't have an argument because there might be \code...\edoc
\def\moddef{\leavevmode\kern-\codemargin\LA}
\def\endmoddef{\RA\ifmmode\equiv\else\unhcopy\equivbox\fi
               \nobreak\hfill\nobreak}
\def\plusendmoddef{\RA\ifmmode\mathord{+}\mathord{\equiv}\else\unhcopy\plusequivbox\fi
               \nobreak\hfill\nobreak}
@ %def \equivbox \plusequivbox \moddef \endmoddef \plusendmoddef
@
Within a code environment, margin tags might be used to mark sub-page
numbers in the margins, separated by [[\nwmarginglue]].\stylehook
The interaction with [[\moddef]] involves tricky kerning.
The tag itself is displayed using [[\nwthemargintag]]
<<noweb.sty>>=
\def\nwopt@nomargintag{\let\nwmargintag=\@gobble}
\def\nwopt@margintag{%
  \def\nwmargintag##1{\leavevmode\llap{##1\kern\nwmarginglue\kern\codemargin}}}
\def\nwopt@margintag{%
  \def\nwmargintag##1{\leavevmode\kern-\codemargin\nwthemargintag{##1}\kern\codemargin}}
\def\nwthemargintag#1{\llap{#1\kern\nwmarginglue}}
\nwopt@margintag
\newdimen\nwmarginglue
\nwmarginglue=0.3in
@ %def \nwmargintag margintag nomargintag \nwmarginglue
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B margintag
Put the sub-page number (tag) of each code-chunk definition in the
left margin. (Default)
.TP
.B nomargintag
Don't use margin tags.
@ \fi
[[\nwtagstyle]] determines the style in which tags are displayed.\stylehook
<<noweb.sty>>=
\def\nwtagstyle{\footnotesize\Rm}
@
<<kernel>>=
\def\chunklist{%
\errhelp{I changed \chunklist to \nowebchunks.  
I'll try to avoid such incompatible changes in the future.}%
\errmessage{Use \string\nowebchunks\space instead of \string\chunklist}}
\def\nowebchunks{\message{<Warning: You need noweave -x to use \string\nowebchunks>}}
\def\nowebindex{\message{<Warning: You need noweave -index to use \string\nowebindex>}}
@ %def \chunklist \nowebchunks \nowebindex
@ We have to be careful with font-changing in the presence of
different font-selection schemes.  In the \LaTeX{} New Font Selection
Scheme something like [[\it\tt]] will attempt to use an italic
typewriter font.  Thus we define new commands like [[\Tt]] which will
work with both the Plain and old and new \LaTeX{} schemes.  (Note that
NFSS will be standard in the next version of \LaTeX.)  A problem with
these definitions arises with NFSS: in math mode the won't work
unless the {\tt oldlfont} backwards-compatibility option is in effect.
For the moment, you can get round this by using [[\mbox]].

If you wanted code set in a different font, you could re-define
[[\Tt]].\stylehook{}  [\LaTeX2e actually behaves like OFSS, but the
extra [[\reset@font]] does no harm.]
<<kernel>>=
% here is support for the new-style (capitalized) font-changing commands
% thanks to Dave Love
\ifx\documentstyle\undefined
  \let\Rm=\rm \let\It=\it \let\Tt=\tt       % plain
\else\ifx\selectfont\undefined
  \let\Rm=\rm \let\It=\it \let\Tt=\tt       % LaTeX OFSS
\else                                       % LaTeX NFSS
  \def\Rm{\reset@font\rm}
  \def\It{\reset@font\it}
  \def\Tt{\reset@font\tt}
  \def\Bf{\reset@font\bf}
\fi\fi
\ifx\reset@font\undefined \let\reset@font=\relax \fi
@ %def \Rm \Tt \It \Bf
@
\clearpage
\section{The {\tt noweb} document-style option for {\LaTeX}}
\label{section:sty}
{\LaTeX} support begins with the kernel shown above.
<<noweb.sty>>=
<<kernel>>
@
\subsection{Support for noweb options}
<<noweb.sty>>=
\def\noweboptions#1{%
  \def\@nwoptionlist{#1}%
  \@for\@nwoption:=\@nwoptionlist\do{%
    \@ifundefined{nwopt@\@nwoption}{%
        \@latexerr{There is no such noweb option as '\@nwoption'}\@eha}{%
        \csname nwopt@\@nwoption\endcsname}}}
@ %def \noweboptions
\subsection{Adjusting placement of code on the page}
{\LaTeX} requires a larger [[\codehsize]] because 
code is indented by [[\codemargin]].\stylehook
<<noweb.sty>>=
\codemargin=10pt
%\setlength{\codemargin}{\parindent}
\advance\codehsize by \codemargin       % make room for indentation of code
\advance\nwdefspace by \codemargin	% and fix adjustment for def/use
@
[[\noweboptions{shift}]] is used to shift the whole page left to make room for
the wide code lines.
It may be emitted by {\tt noweave -shift}, or it might be given by a user.
<<noweb.sty>>=
\def\nwopt@shift{%
  \dimen@=-0.8in
  \if@twoside                 % Values for two-sided printing:
     \advance\evensidemargin by \dimen@
  \else                       % Values for one-sided printing:
     \advance\evensidemargin by \dimen@
     \advance\oddsidemargin by \dimen@
  \fi
%  \advance \marginparwidth -\dimen@
}
\let\nwopt@noshift\@empty
@ %def shift noshift

\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B shift
Shift text to the left so that long code lines won't extend
off the right-hand side of the page.
@ \fi

\subsection{Page-breaking strategy}\label{sec:pagebreaking}

We want to insert penalties aiming for:
\begin{enumerate}
\item 
No page breaks in the middle of a code chunk unless necessary to avoid
an overfull vbox;
\item 
Documentation immediately preceding a code chunk should appear on
the same page as that code chunk unless doing so would violate rule 1.
\end{enumerate}
[[\filbreak]] is useful for this sort of thing (see {\em The \TeX
  book\/}) and is used to encourage breaks at the right places between
chunks.  Appropriate penalties are inserted elsewhere, between code
lines in particular.

\subsection{Environments for setting code}

[[\nwbegincode]] and [[\nwendcode]] are used by {\tt noweave} to bracket
code chunks.
The [[webcode]] environment is intended for users who want to paste
{\tt noweave} output into papers.

The definition of [[\nwbegincode]] is based on the verbatim
implementation in {\tt verbatim.sty}, which will, presumably be in the
next version of \LaTeX\@.  One thing it does differently, apart from
the catcode changes is setting [[\linewidth]]; this will avoid some
overfull hboxen when the code lines are too long, but the lines won't
be broken anyhow (even within chunk names because of the
[[\maybehbox]] definition).
<<noweb.sty>>=
\def\nwbegincode#1{%
  \begingroup
  <<[[\nwbegincode]] separation and penalties>>
  \@begincode }
\def\nwendcode{\endtrivlist \endgroup } %\filbreak} changed by Kurt: 5.5.95 
% keeps code on 1 page

\newenvironment{webcode}{%\topsep \buchcodetopsep
  \@begincode
}{%
  \endtrivlist}
@ %def \nwbegincode \nwendcode webcode
@ This is just common code between [[\nwbegincode]] and [[webcode]].
<<noweb.sty>>=
\def\@begincode{%
  <<[[\trivlist]] clich\'e (\`a la {\Tt verbatim})>>
  \linewidth\codehsize
  <<[[\obeylines]] setup>>
  <<zap ligatures, fix spaces>>
  \nowebsize \setupcode
  \let\maybehbox\mbox }
@ %def \@begincode
@ \iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B smallcode
Set code in 
.I LaTeX
.B "\\\\small"
font instead of 
.B "\\\\normalsize."
@ \fi
@ [[\nowebsize]] governs the size at which code is set; users who want
to minimize code can [[\let\nowebsize=\small]].  
Slitex users should try
\begin{quote}
[[\def\nowebsize{\normalsize\baselineskip=20pt \parskip=5pt }]]
\end{quote}
to avoid code lines that are too far apart.
[[\nwcodetopsep]] is
the glue placed before code chunks.\stylehook
<<noweb.sty>>=
  \newskip\nwcodetopsep \nwcodetopsep = 3pt plus 1.2pt minus 1pt
  %\newskip\buchcodetopsep \buchcodetopsep = 10ex plus 1.2pt minus 1pt
  \let\nowebsize=\normalsize
  \def\nwopt@smallcode{\let\nowebsize=\small}
@ %def  \nwcodetopsep \nowebsize smallcode
@ Maybe the penalties ought to be parameters\dots
<<[[\nwbegincode]] separation and penalties>>=
  \topsep \nwcodetopsep
  \@beginparpenalty \@highpenalty
  \@endparpenalty -\@highpenalty
@ 
The [[\trivlist]] clich\'e isn't quite a clich\'e because we adjust
[[\leftskip]] for indentation by [[\codemargin]] and adjust
[[\rightskip]] to allow lines up to [[\codehsize]] long without
overfull boxen
($\mbox{[[\codehsize]]}=\mbox{[[\hsize]]}+\mbox{[[\rightskip]]}$).
Note that [[\hsize]] isn't altered.
<<[[\trivlist]] clich\'e (\`a la {\Tt verbatim})>>=
  \trivlist \item[]%
  \leftskip\@totalleftmargin \advance\leftskip\codemargin
  \rightskip\hsize \advance\rightskip -\codehsize
  \parskip\z@ \parindent\z@ \parfillskip\@flushglue
@ The penalty inserted between verbatim lines would normally be
[[\interlinepenalty]], but we want to prohibit breaks there.
@
Note the bug lurking somewhere in this code, as reported by Steven Ooms:
\begin{quote}
I have some lay-out
problems in the documentation chunks.  When using the (La)TeX commands
[[\hline]] or [[\vtop]] the right margin is always extended far beyond the page
margin after the first code chunk has been typeset.  I'm still looking for
the exact cause of it, but to me it seems that LaTeX supposes for those
commands that the line width for the documentation chunk is as large as that
for code chunks, which isn't true in reality.
\end{quote}
@
<<[[\obeylines]] setup>>=
  \@@par
  \def\par{\leavevmode\null \@@par \penalty\nwcodepenalty}%
  \obeylines
@ [[\nwcodepenalty]] is the penalty for breaking between lines in a
code chunk.  If you set it to 10000, code will never be broken across
pages.\stylehook{}  I guess this should be settable in [[\noweboptions]].

Kurt: The next line is irrelevant for Lweb.sty. In emptyline I set
nocodepenalty to an appropriate value at the end of each line of code.

<<noweb.sty>>=
\newcount\nwcodepenalty  \nwcodepenalty=0 %\@highpenalty
@ %def \nwcodepenalty
The cursing chunk accounts for the addition of a mess of characters
to those reset by [[\@noligs]] in \LaTeX2e.
<<zap ligatures, fix spaces>>=
  \@noligs <<make all those damn active characters ``other''>>
  \setupcode \frenchspacing \@vobeyspaces
@
We can't make [[`]] ``other,'' because then we'll get ligatures.
(Why Don put these ligatures in the [[\tt]] font I wish I knew.)
But we'll step on all the others.
<<make all those damn active characters ``other''>>=
  \ifx\verbatim@nolig@list\undefined\else
    \let\do=\nw@makeother \verbatim@nolig@list \do@noligs\`
  \fi
<<noweb.sty>>=
\def\nw@makeother#1{\catcode`#1=12 }
@
{\tt noweave} uses [[\nwbegindocs{nnn}]] and [[\nwenddocs]] to bracket
documentation chunks.
If a documentation chunk does not continue the current paragraph, 
{\tt noweave} inserts [[\nwdocspar]], which uses
[[\filbreak]] in an attempt to keep the documentation chunk on the
same page as the code chunk that follows it.  (The code chunk will
have another [[\filbreak]] after it---see [[\nwbegincode]].)
[[\nwbegindocs]] doesn't start a
new paragraph if the previous chunk didn't end one, i.e.\ didn't enter
vmode; if it does start a new one, it's only indented by the use of
[[\nwdocspar]].

Kurt: I want a more flexible rule to generate page breaks and therefore
remove the filbreak here and at the end of code sections (I never understood
anyhow why Norman Ramsey issues two filbreaks so close together. I replace the
filbreak by $\backslash$par.
<<noweb.sty>>=
\def\nwbegindocs#1{\ifvmode\noindent\fi}
\let\nwenddocs=\relax
\let\nwdocspar=\par%\filbreak  changed by Kurt, 5.5.95
@ %def \nwbegindocs \nwdocspar \nwenddocs
The page-breaking strategy implies ragged bottom pages, so we should
turn it on in general (this is relevant for the {\tt report} style):
<<noweb.sty>>=
\raggedbottom
<<nwmac.tex>>=
\def\nwdocspar{\par\semifilbreak}
@

{\tt noweave} doesn't bracket quoted code with [[\code]] and [[\edoc]] any more.
It probably should do something nifty, just to make {\TeX} hackers happy, but it doesn't.
<<noweb.sty>>=
\def\code{\leavevmode\begingroup\setupcode\@vobeyspaces\obeylines}
\let\edoc=\endgroup
@
\subsection{The {\tt noweb} page style}
Headers contain file name, date, and page number.
{\tt noweave} emits [[\nwfilename{]]{\em name}[[}]] for each new file.
In the {\tt noweb} page style, new files cause page breaks;
otherwise they are ignored.
<<noweb.sty>>=
\newdimen\@original@textwidth
\def\ps@noweb{%
  \@original@textwidth=\textwidth
  \let\@mkboth\@gobbletwo
  \def\@oddfoot{}\def\@evenfoot{}%       No feet.
  \if@twoside         % If two-sided printing.
    \def\@evenhead{\hbox to \@original@textwidth{%
           \Rm \thepage\qquad{\Tt\leftmark}\hfil\today}}%        Left heading.
    \def\@oddhead{\hbox to \@original@textwidth{%
           \Rm \today\hfil{\Tt\leftmark}\qquad\thepage}}% Right heading.
  \else               % If one-sided printing.
    \def\@oddhead{\hbox to \@original@textwidth{%
           \Rm \today\hfil{\Tt\leftmark}\qquad\thepage}}% Right heading.
    \let\@evenhead\@oddhead
  \fi
  \let\chaptermark\@gobble
  \let\sectionmark\@gobble
  \let\subsectionmark\@gobble
  \let\subsubsectionmark\@gobble
  \let\paragraphmark\@gobble
  \let\subparagraphmark\@gobble
  \def\nwfilename{\begingroup\let\do\@makeother\dospecials
                \catcode`\{=1 \catcode`\}=2 \nw@filename}
  \def\nw@filename##1{\endgroup\markboth{##1}{##1}\let\nw@filename=\nw@laterfilename}%
}
\def\nw@laterfilename#1{\endgroup\clearpage \markboth{#1}{#1}}
\let\nwfilename=\@gobble
@ %def \@original@textwidth \ps@noweb \nwfilename
@
\subsection{Chunk cross-reference}
[[\nwalsodefined]], [[\nwused]], and [[\nwnotused]] are emitted by the {\tt
noweb} cross-referencers. (What arguments?)
If unused chunks are output chunks, a filter can slip in
[[\let\nwnotused\nwoutput]].
The style uses [[\nwcodecomment]] for all annotations that follow code
chunks.
Fiddling with it can change the appearance of the output.
Note that [[\nwcodecomment]] is used after [[\nwbegincode]], with
[[\obeylines]] in efect.  Since linebreaking can occur here, we need
to change the [[\interlinepenalty]].
A little vertical space ([[\nwcodecommentsep]]\stylehook) appears before the first
comment.

We firkled with [[\rightskip]] in [[\nwbegincode]] above; now we want to
reset it so that paragraphs are the normal width ([[\textwidth]],
possibly less [[\codemargin]]) and set ragged right.  This is done as
usuall by making [[\rightskip]] naturally zero but stretchable.
<<noweb.sty>>=
\def\nwcodecomment#1{\@@par\penalty\nwcodepenalty
    <<add [[\nwcodecommentsep]] if this is the first [[\nwcodecomment]]>>%
    \hspace{-\codemargin}{%
        \rightskip=0pt plus1in
        \interlinepenalty\nwcodepenalty
        \let\\\relax\footnotesize\Rm #1\@@par\penalty\nwcodepenalty}}
@ %def \nwcodecomment 
This stuff is used at the end of a chunk.
<<noweb.sty>>=
\def\@nwalsodefined#1{\nwcodecomment{This definition is continued \nwpageprep\ \@pagesl{#1}.}}
\def\@nwused#1{\nwcodecomment{This code is used \nwpageprep\ \@pagesl{#1}.}}
\def\@nwnotused#1{\nwcodecomment{Root chunk (not used in this document).}}
\def\nwoutput#1{\nwcodecomment{This code is written to file {\Tt \@stripstar#1*\stripped}.}}
\def\@stripstar#1*#2\stripped{#1}
@ %def \nwalsodefined \nwused \nwnotused \nwoutput
<<add [[\nwcodecommentsep]] if this is the first [[\nwcodecomment]]>>=
\if@firstnwcodecomment
  \vskip\nwcodecommentsep\penalty\nwcodepenalty\@firstnwcodecommentfalse
\fi
@
This stuff on the definition line.
Note the hooks\stylehook{} for pointer styles.
<<noweb.sty>>=
\newcommand{\nwprevdefptr}[1]{%
  \mbox{$\mathord{\triangleleft}\,\mathord{\mbox{\subpageref{#1}}}$}}
\newcommand{\nwnextdefptr}[1]{%
  \mbox{$\mathord{\mbox{\subpageref{#1}}}\,\mathord{\triangleright}$}}

\newcommand{\@nwprevnextdefs}[2]{%
  {\nwtagstyle
  \ifx\relax#1\else ~~\nwprevdefptr{#1}\fi
  \ifx\relax#2\else ~~\nwnextdefptr{#2}\fi}}
\newcommand{\@nwusesondefline}[1]{{\nwtagstyle~~(\@pagenumsl{#1})}}
\newcommand{\@nwstartdeflinemarkup}{\nobreak\hskip 1.5em plus 1fill\nobreak}
\newcommand{\@nwenddeflinemarkup}{\nobreak\hskip \nwdefspace minus\nwdefspace\nobreak}
@
And here are the options we use to choose one or the other.
<<noweb.sty>>=
\def\nwopt@longxref{%
  \let\nwalsodefined\@nwalsodefined
  \let\nwused\@nwused
  \let\nwnotused\@nwnotused
  \let\nwprevnextdefs\@gobbletwo
  \let\nwusesondefline\@gobble
  \let\nwstartdeflinemarkup\relax
  \let\nwenddeflinemarkup\relax
}
\def\nwopt@shortxref{%
  \let\nwalsodefined\@gobble
  \let\nwused\@gobble
  \let\nwnotused\@gobble
  \let\nwprevnextdefs\@nwprevnextdefs
  \let\nwusesondefline\@nwusesondefline
  \let\nwstartdeflinemarkup\@nwstartdeflinemarkup
  \let\nwenddeflinemarkup\@nwenddeflinemarkup
}
\nwopt@shortxref % to hell with backward compatibility!
@ \iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B longxref, shortxref
Use either long, Knuth-style chunk cross-reference, or short,
Hanson-style chunk cross-reference.
The former uses small paragraphs after the chunk;
the latter uses symbols on the definition line.
Defaults to 
.B shortxref.
@ \fi
<<noweb.sty>>=
\newskip\nwcodecommentsep \nwcodecommentsep=3pt plus 1pt minus 1pt
\newif\if@firstnwcodecomment\@firstnwcodecommenttrue
@
\subsection{Page ranges}
The goal is to combine sub-page numbers in a way that makes sense.
Multiple sub-pages of one page become that page, and individual
pages are combined into ranges.
(A range may be only one page.)
<<noweb.sty>>=
\newcount\@nwlopage\newcount\@nwhipage  % range lo..hi-1
\newcount\@nwlosub              % subpage of lo
\newcount\@nwhisub              % subpage of hi
\def\@nwfirstpage#1#2{% subpage page
  \@nwlopage=#2 \@nwlosub=#1
  \advance\@nwpagecount by \@ne
  <<$\mbox{[[\@nwhipage]]} := \mbox{[[\@nwlopage]]}+1$>>}
\def\@nwnextpage#1#2{% subpage page
  \ifnum\@nwhipage=#2 
    \advance\@nwhipage by \@ne \advance\@nwpagecount by \@ne \@nwhisub=#1 \else
  \ifnum#2<\@nwlopage <<new range starting with [[#2]]>>\else
  \ifnum#2>\@nwhipage <<new range starting with [[#2]]>>\else
    \@nwlosub=0 \@nwhisub=0
  \fi\fi\fi
  }
<<new range starting with [[#2]]>>=
<<add range to range list>>\@nwfirstpage{#1}{#2}
<<$\mbox{[[\@nwhipage]]} := \mbox{[[\@nwlopage]]}+1$>>=
\@nwhipage=\@nwlopage\advance\@nwhipage by \@ne 
<<add range to range list>>=
<<set [[\@tempa]] to page range(s), marked with [[\\]]>>%
\edef\@tempa{\noexpand\nwix@cons\noexpand\nw@pages{\@tempa}}\@tempa
<<set [[\@tempa]] to page range(s), marked with [[\\]]>>=
\advance\@nwhipage by \m@ne
\ifnum\@nwhipage=\@nwlopage
     \edef\@tempa{\noexpand\noexpand\noexpand\\%
                       {\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}}%
\else
  \count@=\@nwhipage \advance\count@ by \m@ne
  \ifnum\count@=\@nwlopage % consecutive pages
      \edef\@tempa{\noexpand\noexpand\noexpand\\%
                       {\nwthepagenum{\number\@nwlosub}{\number\@nwlopage}}%
                    \noexpand\noexpand\noexpand\\%
                       {\nwthepagenum{\number\@nwhisub}{\number\@nwhipage}}}%
  \else <<use rules from Chicago style manual>>%
  \fi
\fi
<<use rules from Chicago style manual>>=
\ifnum\@nwlopage<110 <<normal range>>\else
  \count@=\@nwlopage \divide\count@ by 100 \multiply\count@ by 100
  \ifnum\count@=\@nwlopage <<normal range>>\else
    \count@=\@nwlopage \divide\count@ by 100
    \@nwpagetemp=\@nwhipage \divide\@nwpagetemp by 100
    \ifnum\count@=\@nwpagetemp %  lo--least 2 digits of hi
      \multiply\@nwpagetemp by 100
      \advance \@nwhipage by -\@nwpagetemp
      <<normal range>>%
    \else <<normal range>>%
    \fi
  \fi
\fi
<<normal range>>=  
\edef\@tempa{\noexpand\noexpand\noexpand\\{\number\@nwlopage--\number\@nwhipage}}
<<noweb.sty>>=
\newcount\@nwpagetemp
@
The sequence [[\@pagesl]] makes a range of pages from a list of labels.
[[\subpages]] works from a list of [[{{subpage}{page}}]].
<<noweb.sty>>=
\newcount\@nwpagecount
\def\@nwfirstpagel#1{% label
  \@ifundefined{r@#1}{<<warn of undefined reference to [[#1]] and add page ??>>}{%
    \edef\@tempa{\noexpand\@nwfirstpage\subpagepair{#1}}\@tempa}}
\def\@nwnextpagel#1{% label
  \@ifundefined{r@#1}{<<warn of undefined reference to [[#1]] and add page ??>>}{%
    \edef\@tempa{\noexpand\@nwnextpage\subpagepair{#1}}\@tempa}}
\def\@pagesl#1{%  list of labels
  \gdef\nw@pages{}\@nwpagecount=0
  \def\\##1{\@nwfirstpagel{##1}\let\\=\@nwnextpagel}#1%
  <<add range to range list>>\let\\=\relax
  \nwpageword\ifnum\@nwpagecount=1 \else s\fi~\commafy{\nw@pages}}
\def\@pagenumsl#1{%  list of labels -- doesn't include word `pages', commas, or `and'
  \gdef\nw@pages{}\@nwpagecount=0
  \def\\##1{\@nwfirstpagel{##1}\let\\=\@nwnextpagel}#1%
  <<add range to range list>>\def\\{\let\\=~}\nw@pages}
\def\subpages#1{% list of {{subpage}{page}}
  \gdef\nw@pages{}\@nwpagecount=0
  \def\\##1{\edef\@tempa{\noexpand\@nwfirstpage##1}\@tempa
            \def\\####1{\edef\@tempa{\noexpand\@nwnextpage####1}\@tempa}}#1%
  <<add range to range list>>\let\\=\relax
  \nwpageword\ifnum\@nwpagecount=1 \else s\fi~\commafy{\nw@pages}}
\def\@nwaddrange{<<add range to range list>>}
@
[[\nwpageword]] and [[\nwpageprep]] let you change the wording of the cross-reference 
information.
<<noweb.sty>>=
\def\nwpageword{chunk}	% was page
\def\nwpageprep{in}	% was on
<<warn of undefined reference to [[#1]] and add page ??>>=
<<warn of undefined reference to [[#1]]>>%
\nwix@cons\nw@pages{\\{\bf ??}}
@
\subsection{Sub-page references}
This is the wonderful code that Dave Love provided to make page
references like 7a, 7b, and so on.

This code
provides a mechanism for defining `page
sub-references' using [[\sublabel{foo}]] referenced with
[[\subpageref{foo}]].  Sub-references will be numbered like these real
examples: \subpageref{ref:foo}, \subpageref{ref:bar},
\subpageref{ref:baz}\sublabel{ref:foo}\sublabel{ref:bar}\sublabel{ref:baz}
etc.\ unless there is only one on the page, in which case the letter
will be dropped like this: \subpageref{ref:fred}.

To be able to use [[\subpageref]] we must define the label with
[[\sublabel]], used like label.  (Using
[[\ref]] with a label defined by [[\sublabel]] will
produce the sub-reference number, by the way, and [[\pageref]]
works as expected.)  Note that
[[\subpageref]] is robust and [[\ref]] and [[\pageref]] are redefined to be
robust also, as they will be in future \LaTeX{} releases.
Incidentally, these expand to the relevant text plus [[\null]]---you
might want to strip this off, e.g.\ for sorting lists.


There are various ways we could attack this task (which is made
non-trivial by the well-known asynchrony of (La)\TeX's output
routine), but
they all must depend on hacks in the [[.aux]] file or a similar one.
Joachim Schrod's [[fnpag.sty]] does the same sort of thing differently
to this \LaTeX-specific approach.  See [[latex.tex]] for enlightenment
on the cross-referencing mechanism and the \LaTeX{} internals used
below.  [DL: The internals change in \LaTeX2e compared with
\LaTeX~2.09.  The code here still works, though.]

@
The [[\subpageref]] macro first does a normal [[\pageref]].  If the
reference is actually defined, it then goes on to check whether the
control sequence [[2on]]\LA{}{page referenced}\RA{} is defined and sets the
[[\ref]] value to get [[a]] etc.\ if so.  The magic, of course, is in
defining the [[2on]] bit appropriately.
<<noweb.sty>>=
\newcommand{\subpageref}[1]{%
  \@ifundefined{r@#1}%
    {\pageref{#1}}%
    {\@ifundefined{2on\@pageref{#1}}%
      {\pageref{#1}}%
      {\expandafter\expandafter\expandafter\nwthepagenum\csname r@#1\endcsname}}}
@ %def \subpageref
[[\subpagepair]] produces a [[{subpage}{page}]] pair.
<<noweb.sty>>=
\newcommand{\subpagepair}[1]{%  % produces {subpage}{page}
  \@ifundefined{r@#1}%
    {{0}{0}}%
    {\@ifundefined{2on\@pageref{#1}}%
      {{0}{\expandafter\expandafter\expandafter\@cdr\csname r@#1\endcsname\@nil}}%
      {\@nameuse{r@#1}}}}
@
[[\@pageref]] is like [[\pageref]], but it expands to [[\relax]] without a warning
if the reference is undefined.
<<noweb.sty>>=
\def\@pageref#1{\expandafter\expandafter\expandafter
                \@cdr\csname r@#1\endcsname\@nil}
@ %def \@pageref
@
[[\sublabel]] is like the [[\label]] command, except that it writes
[[\newsublabel]] onto the [[.aux]] file rather than [[\newlabel]].
<<noweb.sty>>=
\newcommand{\sublabel}[1]{%
  \@bsphack\if@filesw {\let\thepage\relax
   \def\protect{\noexpand\noexpand\noexpand}%
   \edef\@tempa{\write\@auxout{\string
      \newsublabel{#1}{{}{\thepage}}}}%
   \expandafter}\@tempa
   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
@ %def \sublabel
[[\nosublabel]] creates a label with a sub-page part of~0.
<<noweb.sty>>=
\newcommand{\nosublabel}[1]{%
  \@bsphack\if@filesw {\let\thepage\relax
   \def\protect{\noexpand\noexpand\noexpand}%
   \edef\@tempa{\write\@auxout{\string
      \newlabel{#1}{{0}{\thepage}}}}%
   \expandafter}\@tempa
   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
@ %def \sublabel
@
[[\newsublabel]] is the macro that does the important work.  It is called with the
same sort of arguments as [[\newlabel]]: the first argument is the
label name and the second is [[{]]\LA ref value[[}{]]page number\RA[[}]].
(Note that the only definition here which needs to be
global is the one which is, and that [[\global]] is redefined by
[[\enddocument]], which will bite you if you use it\dots)
<<noweb.sty>>=
<<definition of [[\newsublabel]]>>
@
First we extract the page number into [[\this@page]].
<<definition of [[\newsublabel]]>>=
\newcommand{\newsublabel}[2]{%
  \edef\this@page{\@cdr#2\@nil}%
@ %def \newsublabel
@
Then we see whether it's changed from the value of [[\last@page]]
which was stashed away by the last [[\newsublabel]] (or is [[\relax]] if
this is the first one).  If the page has changed, we reset the
counter [[\sub@page]] telling us how many sub-labels there have been
on the page.
<<definition of [[\newsublabel]]>>=
  \ifx\this@page\last@page\else
    \sub@page=\z@
  \fi
  \edef\last@page{\this@page}
  \advance\sub@page by \@ne
@
If we've had at least two on the page, we define the 
[[2on]]\LA{}{page no.}\RA{} macro to indicate the fact.
<<definition of [[\newsublabel]]>>=
  \ifnum\sub@page=\tw@
    \global\@namedef{2on\this@page}{}%
  \fi
@
Then we write a normal [[\newlabel]] with the sub-reference as the
normal reference value in the second argument.
<<definition of [[\newsublabel]]>>=
  \edef\@tempa{\noexpand\newlabel{#1}%
    {{\number\sub@page}{\this@page}}}%
  \@tempa}
@
We need to define these.
<<noweb.sty>>=
\def\last@page{\relax}
\newcount\sub@page
@ %def \last@page \sub@page
@
We use Rainer's new expandable definitions of [[\ref]] and
[[\pageref]] to minimise the risk of nasty surprises.
<<noweb.sty>>=
% RmS 92/08/14: made \ref and \pageref robust
\def\ref#1{\@ifundefined{r@#1}{{\bf ??}<<warn of undefined reference to [[#1]]>>}%
    {\expandafter\expandafter\expandafter
     \@car\csname r@#1\endcsname\@nil\null}}
\def\pageref#1{\@ifundefined{r@#1}{{\bf ??}<<warn of undefined reference to [[#1]]>>}%
     {\expandafter\expandafter\expandafter
      \@cdr\csname r@#1\endcsname\@nil\null}}
\def\@refpair#1{\@ifundefined{r@#1}{{0}{0}<<warn of undefined reference to [[#1]]>>}%
    {\@nameuse{r@#1}}}
<<warn of undefined reference to [[#1]]>>=
\@warning{Reference `#1' on page \thepage \space undefined}
@ %def \ref \pageref
@

Here a a couple of hooks for formatting sub-page numbers,
which can be alphbetic, numeric, or omitted.\stylehook
<<noweb.sty>>=
\def\@alphasubpagenum#1#2{#2\ifnum#1=0 \else\@alph{#1}\fi}
\def\@nosubpagenum#1#2{#2}
\def\@numsubpagenum#1#2{#2\ifnum#1=0 \else.\@arabic{#1}\fi}
\def\nwopt@nosubpage{\let\nwthepagenum=\@nosubpagenum\nwopt@nomargintag}
\def\nwopt@numsubpage{\let\nwthepagenum=\@numsubpagenum}
\def\nwopt@alphasubpage{\let\nwthepagenum=\@alphasubpagenum}
\nwopt@alphasubpage
@ %def \nwthepagenum nosubpage numsubpage alphasubpage
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B alphasubpage, numsubpage, nosubpage
Number chunks by the number of the page on which they appear,
followed by an alphabetic (numeric, not used) ``sub-page'' indicator.
Defaults to 
.B alphasubpage.
.B nosubpage
implies
.B nomargintag.
@ \fi
@

\subsection{{\tt WEB}-like chunk numbering}
Here's a righteous hack: we get the effect of WEB-like chunk numbers
just by redefining [[\sublabel]] to use a counter instead of the current page number.
Since the numbers are all distinct, no sub-page number is ever used.
<<noweb.sty>>=
\newcount\nw@chunkcount
\nw@chunkcount=\@ne
\newcommand{\weblabel}[1]{%
  \@bsphack\if@filesw {\let\thepage\relax
   \def\protect{\noexpand\noexpand\noexpand}%
   \edef\@tempa{\write\@auxout{\string
      \newsublabel{#1}{{}{\number\nw@chunkcount}}}}%
   \expandafter}\@tempa
   \global\advance\nw@chunkcount by \@ne
   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
\def\nwopt@webnumbering{\let\sublabel=\weblabel\def\nwpageword{chunk}\def\nwpageprep{in}}
@ %def \weblabel webnumbering
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B webnumbering
Number chunks consecutively, in 
.I WEB
style, instead of using sub-page numbers.
@ \fi
@
\subsection{Indexing (identifier cross-reference) support}

\subsubsection{Tracking definitions and uses}
All index definitions and uses are associated with 
a label defined with [[\sublabel]] or [[\nosublabel]].
Either the label is the [[\sublabel]] of the code chunk in which the definition or use
appears, or it is a [[\nosublabel]] appearing in the middle of a
documentation chunk.
<<noweb.sty>>=
% \nwindexdefn{printable name}{identifying label}{label of chunk}
% \nwindexuse{printable name}{identifying label}{label of chunk}

\def\nwindexdefn#1#2#3{\@auxix{\protect\nwixd}{#2}{#3}}
\def\nwindexuse#1#2#3{\@auxix{\protect\nwixu}{#2}{#3}}

\def\@auxix#1#2#3{% {marker}{id label}{subpage label}
   \@bsphack\if@filesw {\let\nwixd\relax\let\nwixu\relax
   \def\protect{\noexpand\noexpand\noexpand}%
   \edef\@tempa{\write\@auxout{\string\nwixadd{#1}{#2}{#3}}}%
   \expandafter}\@tempa
   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
@ %def \nwindexdefn \nwindexuse \@auxix
<<noweb.sty>>=
% \nwixadd{marker}{idlabel}{subpage label}
\def\nwixadd#1#2#3{%
  \@ifundefined{nwixl@#2}%
    {\global\@namedef{nwixl@#2}{#1{#3}}}%
    {\expandafter\nwix@cons\csname nwixl@#2\endcsname{#1{#3}}}}
@ %def \nwixadd
@
\subsubsection{Writing lists with commas and ``and''}
You get one of
\begin{itemize}
\item ``$a$''
\item ``$a$ and $b$''
\item ``$a$, $\ldots$, $b$, and $c$''
\end{itemize}
Plus [[\\]] is applied to each element of the list.
<<noweb.sty>>=
\newcount\@commacount
\def\commafy#1{%
  {\nwix@listcount{#1}\@commacount=\nwix@counter
   \let\@comma@each=\\%
   \ifcase\@commacount\let\\=\@comma@each\or\let\\=\@comma@each\or
     \def\\{\def\\{ and \@comma@each}\@comma@each}\else
     \def\\{\def\\{, %
                   \advance\@commacount by \m@ne
                   \ifnum\@commacount=1 and~\fi\@comma@each}\@comma@each}\fi
   #1}}
@ %def \@commacount \commafy

\subsubsection{New, improved index code}
There are two kinds of lists.
One kind is a generic list in which elements are preceded by [[\\]].
If the elements are index elements, they are {\em[[{]]printable
identifier[[}{]]label[[}]]} pairs.
The other kind is a list of sub-page labels, in which each 
element is preceded by either [[\nwixd]] or [[\nwixu]].
<<noweb.sty>>=
\def\nwix@cons#1#2{% {list}{\marker{element}}
  {\toks0=\expandafter{#1}\def\@tempa{#2}\toks2=\expandafter{\@tempa}%
   \xdef#1{\the\toks0 \the\toks2 }}}
@ %def \nwix@cons
The reference list for an identifier labelled {\em id}
is always called [[\nwixl@]]{\em id}.
Most applications will work with reference lists by applying [[\\]]
either to the defs or to the uses.
<<noweb.sty>>=
\def\nwix@uses#1{% {label}
  \def\nwixu{\\}\let\nwixd\@gobble\@nameuse{nwixl@#1}}
\def\nwix@defs#1{% {label}
  \def\nwixd{\\}\let\nwixu\@gobble\@nameuse{nwixl@#1}}
@ %def \nwix@uses \nwix@defs

Some applications count uses to see whether there is any need to
display information.
<<noweb.sty>>=
\newcount\nwix@counter
\def\nwix@listcount#1{% {list with \\}
  {\count@=0
   \def\\##1{\advance\count@ by \@ne }%
   #1\global\nwix@counter=\count@ }}
\def\nwix@usecount#1{\nwix@listcount{\nwix@uses{#1}}}
\def\nwix@defcount#1{\nwix@listcount{\nwix@defs{#1}}}
@ %def \nwix@listcount \nwix@usecount \nwix@defcount
@
\subsubsection{Supporting a mini-index at the end of each chunk}
When displaying identifiers used, show the identifier and its
definitions.
<<noweb.sty>>=
\def\nwix@id@defs#1{% index pair
  {{\Tt \@car#1\@nil}%
  \def\\##1{~\subpageref{##1}}\nwix@defs{\@cdr#1\@nil}}}
\def\nwidentuses#1{% list of index pairs
  \nwcodecomment{Uses \let\\=\nwix@id@defs\commafy{#1}.}}
@ %def \nwidentuses \nwix@id@defs
The definitions section is a bit more complex, because it is omitted
if none of the identifiers defined is ever used.
<<noweb.sty>>=
\def\nwix@totaluses#1{% list of index pairs
  {\count@=0
   \def\\##1{\nwix@usecount{\@cdr##1\@nil}\advance\count@ by\nwix@counter}%
   #1\global\nwix@counter\count@ }}
\def\nwix@id@uses#1#2{% {ident}{label}
  \nwix@usecount{#2}\ifnum\nwix@counter>0
    {\advance\leftskip by \codemargin
     \nwcodecomment{{\Tt #1}, used \nwpageprep\ \@pagesl{\nwix@uses{#2}}.}}%
  \else
    \ifnw@hideunuseddefs\else
      {\advance\leftskip by \codemargin \nwcodecomment{{\Tt #1}, never used.}}%
    \fi
  \fi}
\def\nwidentdefs#1{% list of index pairs
  \ifnw@hideunuseddefs\nwix@totaluses{#1}\else\nwix@listcount{#1}\fi
  \ifnum\nwix@counter>0
    \nwcodecomment{Defines:}%
    {\def\\##1{\nwix@id@uses ##1}#1}%
  \fi}
<<noweb.sty>>=
\newif\ifnw@hideunuseddefs\nw@hideunuseddefsfalse
\def\nwopt@hideunuseddefs{\nw@hideunuseddefstrue}
@ 
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B hideunuseddefs
Omit defined but unused identifiers from
the local identifier cross-reference (Preston Briggs).
@ \fi
<<noweb.sty>>=
\def\nwopt@noidentxref{%
  \let\nwidentdefs\@gobble
  \let\nwidentuses\@gobble}
@ 
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B noidentxref
Omit the local identifier cross-reference which follows each code chunk.
@ \fi

\subsubsection{Support for chunk and identifier indices}
The index in the back shows absolutely all the pages.
<<noweb.sty>>=
\def\nw@underlinedefs{% {list with \nwixd, \nwixu}
  \let\\=\relax\def\nw@comma{, }
  \def\nwixd##1{\\\underline{\subpageref{##1}}\let\\\nw@comma}%
  \def\nwixu##1{\\\subpageref{##1}\let\\\nw@comma}}

\def\nw@indexline#1#2{%
   {\indent {\Tt #1}: \nw@underlinedefs\@nameuse{nwixl@#2}\par}}

\newenvironment{thenowebindex}{\parindent=-10pt \parskip=\z@ 
        \advance\leftskip by 10pt 
        \advance\rightskip by 0pt plus1in\par\@afterindenttrue
    \def\\##1{\nw@indexline##1}}{}
@
The information comes from the list [[nwisx@i]].
<<noweb.sty>>=
\def\nowebindex{%
  \@ifundefined{nwixs@i}%
     {\@warning{The \string\nowebindex\space is empty}}%
     {\begin{thenowebindex}\@nameuse{nwixs@i}\end{thenowebindex}}}
@
Here's a more efficient version for the external case:
<<noweb.sty>>=
\def\nowebindex@external{%
  {\let\nwixadds@c=\@gobble
   \def\nwixadds@i##1{\nw@indexline##1}%
   \def\nwixaddsx##1##2{\@nameuse{nwixadds@##1}{##2}}%
   \begin{thenowebindex}\@input{\jobname.nwi}\end{thenowebindex}}}
@ 
That list ([[nwisx@i]]) is created by calls to [[\nwixlogsorted{i}]].
<<noweb.sty>>=
\def\nwixlogsorted#1#2{% list data
   \@bsphack\if@filesw 
     \toks0={#2}\immediate\write\@auxout{\string\nwixadds{#1}{\the\toks0}}
   \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack}
@ 
[[nwixs@c]] and [[nwixs@i]] are sorted lists of chunks and identifiers, respectively.
<<noweb.sty>>=
\def\nwixadds#1#2{%
  \@ifundefined{nwixs@#1}%
    {\global\@namedef{nwixs@#1}{\\{#2}}}%
    {\expandafter\nwix@cons\csname nwixs@#1\endcsname{\\{#2}}}}
\let\nwixaddsx=\@gobbletwo
@
If an external index is used, we need a [[.nwi]] file,
[[\nwixadds]] is to be ignored, and we use [[\nwixaddsx]].
<<noweb.sty>>=
\def\nwopt@externalindex{%
  \ifx\nwixadds\@gobbletwo % already called
  \else
    \let\nwixaddsx=\nwixadds \let\nwixadds=\@gobbletwo
    \let\nowebindex=\nowebindex@external
    \let\nowebchunks=\nowebchunks@external
  \fi}
@ 
\iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B externalindex
Use an index generated with 
.I noindex(1)
(q.v.).
@ \fi
@
<<noweb.sty>>=
\def\nowebchunks{%
  \@ifundefined{nwixs@c}%
     {\@warning{The are no \string\nowebchunks}}%
     {\begin{thenowebchunks}\@nameuse{nwixs@c}\end{thenowebchunks}}}
\def\nowebchunks@external{%
  {\let\nwixadds@i=\@gobble
   \def\nwixadds@c##1{\nw@onechunk##1}%
   \def\nwixaddsx##1##2{\@nameuse{nwixadds@##1}{##2}}%
   \begin{thenowebchunks}\@input{\jobname.nwi}\end{thenowebchunks}}}
    \@namedef{r@nw@notdef}{{0}{(never defined)}}
<<noweb.sty>>=
\def\nw@chunkunderlinedefs{% {list of labels with \nwixd, \nwixu}
  \let\\=\relax\def\nw@comma{, }
  \def\nwixd##1{\\\underline{\subpageref{##1}}\let\\\nw@comma}%
  \def\nwixu##1{\\\subpageref{##1}\let\\\nw@comma}}
<<noweb.sty>>=
\def\nw@onechunk#1#2#3{% {name}{label of first definition}{list with \nwixd, \nwixu}
  \@ifundefined{r@#2}{}{%
    \indent\LA #1~{\nwtagstyle\subpageref{#2}}\RA 
    \if@nwlongchunks{~\nw@chunkunderlinedefs#3}\fi\par}}
<<noweb.sty>>=
\newenvironment{thenowebchunks}{\vskip3pt
  \parskip=\z@\parindent=-10pt \advance\leftskip by 10pt
  \advance\rightskip by 0pt plus10pt \@afterindenttrue
  \def\\##1{\nw@onechunk##1}}{}
<<noweb.sty>>=
\newif\if@nwlongchunks
\@nwlongchunksfalse
\let\nwopt@longchunks\@nwlongchunkstrue
@ \iffalse
<<man page: [[\noweboptions]]>>=
.TP
.B longchunks
When expanding 
.B "\\\\nowebchunks,"
show page numbers of definitions and uses of each chunk.
@ \fi

@
\clearpage
\section{The {\tt nwmac} macros for use with plain {\TeX}}

First we make [[@]] a letter so that we can use `private' macro names.
<<nwmac.tex>>=
\catcode`\@=11
<<nwmac.tex>>=
% scale cmbx10 instead of using cmbx12 because {\LaTeX} does, so fonts exist
\font\twlbf=cmbx10 scaled \magstep1
\font\frtbf=cmbx10 scaled \magstep2
% These fonts don't work with xdvi!

\advance\hoffset 0.5 true in
\advance\hsize -1.5 true in
\newdimen\textsize
\textsize=\hsize
\def\today{\ifcase\month\or
  January\or February\or March\or April\or May\or June\or
  July\or August\or September\or October\or November\or December\fi
  \space\number\day, \number\year}
@ %def \textsize \today
<<nwmac.tex>>=
\long\def\ifundefined#1#2#3{%
   \expandafter\ifx\csname#1\endcsname\relax
       #2%
   \else#3%
   \fi}

\ifundefined{myheadline}
    {\headline={\hbox to \textsize{\tentt\firstmark\hfil\tenrm\today\hbox
                to 4em{\hss\folio}}\hss}}
    {\expandafter\headline\expandafter{\myheadline}}

\ifundefined{myfootline}
    {\footline={\hfil}}
    {\expandafter\footline\expandafter{\myfootline}}
@ %def \ifundefined
<<nwmac.tex>>=
\def\semifilbreak{\vskip0pt plus1.5in\penalty-200\vskip0pt plus -1.5in}
\raggedbottom
@ %def \semifilbreak
<<nwmac.tex>>=
%
% \chapcenter macro to produce nice centered chapter titles
%
\def\chapcenter{\leftskip=0.5 true in plus 4em minus 0.5 true in
    \rightskip=\leftskip
    \parfillskip=0pt \spaceskip=.3333em \xspaceskip=.5em
    \pretolerance=9999 \tolerance=9999
    \hyphenpenalty=9999 \exhyphenpenalty=9999}
@ %def \chapcenter
<<nwmac.tex>>=
% \startsection{LEVEL}{INDENT}{BEFORESKIP}{AFTERSKIP}{STYLE}{HEADING}
%               #1     #2      #3          #4         #5     #6
%
%       LEVEL:          depth; e.g. part=0 chapter=1 sectino=2...
%       INDENT:         indentation of heading from left margin
%       BEFORESKIP:     skip before header
%       AFTERSKIP:      skip after header
%       STYLE:          style of heading; e.g.\bf
%       HEADING:        heading of the sectino
%
\def\startsection#1#2#3#4#5#6{\par\vskip#3 plus 2in
        \penalty-200\vskip 0pt plus -2in
    \noindent{\leftskip=#2 \rightskip=0.5true in plus 4em minus 0.5 true in
              \hyphenpenalty=9999 \exhyphenpenalty=9999
              #5#6\par}\vskip#4%
    {\def\code##1{[[}\def\edoc##1{]]}\message{[#6]}}
    \settocparms{#1}
    \def\themodtitle{#6}
%%%%    {\def\code{\string\code}\def\edoc{\string\edoc}%
    \edef\next{\noexpand\write\cont{\tocskip
        \tocline{\hskip\tocindent\tocstyle\relax\themodtitle}
                {\noexpand\the\pageno}}}\next % write to toc
    }%
}
@ %def \startsection
<<nwmac.tex>>=
\def\settocparms#1{
        \count@=#1
        \ifnum\count@<1
            \def\tocskip{\vskip3ptplus1in\penalty-100
                        \vskip0ptplus-1in}%
            \def\tocstyle{\bf}
            \def\tocindent{0pt}
        \else
            \def\tocskip{}
            \def\tocstyle{\rm}
            \dimen@=2em \advance\count@ by \m@ne \dimen@=\count@\dimen@
            \edef\tocindent{\the\dimen@}
        \fi
}
@ %def \settocparms
<<nwmac.tex>>=
\def\tocline#1#2{\line{{\ignorespaces#1}\leaders\hbox to .5em{.\hfil}\hfil
     \hbox to1.5em{\hss#2}}}
@ %def \tocline
<<nwmac.tex>>=
\def\section#1{\par \vskip3ex\noindent {\bf #1}\par\nobreak\vskip1ex\nobreak}
\def\chapter#1{\vfil\eject\startsection{0}{0pt}{6ex}{3ex}{\frtbf\chapcenter}{#1}}
\def\section#1{\startsection{1}{0pt}{4ex}{2ex}{\twlbf}{#1}}
\def\subsection#1{\startsection{2}{0pt}{2ex}{1ex}{\bf}{#1}}
\def\subsubsection#1{\startsection{3}{0pt}{1ex}{0.5ex}{\it}{#1}}
\def\paragraph#1{\startsection{4}{0pt}{1.5ex}{0ex}{\it}{#1}}

<<kernel>>

\def\nwfilename#1{\vfil\eject\mark{#1}}

\def\nwbegindocs#1{\filbreak}
\def\nwenddocs{\par}
\def\nwbegincode#1{\par\nobreak
  \begingroup\setupcode\newlines\parindent=0pt\parskip=0pt
  \let\oendmoddef=\endmoddef \let\oplusendmoddef=\plusendmoddef
  \def\endmoddef{\oendmoddef\par}\def\plusendmoddef{\oplusendmoddef\par}%
  \hsize=\codehsize\noindent\bchack}
\def\nwendcode{\endgroup}
{\catcode`\^^M=\active % make CR an active character
  \gdef\bchack#1^^M{\relax#1}%
}
@ %def \section \chapter \section \subsection \subsubsection \paragraph
@ %def \nwbegindocs \nwenddocs \nwbegincode \nwendcode \nwfilename
<<nwmac.tex>>=
\edef\contentsfile{\jobname.toc } % file that gets table of contents info
\def\readcontents{\expandafter\input \contentsfile}

\newwrite\cont
\openout\cont=\contentsfile
\write\cont{\string\catcode`\string\@=11}% a hack to make contents
@ %def \readcontents \cont
<<nwmac.tex>>=
                                 % take stuff in plain.tex
\def\bye{%
    \write\cont{}% ensure that the contents file isn't empty
    \closeout\cont
    \vfil\eject\pageno=-1 % new page causes contents to be really closed
    \topofcontents\readcontents\botofcontents
    \vfil\eject\end}
\def\topofcontents{\vfil\mark{{\bf Contents}}}
\def\botofcontents{}
@ %def \bye \topofcontents \botofcontents
<<nwmac.tex>>=
\let\em=\it
% used to produce an itemized (bulleted) list in plain {\TeX}
% such lists can be nested
% mostly useful with WEB

% Usage:
% \itemize
% \item First thing
% \item second thing
% \enditemize

\newcount\listlevel
\listlevel=0
\newdimen\itemwidth
\itemwidth=3em

\def\itemize{\begingroup\advance\listlevel by1
    \def\item{\par\noindent
         \raise2pt\llap{$\scriptstyle\bullet$\ }\ignorespaces}%
    \def\nameditem##1{\par\noindent
         \llap{\rlap{##1}\hskip\itemwidth}\ignorespaces}%
    \par\advance\leftskip by\itemwidth\advance\rightskip by0.5\itemwidth}
\def\enditemize{\par\endgroup\noindent\ignorespaces}

\let\begindocument=\relax
@ %def \listlevel \itemwidth \itemize \enditemize
Finally we make [[@]] `other' again.
<<nwmac.tex>>=
\catcode`\@=12
@
\section{Chunks} \nowebchunks
\twocolumn[\section{Index}]
\nowebindex*
@
\end{document}


