summaryrefslogtreecommitdiff
path: root/web/noweb/src/tex/support.nw.orig
diff options
context:
space:
mode:
Diffstat (limited to 'web/noweb/src/tex/support.nw.orig')
-rw-r--r--web/noweb/src/tex/support.nw.orig1301
1 files changed, 1301 insertions, 0 deletions
diff --git a/web/noweb/src/tex/support.nw.orig b/web/noweb/src/tex/support.nw.orig
new file mode 100644
index 0000000000..c706a0b4cb
--- /dev/null
+++ b/web/noweb/src/tex/support.nw.orig
@@ -0,0 +1,1301 @@
+% -*- mode: Noweb; noweb-code-mode: tex-mode -*-
+\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
+\advance\nwdefspace by -\hsize\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
+ \catcode`\"=\other % fixes problem with german.sty
+ \obeyspaces\Tt
+}
+\let\nwlbrace=\{
+\let\nwrbrace=\}
+@ %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.
+This hack doesn't properly restore [["]] for use in {\tt german.sty}.
+<<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
+ \let\{\nwlbrace
+ \let\}\nwrbrace
+ % bad news --- don't know what catcode to give "
+ \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
+\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} % keeps code on 1 page
+
+\newenvironment{webcode}{%
+ \@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
+ \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]].
+<<noweb.sty>>=
+\newcount\nwcodepenalty \nwcodepenalty=\@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]].
+<<noweb.sty>>=
+\def\nwbegindocs#1{\ifvmode\noindent\fi}
+\let\nwenddocs=\relax
+\let\nwdocspar=\filbreak
+@ %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.
+[[\subpageref]] also tries to include the right hyperstuff for xhdvi.
+<<noweb.sty>>=
+\newcommand{\subpageref}[1]{%
+ \nwhyperreference{#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]].
+For hyperreferencing, all labels must be hypertext
+anchors, for which we use [[\nwblindhyperanchor]].
+<<noweb.sty>>=
+\newcommand{\sublabel}[1]{%
+ \nwblindhyperanchor{#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
+
+@
+\subsection{support for hypertext with {\tt hyper.sty}}
+Initial support courtesy of Balasubramanian Narasimhan.
+<<noweb.sty>>=
+\newcommand\nwhyperreference[2]{%
+ \@ifundefined{hyperreference}%
+ {#2\global\let\nwhyperreference\@gobble}%
+ {\hyperreference{#1}{#2}\global\def\nwhyperreference\hyperreference}}
+\newcommand\nwblindhyperanchor[1]{%
+ \@ifundefined{blindhyperanchor}%
+ {\global\let\nwblindhyperanchor\@gobble}%
+ {\blindhyperanchor{#1}\global\def\nwblindhyperanchor\blindhyperanchor}}
+@
+\subsection{Support for hypertext translation to HTML}
+<<noweb.sty>>=
+\newcommand\nwanchorto{%
+ \begingroup\let\do\@makeother\dospecials
+ \catcode`\{=1 \catcode`\}=2 \nw@anchorto}
+\newcommand\nw@anchorto[1]{\def\nw@next{#1}\endgroup\nw@anchortofin}
+\newcommand\nw@anchortofin[1]{#1\footnote{See URL \texttt{\nw@next}.}}
+\let\nwanchorname\@gobble
+@
+\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}
+
+