\part Front and\\ Back Matter\label{FBM}\endpart


\chapter Front Matter\\(Table of Contents, List of Figures, Tables, etc.)
\label{FRONTMATTER}\endchapter
\runningchapter{Front Matter}

Now that we've covered all the formatting of the paper proper, we only have
to worry about the formatting of the *.toc* and *.tic* files for the front
matter, and the *.ndx* file for the index.

As we've  seen in section~\Sref{STYF}, the 
*\predocstyle* and *\postdocstyle* commands simply *\input* files with 
the extension *.stf* and *.stb*, respectively.  In the default style,
we say
**
\predocstyle{lamstex}
**
to *\input lamstex.stf*, and
**
\postdostyle{lamstex}
**
to *\input lamstex.stb*.  In this chapter we consider the file *lamstex.stf*,
while the next chapter considers *lamstex.stb*.   

As in section~\Sref{GENDEFS}, we will be using double horizontal lines
for code from these subsidiary files.

\section{{\tt lamstex.stf} preliminaries} The file
*lamstex.stf*, although it is only a
particular example of a front matter style file, nevertheless illustrates all
the main points we have to consider.

As usual, we begin with 
\CC**
\catcode`\@=11
**
Since we are going to  be introducing some *\newdimen*'s, we first
\CC**
\let\alloc@=\alloc@@
**
(compare page~\ref{NEWALLOC}).


\medskip

 In the default style, we will be setting entries like
\bigskip
\line{\qquad\bf 
Chapter 1. Introduction\leaders\hbox to10pt{\rm\hfil.\hfil}\hfil
 \kern10pt\hbox{\rm3}\qquad}
\bigskip
\noindent
using dot leaders.  This, of course, is merely a style decision, and some
modern style designers eschew dot leaders, on the grounds that blank space
will work just as well.  I suspect, however, that many such supposedly
aesthetic decisions were really influenced by the difficulty of handling dot
leaders correctly. In any case, the default style uses dot leaders, giving us
the opportunity to address the question of long entries, where we will need
to use something like
\bigskip
\line{\qquad\bf Chapter 1. This chapter has such a long title that it will
 be \hfil}
\line{\qquad\bf\setbox0\hbox{Chapter 1.}\hskip10pt\hskip\wd0
  necessary to split it into two parts\leaders\hbox
to10pt{\rm\hfil.\hfil}\hfil\kern10pt \rm3\qquad}
\bigskip

For the moment, we simply define our leaders,
\CC**
\def\dotleaders{\leaders\hbox to10pt{\rm\hfil.\hfil}\hfil}
**
We also want to define the formatting for page numbers. 
The *.toc* and *.tic* files contain lines like
**
\Page {3}{\arabic }{}{}
**
to handle the page number, the numbering style, and possible pre- and
post-page material.  The routine *\Page@#1#2#3#4* tells how these will
be combined when typeset:
\CC**
\def\Page@#1#2#3#4{\kern10pt\hbox{\rm#3#2{#1}#4}}
**
Thus, for example,
**
\Page {3}{\roman }{A-}{}
**
will be printed as `A-iii', with at least 10~points of space between the
leaders and the number.

\section{Setting an entry\label{SETENTRY}}
We begin with a test
**
\widerthanhsize@#1#2#3#4
**
to determine 
 whether
the material for an entry is longer than *\hsize*.
In the example given above, *#1* will be the `\hbox{\bf Chapter 1. }' part of
the heading,
 *#2* will be the title `{\bf This chapter \dots into two parts}', *#3* will
be  the *\dotleaders*, and *#4* will be the suitable `*\Page@...*'.

 Displayed formulas and other
such nonsense aren't allowed in heading levels, but captions, at any rate,
could have more than one paragraph of text; moreover, in the *.toc* file
 we might well want
to use *\newline* to force a short line when our entry is so long
that only one or
two of the dot leaders appear.
So we will use a test similar to 
the *\widerthanisland@* test of section~\Sref{FMTC}:
\CC**
\long\def\widerthanhsize@#1#2#3#4{%
 \test@true
 \setbox0=\vbox{\hsize=\maxdimen
  \rm\noindent@#1#2#3#4\par\setbox0=\lastbox}%
 \ifdim\wd0=0pt 
  \setbox0=\hbox{\rm#1#2#3#4}%
  \ifdim\wd0 > \hsize\else\test@false\fi
 \fi}
**
We use *\noindent@* instead of the more complicated *\noindent@@* here
because we will be setting *\everypar{}* while the table of contents is
being made.  (Actually, even the *\noindent@* is unnecessary, since we will
also be setting *\parindent=0pt*.)
Instead of  *\rm*, other style files
might need to insert something like *\tenpoint* (just
in case the user has, for example, added
 *\eightpoint* material at the beginning of the *.toc* file).


Then we  define the routine *\setentry@#1#2#3#4*,
 which sets the entry with parts *#1*, \dots, *#4* properly; when the
entry will have to be set on more than one line, we call the routine
*\longentry@*:
\CC**
\long\def\setentry@#1#2#3#4{%
 \widerthanhsize@{#1}{#2}{#3}{#4}%
 \iftest@
  \longentry@{#1}{#2}{#3}{#4}%  
 \else
  \hbox to\hsize{\rm\strut#1#2#3#4\strut}%
 \fi}
**
Notice that we added the *\strut*'s after the *\rm*; other styles
might have to specify something like *\tenpoint* instead of the *\rm*.

Because our lines have *\strut*'s, which already make the baselines *12pt*
apart, 
it is essential that we have
**
\lineskiplimit=0pt "8USELIMITPROB"8
**
while we are setting the table of contents,
so that additional *\lineskip* glue isn't inserted between lines
(compare page~\ref{LIMITPROB}). However, instead of making this assignment
now, we will make it later, within the definition of *\maketoc*.


For entries that are longer than one line,
the default style uses hanging indentation, so that
 lines after the first are indented by 10~points more than
the width of argument *#1*.  We will declare a \<dimen\> register
*\thehang@*
for the necessary amount of hanging indentation, which will be determined by
**
\setbox0=\hbox{#1}
\thehang@=\wd0 \advance\thehang@ by 10pt
**

 All lines before the last will be made shorter
than *\hsize*, so that they don't overlap the width of the page number.
The default style leaves an extra 20~points leeway, which we arrange with
**
\setbox0=\hbox{#4}
\advance\hsize by -\wd0 \advance\hsize by -20pt
 \hangafter 1 \hangindent=\thehang@
**
Now the idea is to set a *\vbox* that looks like
\medskip
\line{\qquad\bf Chapter 1. This chapter has such a long title that it will
 be necessary\hfil}
\line{\qquad\bf\setbox0\hbox{Chapter 1.}\hskip10pt\hskip\wd0
  to split it into two parts\hfil}
\medskip
\noindent
and then use *\lastbox* to extract the last line, to which we will finally
add the dot leaders and the page number:  
**
\long\def\longentry@#1#2#3#4{%
 \setbox0=\hbox{#1} \thehang@=\wd0 \advance\thehang@ by 10pt
 \setbox0=\hbox{#4}
 \setbox0=\vbox{\advance\hsize by -\wd0 
  \advance\hsize by -20pt
  \hangafter 1 \hangindent=\thehang@
  \rm\noindent@\strut\hbox{#1}#2\vphantom{#3#4}\strut}
 . . .
**
We  put *#1* inside an *\hbox* so that any glue within it will have only
its natural width, without any
 stretch or shrink; this is necessary in order to insure that our hanging
indentation will truly be the width of *#1* plus 10~points. 
The *\vphantom{#3#4}* is added so that the height and depth of the
last line of *\box0* won't
change when we add the dot leaders (*#3*) and the page number (*#4*).
As mentioned before, other styles might have to specify something like
*\tenpoint* rather than *\rm*; the *\strut* should come after that,
{\it and also after the\/} *\noindent@* (so that it doesn't start
a paragraph prematurely).

As with footnotes (section~\Sref{VF}), we will actually want to replace
the first *\strut* with
**
\vbox to\ht\strutbox{}
**
and the last *\strut* with 
**
\lower\dp\strutbox\vbox to\dp\strutbox{}
**
The latter combination will appear
 more than once, so we adopt an abbreviation:
\CC**
\def\endstrut@{\lower\dp\strutbox\vbox to\dp\strutbox{}}
**

Although we will have  *\lineskiplimit=0pt* when *\longentry@* is
being used,
within our *\vbox* we want to declare
**
\normalbaselines
**
so that the standard value of *\lineskiplimit* is used there. (In the default
style *\normallineskiplimit* happens to be ~*0pt*, so that this is actually
superfluous, but in other styles that is not necessarily the case.)

Now we start to make a new box, in which we *\unvbox0*:
**
\setbox0=\vbox{\unvbox0
 \setbox0=\lastbox
  . . .
**
This makes the inner *\box0* the last line of the
paragraph, a ``short'' line that ends with *\parfillskip* glue,
and then yet another glue, namely *\rightskip*. So we need 
**
\unhbox0 \unskip\unskip
**
to get rid of this extra glue, before we 
 add *#3* and *#4*.
  In addition,
the hanging indentation does not insert glue or a kern at the beginning of
this box---instead, it merely shifts it to the right in the vertical list.
So we use
**
\setbox0=\vbox{\unvbox0
 \setbox0=\lastbox
 \hbox to\hsize{\kern\thehang@
  \unhbox0 \unskip\unskip#3#4\endstrut@}
 }
**
 to create  the desired final line.
And then we	
simply *\unvbox0*:
\CC**
\newdimen\thehang@
"slip
\long\def\longentry@#1#2#3#4{\setbox0=\hbox{#1}%
 \thehang@=\wd0 \advance\thehang@ by 10pt
"2
 \setbox0=\hbox{#4}%
"2
 \setbox0=\vbox{\advance\hsize by -\wd0 
  \advance\hsize  by -20pt
  \normalbaselines
  \hangafter1 \hangindent=\thehang@
"2
  \vskip-\parskip
  \rm\noindent@\vbox to\ht\strutbox{}%
   \hbox{#1}#2\vphantom{#3#4}\endstrut@}%
"2
 \setbox0=\vbox{\unvbox0
  \setbox0=\lastbox 
  \hbox to\hsize{\kern\thehang@
   \unhbox0 \unskip\unskip #3#4\endstrut@}%  
  }%
 \unvbox0 }
**
Note that in the last *\setbox0=\vbox* there is no extra glue between the
*\unvbox0* and the *\hbox to\hsize* (compare the footnote on page~\ref{NEXG});
that is why it is important to have the *\vphantom{#3#4}*, to insure
that the *\hbox to\hsize* has the same height as the *\lastbox* that it is
replacing. 


\section{Further preliminaries for the table of contents}
The *\maketoc* command is going to *\input* the appropriate *.toc* file,
which will have entries like
\setbox0\hbox{and}
\setbox1\hbox{\<word\>}
\setbox2\hbox{\<formatted heading number\>}
**
\HL {1}{"copy1}{"box2}  "8HLILLUS"8
  . . .     
\Page ...   
**
and/or entries like
\setbox0\hbox{and}
\setbox1\hbox{\<word\>}
\setbox2\hbox{\<formatted heading number\>}
**
\chapter {"copy1}{"box2}
 . . .                  
\Page ...     
**
(in which case an extra line like
**
\NameHL 1\chapter
**
should appear at the beginning), and similarly for *\hl*.

We will therefore be redefining *\HL* and *\hl* so that  such lines
print proper lines for the table of contents. 
But
a few preliminaries are needed to deal with the
 possibility that something like *""B""*, or even
*""\style B""* occurs instead of a \<formatted heading number\>.
First, we want a flag
\CC**
\newif\ifemptynumber@
**
which will be set true precisely in the case where we have *""""* (in the
paper proper, this happens when *\thelabel@@* is *\empty*). When it comes
time to properly print the argument `*...*'
of *\HL* that represents the heading
number, we will use
**
\Style@...\Style@
**
so that *\Style@* can use a *\futurelet* to see if `*...*' begins with
a *""* (we use *\Style@* because *\style@* is already used, as part of the
definition of *\style*).
We begin with 
\CC**
\def\Style@{\emptynumber@false\futurelet\next\Style@@}
\def\Style@@{\ifx\next""\expandafter\Style@@@
 \else\expandafter\Style@@@@\fi}
**
For *\Style@@@*, when no *""* occurs, we might expect to use
**
\def\Style@@@#1\Style@{#1}
**
Instead, however, we will use
\CC**
\def\Style@@@@#1\Style@{\style{#1}}
**
so that each heading level can temporarily define `*\style*' to produce
whatever sort of formatting for the number that we want.
On the other hand, *\Style@@@* is defined by
\CC**
\def\Style@@@""#1""\Style@{%
 \def\next@{#1}\ifx\next@\emtpy
  \emptynumber@true\else#1\fi}
**
Thus, in the special case that our original argument is *""""*, 
we simply set *\emptynumber@true*; otherwise we 
 print the argument *#1*. Notice that if this argument happens
to be something like *""\style B""*, the `*B*' will be formatted according
to the manner in which this heading level has temporarily defined
*\style* to operate.

For setting *\hl1* entries,
we will also declare a new dimension *\digits*, 
\CC**
\newdimen\digits "8DIGITS"8
\setbox0\hbox{0.00}
\digits=\wd0
**
so that *\digits* is the width of a double-digit number like  `1.12' (the
user could reset *\digits* if necessary to accommodate even more digits).

We also want to define
\CC**
\def\maketoc@W{CONTENTS}
**
so that *\newword\maketoc* can be used to choose a different word.

\section{Starting the \CS{maketoc} command}
The *\maketoc* command first uses *\checkmainfile@* (page~\ref{CHECKMF})
to issue an error message if no *\mainfile* command has appeared in the front
matter file, since it will have to *\input \mainfile@.toc*, where
*\mainfile@* has been defined by *\mainfile*.
Then it
 starts a new page,
in case something like a Preface precedes it (the default  front
matter style file *lamstex.stf*
doesn't have special constructions for Prefaces, etc., but
the *book* style, for example, does).
\footnote{We don't simply put *\checkmainfile@* at the beginning of
our file, since a user might omit the *\mainfile* line when 
simply checking that something like a Preface looks right.}
Then we produce a centered bold heading `{\bf CONTENTS}', followed by
some space.

Now we want  to
*\input* the appropriate *.toc* file, which
is when everything interesting will happen. Certain subsidiary definitions
will be needed, so
 we will  start with
*\begingroup* and add an *\endgroup* after the *\input*, to keep these all
local. 

Any
 *\label* or *\pagelabel* in a heading level or a 
caption will have been written
 to the *.toc* or *.tic* file (there's no practical
way to eliminate them), but they play no further role, and
we simply want to ignore them.  The same is true of any *\Reset* or
*\Offset*.  So after the *\begingroup* we want to add
**
\noset@ \unlabel@
**
(section~\Sref{relax} and ~\Sref{relax2}). 
Any *\nopunct* or *\nospace* or *\overlong* in the main file
will also show up in the *.tic* file.  Some styles might want to make
use of these (presumably having them set certain flags), but in the default
front matter style *lamstex.stf*, we simply want to
**
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
**
We also add
**
\everypar={}\parindent=0pt
**
for good measure.

Furthermore, as mentioned previously (page~\ref{USELIMITPROB}), it is
essential that we
 set
*\lineskiplimit=0pt*.
So our definition of *\maketoc* will start
**
\def\maketoc{\checkmainfile@
 \par\vfill\break
 \noset@ \unlabel@
 \let\nopunct=\relax \let\nospace=\relax
 \let\overlong=\relax
 \everypar={}\parindent=0pt
 \lineskiplimit=0pt
**


\section{Redefining \CS{HL} and \CS{hl}}
Next we have to redefine *\HL* and *\hl* so that *\HL* and *\hl* entries 
will be properly set for the table of contents. 

To redefine *\HL*, recall (page~\ref{HLILLUS})
that it will occur in a combination like
\setbox0\hbox{\<heading level\>}
\setbox1\hbox{\<formatted heading number\>}
\setbox3\hbox{\<heading word\>}
\setbox2\hbox{\<The heading\>}
**
\HL {"box0}{"box3}{"box1}
 "box2
\Page{...}{...}{...}{...}
**
so that we need a definition like
**
\def\HL#1#2#3#4\Page#5#6#7#8{ . . .   "87ARGS"8
**
(except that *#1* will be *##1*, etc., since this entire definition will be
made within the definition of *\maketoc*).

The definition should always begin 
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}
 . . .
**
so that subsequent constructions can know which heading level is being
considered. For the default front matter style we will be using
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}
 \ifnum\HLlevel@ = 1
   . . .
   . . . 
 \else
  \Err@{\string\HL#1 not defined in this style}%
 \fi}
**
so that an error message will be given if *\HL {*\<number\>*}* occurs
for any \<number\>${}\ne{}$*1*. (Theoretically this shouldn't happen, since
the *.toc* file is generated by the main file, which only recognizes
*\HL1*; but we might as well add this precaution in case the *.toc* file
has been edited.)

When *\HLlevel@* is~*1*, we want to use *\setentry@* with 
the appropriate data,
\setbox1\hbox{\<arg$_{\text1}$\>}
\setbox2\hbox{\<arg$_{\text2}$\>}
\setbox3\hbox{\<arg$_{\text3}$\>}
\setbox4\hbox{\<arg$_{\text4}$\>}
**
\setentry@{"box1}{"box2}{"box3}{"box4}
**
In terms of the original arguments *#1*, *#2*, *#3*, \dots, *#8*
 of *\HL* (see~ \recentpageref{7ARGS}{above}{the previous page}{}),
\<arg$_{\text2}$\> will be
**
\bf\ignorespaces#4\unskip
**
\<arg$_{\text3}$\> will be *\dotleaders*, and
\<arg$_{\text4}$\> will be
**
\Page@{#5}{#6}{#7}{#8}
**

As for
\<arg$_{\text1}$\>, it will essentially be
\setbox0\hbox{\<word\>}
**
\bf #2 #3
**
More precisely, it will be
**
\bf \def\next@{#2}\ifx\next@\empty\else#2\space\fi
 \let\style=\HL@@S \Style@#3\Style@
 \ifemptynumber@\else\space\fi
**
So the \<word\> *#2* is followed by a space, if it is non-empty. Moreover,
 when *\Style@...\Style@* uses *\style* to  
produce the formatting of the number, this *\style* 
 will be *\HL@@S* (i.e.,
`*\HL@S1*', since *\Hllevel@* was defined to be~*1*). And we also
add a space after this number,
 except in the case of an empty number.  Naturally, other
style files might do things differently.  Note, moreover, that although
`*\HL@S1*' has been defined in *lamstex.tex*, if *\newstyle\HL1* appears
in the main file, it will also have to be added to the *.toc* file to
produce the same effect.  (In practice, of course, only style file designers
will use *\newstyle\HL*, except perhaps for transient effects.)

A multi-level *\HL1* heading will have *\\* in it.  Although that should
probably be edited out, we can at least give *\\* a provisional definition as
\linebreak
`*\unskip\space\ignorespaces*'.
 The only other thing to worry about is the spacing around the heading:
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}%
 \ifnum\HLlevel@ = 1
"2
 \bigbreak
"2
  \begingroup
  \def\\{\unskip\space\ignorespaces}%
"2
  \setentry@
   {\bf\def\next@{##2}\ifx\next@\empty\else##2\space\fi
    \let\style=\HL@@S \Style@#3\Style@
    \ifemptynumber@\else\space\fi}%
   {\bf\ignorespaces#4\unskip}%
   \dotleaders
   {\Page@{#5}{#6}{#7}{#8}}
"2
  \endgroup
  \nobreak\smallskip
"2
 \else
  \Err@{\string\HL#1 not defined in this style}%
 \fi}
**

\newdimen\digits
\setbox0\hbox{0.00}
\digits=\wd0

The default style for *\hl1* headers is
\medskip
\line{\quad\qquad\hbox to\wd0{1.12}\enspace A short section
  \leaders\hbox to10pt{\rm\hfil.\hfil}\hfil\kern10pt79\qquad}
\medskip
\noindent
where we indent a *\quad* from the left margin, and
 leave room for a double-digit number like `*1.12*', followed by
an *\enspace*, before the section title.

We have already introduced *\digits* (page~\ref{DIGITS}),
and  the definition of *\hl* introduces nothing especially new:
**
\def\hl#1#2#3#4\Page#5#6#7#8{\def\hllevel@{#1}%
  \ifnum\hllevel@ = 1
"2
   \setentry@
    {\rm\quad \let\style=\hl@@S
     \hbox to\digits{\Style@#3\Style@\hfil}\enspace}%
    {\rm\ignorespaces#4\unskip}%
    \dotleaders
    {\Page@{#5}{#6}{#7}{#8}}%
"2
  \else
   \Err@{\string\hl#1 not defined in this style}%
  \fi}
**
In the default style, not only is `*\hl@W1*' empty, but *\hl1* doesn't
print this \<word\>, even if it has been changed by *\newword*; so
we also don't bother about printing it in the table of contents.


\section{\CS{NameHL} and \CS{Namehl}}
Finally, *\maketoc* has to deal with alternate names like *\chapter* and
*\section*.  If the main file has
**
\NameHL 1 \chapter
\Namehl 1 \section
**
then these lines should also appear in the *.toc* file (before the use
of *\chapter* or *\section*, respectively).


First of all, we have to redefine *\NameHL* so that, for example,
\setbox0\hbox{\<word\>}
**
\chapter {"box0}{2}
  . . . 
\Page...
**
will typeset the same thing as
\setbox0\hbox{\<word\>}
**
\HL {1}{"box0}{2}
 . . .
\Page...
**
In other words, we want to
**
"hskip-20pt\def\chapter#1#2#3\Page{\HL{1}{#1}{#2}#3\Page}
**
(we don't need braces around the second *#3*, since it is delimited by
*\Page*).   So in general we want *\NameHL#1#2* to  mean
**
\def#2##1##2##3\Page{\HL{#1}{##1}{##2}##3\Page}
**
and, similarly, we want
*\Namehl#1#2* to mean
**
\def#2##1##2##3\Page{\hl{#1}{##1}{##2}##3\Page}}
**

\section{\CS{maketoc}}Putting all this together, our definition of
*\maketoc* is:
\CC**
\def\maketoc{\checkmainfile@  "8STFMAKETOC"8
 \par\vfill\break
"2
 \begingroup
 \noset@ \unlabel@
"2
 \let\nopunct=\relax \let\nospace= \relax
"2
 \let\overlong=\relax
"2
 \everypar{}\parindent=0pt
 \lineskiplimit=0pt
"2
 \def\HL##1##2##3##4\Page##5##6##7##8{%
  \def\HLlevel@{##1}%
"2
  \ifnum\HLlevel@=1
  \bigbreak
"2
   \begingroup
   \def\\{\unskip\space\ignorespaces}%
"2
   \setentry@{\bf\def\next@{##2}\ifx\next@\empty
    \else##2\space\fi
    \let\style=\HL@@S \Style@##3\Style@
    \ifemptynumber@\else\space\fi}%
    {\bf\ignorespaces##4\unskip}\dotleaders
    {\Page@{##5}{##6}{##7}{##8}}%
"2
   \endgroup
"2
   \nobreak\smallskip
"2
  \else
   \Err@{\string\HL##1 not defined in this style}%
  \fi}%
"2
 \def\hl##1##2##3##4\Page##5##6##7##8{%
  \def\hllevel@{##1}%
"2
   \ifnum\hllevel@=1
"2
    \setentry@{\rm\quad\let\style=\hl@@S
     \hbox to\digits{\Style@##3\Style@\hfil}\enspace}%
     {\rm\ignorespaces##4\unskip}\dotleaders
     {\Page@{##5}{##6}{##7}{##8}}%
"2
   \else
    \Err@{\string\hl##1 not defined in this style}%
   \fi}%
"2
 \def\NameHL##1##2{\def##2####1####2####3\Page
  {\HL{##1}{####1}{####2}####3\Page}}%
"2
 \def\Namehl##1##2{\def##2####1####2####3\Page
  {\hl{##1}{####1}{####2}####3\Page}}%
"2
 \centerline{\bf\maketoc@W}%
 \vskip30pt plus10pt minus10pt
 \input\mainfile@.toc
 \endgroup}
**

\nopunct\section{Lists of Figures, Tables, etc.}
The commands
**
\makelistFigures
\makelistTables
**
are defined directly in terms of the more general *\makelist* command,
\CC**
\def\makelistFigures{\makelist\c{F}List of
  Figures\endmakelist}
\def\makelistTables{\makelist\c{T}List of
  Tables\endmakelist}
**
The syntax has been changed from that of the \lamstex~Manual, page~92,
to conform with the general \amstex\ and \lamstex\ syntax for constructions
that allow *\\* to be used to indicate line breaks.

*\makelist\c#1#2\endmakelist*,
 like *\maketoc*, first uses the test\linebreak *\checkmainfile@*, and then
ends the previous page. After this we want to add 
**
\noset@ \unlabel@
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
\everypar={}\parindent=0pt
\lineskiplimit=0pt
**
just as in *\maketoc*.
Then
*\makelist* will
**
\def\listclass@{#1}
**
so that, when we *\input* the *.tic* file we will know which of the
*\island*'s to process.  

Next *\makelist* must redefine *\island*.
In the case of *\HL#1...*,
once we had defined *\HLlevel@* as *#1*, 
the style control sequence *\HL@@S* was defined, so that we could
*\let\style=\HL@@S* in our definition of *\HL*.  A construction 
 introduced with *\NameHL1* is basically just a synonym for *\HL1*,
so we did not need to consider *\HL@@@S*, defined in terms of *\HLtype@*.
But the situation is different for *\island*'s, where we have only
*\island@@@S*, defined in terms of *\islandtype@*, which is *\island* for
an explicitly typed *\island*, but *\Figure* for a *\Figure*, etc.

To deal with this situation, 
\setbox0\hbox{\<Figure number\>}
\setbox1\hbox{\<caption\>}
**
\Figure {"box0}
 "copy1
\Page ...
**
 in the *.tic* file will translate
to
\setbox0\hbox{\<Figure number\>}
\setbox1\hbox{\<caption\>}
\Litbox2=**
\island \at@\Figure \c{F}{Figure}{"copy0}
 "copy1
\Page ...
**
$$\vcenter{\box2}\tag"\style{\bf A}"$$
---here *\at@* is simply an arbitrarily chosen \lamstex\ control sequence
that the user can't insert---%
while an explicitly typed *\island*, like
\setbox0\hbox{\<map number\>}
**
\island \c{M}{Map}{"box0}
**
will be regarded as 
\setbox0\hbox{\<map number\>}
**
\island \at@\island \c{M}{Map}{"box0}
**
so that eventually everything reduces to a common case.

We begin by redefining *\island* in terms of a *\futurelet*, to see whether
*\at@* follows:
**
\def\island{\futurelet\next\island@}
\def\island@{\ifx\next\at@\expandafter\island@@\else
 \expandafter\island@@@\fi}
**

*\island@@*, where *\at@* follows, has 9 arguments: 
**
\long\def\island@@\at@#1\c#2#3#4#5\Page#6#7#8#9
**
For example, in ({\bf A}), *#1* is `*\Figure*', *#2* is `*F*', *#3* is
`*Figure*', *#4* is the \<Figure number\>, and *#5* is the \<caption\>.

The definition of *\island@@*
is similar to
the definition of *\HL* except that:
\list\item we use argument *#1* to define
*\islandtype@*, rather than *\HLlevel@*; 
\item we print *#3* rather than the \<word\> before the \<Figure number\>; 
\item 
we process only those *\island*'s whose class *#2* is the *\listclass@* for
the list we are printing.\endlist
**
\long\def\island@@\at@#1\c#2#3#4#5\Page#6#7#8#9{%
 \def\islandtype@{#1}%
"2
 \def\next@{#2}%
"2
  \ifx\next@\listclass@
"2
   \setentry@
    {\rm#3" \let\style=\island@@@S \Style@#4\Style@
     \ifemptynumber@\else\space\fi}%
    {\rm\ignorespaces#5\unskip}%
    \dotleaders
    {\Page@{#6}{#7}{#8}{#9}}%
  \fi}
** 

The definition of *\island@@@*, when no *\at@* follows, is reduced to
the case where *\at@\island* follows:
**
\long\def\island@@@\c#1#2#3#4\Page#5#6#7#8{%
 \island@@\at@\island
  \c{#1}{#2}{#3}#4\Page{#5}{#6}{#7}{#8}}
**

\bigskip

When something like
**
\newisland\map\c{M}{Map}
**
appears, an occurrence of
\setbox0\hbox{\<map number\>}
\setbox1\hbox{\<caption\>}
**
\map {"box0}
 "box1
\Page ...
**
should translate to
\setbox0\hbox{\<map number\>}
\setbox1\hbox{\<caption\>}
**
\island \at@\map \c{M}{Map}{"box0}
 "box1
\Page ...
**
In other words, we should
**
\long\def\map#1#2\Page#3#4#5#6{\island \at@\map
  \c{M}{Map}{#1}#2\Page{#3}{#4}{#5}{#6}}
**

So in general, we want to
**
\def\newisland#1\c#2#3{%
 \long\def#1##1##2\Page##3##4##5##6{%
  \island\at@#1\c{#2}{#3}{##1}##2%
  \Page{##3}{##4}{##5}{##6}}}
**

Since *\Figure* and *\Table* are *\island* classes that are assumed to
be present in all styles, we should also add
**
\newisland\Figure\c{F}{Figure}
\newisland\Table\c{T}{Table}
**

Putting this all together, we have
\CC**
\def\makelist\c#1#2\endmakelist{\checkmainfile@
 \par\vfill\break
"2
 \begingroup
"2
 \noset@ \unlabel@
"2
 \let\nopunct=\relax \let\nospace=\relax
 \let\overlong=\relax
"2
 \everypar{}\parindent=0pt
 \lineskiplimit=0pt
"2
 \def\listclass@{#1}%
 \def\island{\futurelet\next@\island@}%
"2
 \def\island@{\ifx\next\at@\expandafter\island@@\else
  \expandafter\island@@@\fi}%
"2
 \long\def\island@@\at@##1\c##2##3##4##5\Page##6##7##8##9{%
  \def\islandtype@{##1}%
  \def\next@{##2}%
"2
  \ifx\next@\listclass@
"2
    \setentry@{\rm##3 
     \let\style=\island@@@S \Style@##4\Style@
     \ifemptynumber@\else\space\fi}%
     {\rm\ignorespaces##5\unskip}\dotleaders
     {\Page@{##6}{##7}{##8}{##9}}%
"2
  \fi}%
"2
 \long\def\island@@@\c##1##2##3##4\Page##5##6##7##8{%
  \island@@\at@\island\c{##1}{##2}{##3}##4\Page
   {##5}{##6}{##7}{##8}}%
"2
 \def\newisland##1\c##2##3{\long\def##1####1####2\Page
   ####3####4####5####6{%
  \island\at@##1\c{##2}{##3}{####1}####2\Page
   {####3}{####4}{####5}{####6}}}%
"2
 \newisland\Figure\c{F}{Figure}%
 \newisland\Table\c{T}{Table}%
"2
 \vbox{\Let@\tabskip\centering@\halign to\hsize
  {\bf\hfil\ignorespaces##\unskip\hfil\cr#2\crcr}}%
 \vskip30pt plus10pt minus10pt
 \input\mainfile@.tic
 \endgroup}
**

\section{Fini}Then, as in section~\Sref{DONE},
we finish with
\CC**
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
 \ch@ck#1#4#2\allocationnumber=\count1#1
 \global#3#5=\allocationnumber
 \wlog{\string#5=\string#2\the\allocationnumber}}
\catcode`\@=\active
**




\chapter Back matter\\The index\endchapter
\runningchapter{Back matter; the index}
Although the ``back matter'' may include the bibliography, and other matter,
the default style file *lamstex.stb* is used only for the index. As explained
in Chapter~13 of the \lamstex~Manual, the *\makeindex* command is going to
read in an *.xdx* ``expanded index file'', which is produced by the *index*
program from the *.ndx* file that \lamstex\ writes.  The *index* program is
discussed in the next chapter.  In this chapter, we are only concerned with
typesetting the *.xdx* file.  In the default style, we will be using a
two-column format, with balanced columns at the end.

Page 114 of The \lamstex~Manual 
gives 
a sample piece from an
*.xdx* file that illustrates almost all the features that we have to
consider;
 the only additional feature is *\PageSpan*, mentioned on page~117.


\section{Preliminaries\label{BMPRE}}As with *lamstex.stf*, we begin with
\CC**
\catcode`\@=11
\let\alloc@=\alloc@@
**
Since *"1* has a special role of indicating options in
 index entries, if an index entry actually had a \ast\ in it that symbol
will appear as *\asterisk*. So we will need to state
\dotC**
\let\asterisk="1
**
so that *\asterisk* will print out a \ast\,. We've printed dotted lines
around this definition, since it will
actually 
 only be made within the definition
of *\makeindex*---for any 
material inserted before or after *\makeindex*, the control sequence
*\asterisk* will simply be
undefined. 

As with the bibliography (section~\Sref{SBMACS}),
 we will be redefining  *\lkerns@* and
 *\nkerns@*
for properly placing punctuation before line-breaking penalties,
\dotC**
\def\lkerns@{\null\kern-1sp\kern1sp}
\def\nkerns@{\null\kern-2sp\kern2sp}
**
(we don't really need the *\null*'s that occurred previously, since we're not
setting *\vbox*'s, but for simplicity we might as well stick to the old
definitions). 
Once again, we use dotted lines,
since the redefinitions will only be made later,
by *\makeindex*,  so that line
breaking commands won't change their meaning until we are actually setting
the index. 
On the other hand, we can give
 a definition of *\adjustpunct@*
(section~\Sref{BIBMACS}) right now; it differs from the previous definition
only in the omission of
 *\closequotes@*:
\CC**
\def\adjustpunct@#1{\count@\lastkern
 \ifnum\count@=0 #1\else
 \ifnum\count@>2 #1\else
 \ifnum\count@<-2 #1\else
  \unkern\unkern\setbox0=\lastbox
  \skip@=\lastskip \unskip
  \count@@=\lastpenalty \unpenalty
  \ifnum\count@ = 2 \unskip \setbox0=\lastbox\fi
  \ifdim\skip@ = 0pt \else \hskip\skip@ \fi
  #1%
  \ifnum\count@=2 \null\hfill\fi
  \penalty\count@@
 \fi\fi\fi}
**
(Since *\adjustpunct@* is stated within *lamstex.tex* itself,
we could simply state
*\let\closequotes@=\relax*, but restating the definition is preferable
in case *\purge{bib}* has been used.)

In all the commands appearing in the *.xdx* file, 
\setbox0\hbox{etc.,}
**
\Entry 10{acetyl-CoA}{}{}{}{}
\Page {34}
"box0
**
we are going to want to ignore the space after the last *}*.
In addition, since blank lines might be introduced during editing,
or by ``error messages'',
we will want to skip over any such blank lines---we can't afford to
introduce a *\par* until we know that there are no more page numbers left to
be printed.
\footnote{In version~*1* of \lamstex@,
 the *index* program was careful not to introduce
any blank lines, inserting a~ *%* before an otherwise blank line if
necessary, and users were warned not to introduce blank lines.  However,
it seems preferable to have the macros
skip the blank lines, since they can make the
*.xdx* file look so much nicer.}
 So we will use *\FNSS@* to get the first non-space token, and then 
use a
*\futurelet\next* to see if the next token is
*\par*, which should also be discarded:
\CC**
\def\ignorepars@{\FNSS@\ignorepars@@}
\def\ignorepars@@{\ifx\next\par
 \def\next@\par{\futurelet\next\ignorepars@@}\else
 \let\next@=\relax\fi\next@}
**

One of the main tasks of the *lamstex.stb* macros is to provide suitable
*\mark*'s so that appropriate ``continuation'' lines may be written at the
top of a page
when a page
break has occurred within an index entry, or subentry, etc. And because of
this, 
column-breaking penalties will require more care.


The 
*\columnbreak* command was not mentioned in the Manual, but 
 was added for the
*paper* style, and mentioned in the Installation~Manual. In version~*2*
we are also supplying *\nocolumnbreak* and *\newcolumn* (for a short
column), although *\columnbreak* is really the only important one.
Although these commands
essentially insert penalties in vertical mode, we have to make sure
that the penalties occur at the proper time with respect to the
*\mark*'s that are emitted by the *\LETTER* and *\Entry* construction.

The column-breaking macros work quite differently from the line-breaking
macros because a penalty cannot be removed once it has been placed on the
main vertical list:	
they
will not insert any penalties directly, but
will simply set the value of a counter, for later use. We declare the counter
now,
\CC**
\newcount\ctype@
**	
but the  definitions
\dotC**
\def\nocolumnbreak{\ctype@=1 }
\def\columnbreak{\ctype@=2 }
\def\newcolumn{\ctype@=3 }
**
will only be given within the definition of *\makeindex*.
We also need to
declare a new counter to store the value of *\ctype@*, for use by the
*\output* routine, after other constructions have returned *\ctype@* to~*0*:
\CC**
\newcount\Ctype@
**

It also turns out that column breaks have to be treated quite differently
depending on whether they are inserted in the left column or the right
column, and we will need a flag
\CC**
\newif\ifleftcolbreak@
**

Now we define a routine *\cbreak@#1#2* that uses the value of *\ctype@*,
before resetting it to ~*0*.
The definition begins
**
\def\cbreak@#1#2{\ifcase\ctype@#1\or\nobreak#2\else
 . . .
**
Thus, if *\ctype@* is *0* (the usual situation, when no column-breaking
command has recently been given), we simply insert *#1*, which will normally
be penalty and glue.  If *\ctype@* is~*1* (because a *\nocolumnbreak*
command has recently been given), we instead insert *\nobreak* and then
*#2* (which would normally be *#1*
without the penalty).  If *\ctype@* is *2* or *3* (because a *\columnbreak*
or *\newcolumn* command has recently been given), we simply insert a
*\break*. Then we reset *\ctype@* to~*0*.  Before doing that last step,
however, we store *\ctype@* in *\Ctype@*.  Moreover, we set
*\ifleftcolbreak@* to be false if $\hbox{*\pagetotal*}>\hbox{*\pageheight*}$
(i.e., we already have enough on the page for the first column), but
true otherwise:
\CC**
\def\cbreak@#1#2{%
 \ifcase\ctype@#1\or
"2
 \nobreak#2\else
"2
  \global\leftcolbreak@true
  \ifdim\pagetotal > \pageheight@
   \global\leftcolbreak@false
  \fi
"2
  \global\Ctype@=\ctype@
  \break
 \fi
 \ctype@=0 }
**
The value of *\Ctype@* will be used by the *\output* routine, which will
then globally reset *\Ctype@* to ~*0*.


We have another flag
\CC**
\newif\ifshortlastcolumn@
**
for a final index feature not mentioned in the \lamstex~Manual,
\dotC**
\def\shortlastcolumn{\shortlastcolumn@true}
**
if we want the right
column on the last page of the index
to end short, instead of being spread out to match
the height of the left column.

\section{\CS{LETTER} and \CS{Entry}}
The first *\Entry* after a *\LETTER* will be treated somewhat specially, so
we will need a flag
\CC**
\newif\ifletter@
**
to tell when a *\LETTER* line has just been set. 

 *\LETTER* will 
end the previous paragraph (in which the various page numbers for a previous
entry are being set) and
emit a *\mark{}* to clear the marks.
 Then we want
**
\penalty-200
\bigskip
**
to encourage a page break (which really means a column break, since we will
be setting in double columns). 
More precisely, we will use
**
\cbreak@{\penalty-200 \bigskip}\bigskip
**
Thus, when a *\nocolumnbreak* command has just appeared, we insert only the
*\bigskip*, and when a *\columnbreak* or *\newcolumnbreak* command
has just appeared, we just insert a *\break*.
Then we set *\ifletter@* to be true,
center the letter in bold face in its column, and finally
add a\linebreak *\nobreak\medskip*:
\dotC**
\def\LETTER#1{\par
 \mark{}%
 \cbreak@{\penalty-200 \bigskip}\bigskip
 \letter@true
 \centerline{\bf#1}%
 \nobreak\medskip}
**
As usual, the dotted lines indicate that
this is a definition that will actually be included within the
definition of *\makeindex*.


To deal with the necessary *\mark*'s to be provided by
*\Entry*, it will be convenient to have five token lists:
\CC**
\newtoks\marktoks@i
\newtoks\marktoks@ii
\newtoks\marktoks@iii
\newtoks\marktoks@iv
\newtoks\marktoks@v
**
Moreover, we will use a  flag
\CC**
\newif\ifentry@
**
which *\Entry* will set true, and each *\Page* will set false.


\def\di{{\it d}$_{\text1}$}
\def\dii{{\it d}$_{\text2}$}

Some aspects of our *\Entry* macro are particular to the default style,
namely the particular manner in which entries and subentries are typeset.
But the really
 interesting aspect of *\Entry* is the way that
it uses the first
two arguments (\di, \dii, in the notation of
page~115 of the \lamstex~Manual), to determine which *\mark*'s should be
emitted; these *\mark*'s can be used by any style to define ``continuation
lines'' of any desired sort. To deal with all possibilities, we will need a
new counter
\CC**
\newcount\dii@
**
which will hold the value of \dii\ for the {\it previous\/}
*\Entry*.

The definition begins
**
\def\Entry#1#2#3#4#5#6#7{\par\entry@true
 \marktoks@i={#3}\marktoks@ii={#4}\marktoks@iii={#5}%
 \marktoks@iv={#6}\marktoks@v={#7}%
 \ifcase#1%
 \or
   . . .
**
Thus, since the
 case $\hbox{*#1*}=\hbox{\di}=\hbox{0}$ 
is not supposed to occur,  we consider first
the case  $\hbox{*#1*}=\hbox{\di}=\hbox{1}$,
 which means that we have a first order entry, i.e., 
  *#4*, \dots, *#7* are empty;
 in this case $\hbox{*#2*}=\hbox{\dii}$
 should be 0, since this new first order
entry can't have any number of groups agreeing with the previous entry.

We begin with
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent@
\mark{10{\the\marktoks@i}}%
\hangafter 1 \hangindent=.5em{#3}%
**
Thus:
\list\item
 We issue a *\mark{}* to clear the marks, unless the *\Entry* comes
right after a *\LETTER*, which has already done this.
\item  If a *\nocolumnbreak* appeared right before the *\Entry* we
add a *\nobreak*; and if a *\columnbreak* or *\newcolumn* appeared,
we add a *\break*, and also set *\ifleftcolbreak@* to the appropriate value
and store *\ctype@* in *\Ctype@* before restoring *\ctype@* to~ *0*.
\item
Then we start an unindented paragraph, which begins 
with a *\mark*,
**
\mark{10{\the\marktoks@i}}%
**
containing  *#1#2*, and then a single group containing
*#3* (without any expansion).
The
**
\hangafter1 \hangindent=.5em{#3}%
**
means 
that after the entry *#3* is printed  we are set up for printing the
various page numbers, with hanging indentation if there are so many that they
won't fit on a line. We enclose *#3* in a group, in case it involves a font
change command, and are careful not to allow a space after *{#3}*, since
punctuation  still has to be added.
\endlist

When the paragraph with this entry is completed,
the *\mark{10{...}}*\linebreak will  migrate out so that it occurs right after
the first line (before any\linebreak *\baselineskip* glue); consequently,
there will be no legal breakpoint between the *\mark* and this first line,
containing the typeset *{#3}*.
If a page break occurs after this entry, but
 before another entry, which contributes a new *\mark*,
then after the
page has been *\output* the value of
*\botmark*
will be
**
10{#3}
**
When a style file has to add continuation lines at the beginning of the next
page, the *10* will tell it that the style broke at a main entry, which will
be contained in the next group.
 (Actually, we will be using *\splitbotmark* rather than
*\botmark* when we do two-column setting.)


In summary, our definition begins:
**
\def\Entry#1#2#3#4#5#6#7{\par\entry@true
 \marktoks@i={#3}\marktoks@ii={#4}\marktoks@iii={#5}%
 \marktoks@iv={#6}\marktoks@v={#7}%
 \ifcase#1%
 \or
   \ifletter@\else\mark{}\fi
   \cbreak@\relax\relax
   \noindent@
   \mark{10\the\marktoks@i}%
   \hangafter1 \hangindent=.5em{#3}%
 \or
**

Now let's consider the next case, $\hbox{\di}=\hbox{*#1*}=\hbox{2}$, 
so that we have a first order
subentry. In this case $\hbox{\dii}=\hbox{*#2*}$
 may be either ~0 or~1. When $\hbox{*#2*}=\hbox{0}$, we
have a subentry that does {\it not\/} have the same main entry as the
previous line, like the situation
**
\Entry 10{abracadabra}{}{}{}{}
\Page {5}
\Entry 20{acetyl-CoA}{action of}{}{}{}
\page {32}
**
As mentioned on page~116 of the \lamstex~Manual, in some styles this might
be printed as
 {\bigskip\eightpoint\leftskip=30pt \noindent
 abracadabra, 5\newline
 acetyl-CoA, action of, 32
\bigskip}
\noindent  
In the default style, we will still print 
 {\bigskip\eightpoint\leftskip=30pt \noindent
 abracadabra, 5\newline
 acetyl-CoA\newline
 \null\hskip5pt action of, 32
\bigskip}
\noindent 
but we still have to treat the *\mark*'s differently for the
cases $\hbox{\dii}=\hbox{*#2*}=\hbox{0}$ and $\hbox{\dii}=\hbox{*#2*}=
\hbox{1}$.

For the  case $\hbox{*#2*}=\hbox{0}$ we want
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent
\mark{20{\the\marktoks@i}{\the\marktoks@ii}}%
\hangafter1 \hangindent=.5em{#3}\par\nobreak
\noindent\hangafter1 \hangindent=1.5em\quad{#4}%
**
Thus:
\list\item
We clear the previous mark (the one for *abracadabra*).
\item We emit the mark
\setbox0\hbox
 {$\bigl[$*20{acetyl-CoA}{action of}*, in the above example$\bigr]$}
**
20{#3}{#4}   "box0
**
 and then set up the proper format for printing things.
If the page breaks in the middle of this entry, then *\botmark* will have
the value
**
20{#3}{#4}
**
and the *\output* routine will be clued in as to
what sort of continuation lines to
add.
\endlist

The other case, when $\hbox{*#2*}=\hbox{1}$, 
corresponds to the more common situation
where we have something like
**
\Entry 10{acetyl-CoA}{}{}{}{}
\Page {32}
\Entry 21{acetyl-Coa}{action of}{}{}{}
\Page {45}
**
Here we will use
**
\mark{10{\the\marktoks@i}}%
\cbreak@\relax\relax
\noindent@
\mark{21{\the\marktoks@i}{\the\marktoks@ii}}%
\hangafter 1 \hangindent=1.5em\quad{#4}
**

Even when the *\cbreak@* contributes nothing (the usual situation), there
is a legal break point between the first *\mark* and the *\noindent@*'ed
paragraph that follows, because of the *\parskip* glue (possibly *0pt*)
before this paragraph.
If the page breaks at this point, then *\botmark* will be this first
**
\mark{10{acetyl-CoA}}
**
which is precisely right: we have broken in the middle of a first level
entry. If the page breaks after the sub-entry begins, but before a new
*\Entry*, which contributes a new *\mark*, then *\botmark* will be
**
21{acetyl-CoA}{action of}
**
again giving the *\output* routine all the information it needs to decide
what sort of continuation lines to insert.

\small
Although we are using *\cbreak@\relax\relax* in all clauses of our
*\Entry* definition, other styles might give more detailed choices. For
example, it might be considered 
 better to break right before an entry than right before 
a subentry.  We might use something like
**
\cbreak@{\ifletter@\else\penalty-20 \fi}\relax
**
for the case $\hbox{*#1*}=1$, thereby slightly encouraging a column break
before main entries, except those immediately following a *\LETTER*.
\endsmall


The case $\hbox{\di}=\hbox{*#1*}=\hbox{3}$
 begins similarly: When $\hbox{*#2*}=\hbox{0}$ we use
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent
\mark{30{\the\marktoks@i}{\the\marktoks@ii}{\the\marktoks@iii}}%
\hangafter1 \hangindent=.5em{#3}\par\nobreak
\noindent@\hangafter1 \hangindent=1.5em\quad{#4}\par\nobreak
\noindent@\hangafter1 \hangindent=2.5em\qquad{#5}%
**
and when $\hbox{*#2*}=\hbox{1}$ we use
**
\mark{10{\the\marktoks@i}}%
\cbreak@\relax\relax
\noindent@
\mark{31{\the\marktoks@i}{\the\marktoks@ii}{\the\marktok@iii}}%
\hangafter1 \hangindent=1.5em\quad{#4}\par\nobreak
\noindent@\hangafter1 \hangindent=2.5em\qquad{#5}%
**

But the case $\hbox{*#2*}=\hbox{2}$
 is a little different, because the previous entry
might have been an *\Entry 20* or an *\Entry 21*, and to provide the style
with all possible information, we want to supply the correct result.  So we
use
**
\mark{2"9\number\dii@"9{\the\marktoks@i}{\the\marktoks@ii}}%
\cbreak@\relax\relax
\noindent@
\mark{32{\the\marktoks@i}{\the\marktoks@ii}{\the\marktoks@iii}}%
\hangafter1 \hangindent=2.5em\qquad{#5}%
**
where *\dii@* will have the proper value, because, at the very end of
this long *\ifcase* (with sub *\ifcase*'s)
we finish off the whole definition of *\Entry* with
**
\dii@=#2\relax
\letter@false\ignorepars@}
**

We won't bother writing out the whole definition, since these parts explain
everything interesting that is going on (moreover, the whole definition
appears only within the definition of *\makeindex*).

\nopunct\section{\CS{Page}, etc.\label{IPAGE}}
Using *\adjustpunct@* (section~\Sref{BMPRE}), we will define
*\Page* for the index setting by
\dotC**
\def\Page#1{\ifentry@\adjustpunct@,\enspace\else
 \adjustpunct@, \fi\entry@false{#1}\ignorepars@}
**
In other words, the first *\Page* after an *\Entry*, when *\ifentry@* is
still true,
 will add a comma after
the entry, and then an *\enspace*, while successive *\Page*'s, for which
*\ifentry@* will be false,
 will simply
add a comma after that page number and then an ordinary space
(with suitable juggling of line-breaking penalties).
We put *#1* in a group in case it involves a font change.

The *\Pagespan*, *\Topage* combination requires a bit more
 manipulation, because
the *index* program may have produced something like
**
\Pagespan {123}
\Topage {123}
**
which should be printed simply as `123', rather than as `123@--123'.

We begin with
\dotC**
\def\Pagespan#1{\ifentry@\adjustpunct@,\enspace\else
 \adjustpunct@, \fi
 \entry@false\def\frompage@{#1}{#1}\ignorepars@}
**
Thus, we supply punctuation just as with *\Page*, and before printing
*#1* we also
 store
*#1* in *\frompage@*, for use with *\Topage*, defined by
\dotC**
\def\Topage#1{\def\next@{#1}\ifx\next@\frompage@
 \else\hbox{--}{#1}\fi\ignorepars@}
**
The *\hbox{--}* gives an en-dash at which a line break can't occur
 (it is what the
\lamstex\ construction *@--* produces).

The variant *\PageSpan#1#2*, which has a control sequence as
its first argument, puts in punctuation in the same manner as 
 *\Pagespan*, and also
 stores the page argument, *#2*, in *\frompage@*, as well as the
control sequence, *#1*, in *\pagecs@*.  Then it begins a group in which
the definition of *\Topage* will be changed, so that the *\Topage* following
*\PageSpan* can act differently than when it follows *\Pagespan*:
\dotC**
\def\PageSpan#1#2{\ifentry@\adjustpunct@,\enspace
 \else\adjustpunct@, \fi\entry@false
 \def\pagecs@{#1}\def\frompage@{#2}%
 \bgroup\let\Topage=\Topage@\ignorepars@}
**
Then *\Topage@* will apply *\pagecs@* to the pages spanned (or to
a single page if the two numbers are the same), and supply the *\egroup* to
match the *\bgroup*:
\CC**
\def\Topage@#1#2{\def\next@{#2}\ifx\next@\frompage@
  \pagecs@{\frompage@}\else
  \pagecs@{\frompage@\hbox{--}#2}\fi
  \egroup\ignorepars@}
**
We use *\pagecs@{...}* 
in case *\pagecs@* is a control sequence with
an argument; the *\bgroup* and *\egroup* provide the necessary extra level of
grouping in case *\pagecs@* is a font change instruction. We might as 
well give the definition of *\Topage@* now, rather than within the
definition of *\makeindex*, since *\Topage@* can't be typed by the user
anyway. 


\nopunct\section{\CS{Xref}, etc.}
The description of the *"1x* option 
on page~108 of the \lamstex~Manual, and the output it supposedly produces in
the *.xdx* file, as described on page~115 of the Manual, is incorrect.
\footnote{As mentioned on pages~8--9 of the \lamstex\
Installation Manual.} 
There are actually {\it two\/} options, *"1x* and *"1X*. The *"1x* option
is to be used
when only a cross-reference is desired, and not a reference to the page on
which the entry is marked, while the *"1X* option indicates a reference to
the page on which the entry is marked, together with a cross reference.

If an entry is always marked with the *"1x* option, then the pages on which
it is marked are completely irrelevant, and it will give rise to an 
*\Entryxref* line in the *.xdx* file (possibly followed by various
*\Morexref* lines).  Otherwise, it will give rise to something like
\Litbox0=**
\Entry ...
\Xref ...
\Morexref ...
 . . .
\Page ...
\Page ...
\Xref ...
\Morexref ...
 . . .
**
$$\vcenter{\box0}\tag"\style{\bf A}"$$
with *\Xref...* material occurring both before and after the *\Page*'s because
some styles might want to print the `{\it see also\/}' before the page
numbers instead of after them.

In any case, as the Manual shows on page~115, each *\Xref*, *\Morexref*,
and *\Entryxref* will contain *\See*, which can be defined as needed.

In the default style we will be ignoring the *\Xref* and *\Morexref*'s in 
({\bf A}) that come before the first *\Page*;
this means that we want
 *\Xref* and *\Morexref* to operate only when *\ifentry@* is false.


*\Xref*, which will occur after some *\Page*, will add a semi-colon after
the page, and then print `{\it see also\/} ' before its argument.
As with the bibliography macros, we use *\semicolon@* instead of~ *;* for
the benefit of French styles (section~\Sref{SEMICOL}), and we add *\/* before
it,
\dotC**
\def\Xref#1{\ifentry@\else
 \def\See##1{\/\adjustpunct@\semicolon@\space
 {\it see~also\/}~##1}{#1}\fi\ignorepars@}
**
while *\Morexref* will simply add a comma after the previous 
cross-reference page, and then a space:
\dotC**
\def\Morexref#1{\ifentry@\else
 \def\See##1{\adjustpunct@, ##1}{#1}\fi\ignorepars@}
**

An *\Entryxref* is basically just an *\Entry*, after which we 
add the final argument rather than succeeding *\Page*'s.
\dotC**
\def\Entryxref#1#2#3#4#5#6#7#8{%
 \Entry{#1}{#2}{#3}{#4}{#5}{#6}{#7}%
 \def\See##1{\adjustpunct@, {\it see\/}~##1}%
 {#8}\ignorepars@}
**
(The *\adjustpunct@* is added in case the user adds a line-breaking
command, like
**
\Entryxref 10{adrenalin}{}{}{}{}{\linebreak\See {epinephrine}}
**
by hand.)


\small
Suppose that we want to print the `{\it see also }'
before the page numbers instead of after them, which means that 
we need to
use the *\Xref*'s and *\Morexref*'s that
appear before the first *\Page*, 
ignoring *\Xref*'s and *\Morexref*'s
following a *\Page*. 

For this we would introduce a new flag
**
\newif\ifxref@
**
which *\Xref* would set true and *\Entry* would set false, and then
we could use  definitions like
**
\def\Xref#1{\ifentry@
 \def\See##1{ {\it see also\/} ##1}{#1}\fi\ignorepars@}
\def\Morexref#1{\ifentry@
 \def\See##1{\adjustpunct@, ##1}{#1}\fi\ignorepars@}
\def\Page#1{\ifxref@\newline\else
 \ifentry@\adjustpunct@,\enspace\else
  \adjustpucnt@, \fi\fi\entry@false{#1}\ignorepars@}
**
Then entries without cross-references would appear as before, while
entries with cross-references would appear as
{\bigskip\eightpoint\leftskip30pt
 acetyl-CoA {\it see also\/} derivative, pyruvate 
 \hskip5pt 30, 56, 78
\bigskip}
\noindent Instead of the *\newline* we might prefer `*. *' or 
perhaps *\Xref* would add `*({\it see also\/} *' while
*\Page* would add `*) *' instead of *\newline*.

\andsmall
Similarly,
any punctuation  after the last page number would have to be added by
the next *\Entry* (the definition
of *\makeindex* would also have to take care of the last *\Entry* specially).
 But
no one ever adds this punctuation, so why worry about it. 
\endsmall



\section{Preliminaries for double columns}
We first declare
a \<dimen\> register to store *\vsize*,
\CC**
\newdimen\pageheight@
\pageheight@=\vsize
**
since *\vsize* will be changed when
we are storing material for double columns,
and a dimension *\doublepageheight@*, which is a little more than twice
*\pageheight@*,
\CC**
\newdimen\doublepageheight@
\doublepageheight@=2\pageheight@
\advance\doublepageheight@ by 1 pc
**

We also declare a \<dimen\> register
 to store the original *\hsize*, 
\CC**
\newdimen\pagewidth@
\pagewidth@=\hsize
**

The *\makeindex* routine will be setting columns 3~inches wide, so we will be
changing *\hsize*.  Consequently, we must redefine *\makeheadline* and
*\makefootline*  from *plain* \tex@, so that *\line* ($=${}*\hbox to\hsize*)
is replaced by *\hbox to\pagewidth@*:
\CC**
\def\makeheadline{\vbox to 0pt{\vskip-22.5pt
 \hbox to\pagewidth@{\vbox to 8.5pt{}\the\headline}\vss}%
 \nointerlineskip}%
\def\makefootline{\baselineskip=24pt
 \hbox to\pagewidth@{\the\footline}}%
**
(The definition of *\makeheadline* isn't really needed for the default style,
 since we are going to keep *\headline={}*, but we might as well take care of
the general mechanism.)

As in Appendix E of {\it The \tex book}, page~417, 
we will be setting ``pages'' 
of
length *\doublepageheight@*, so that we can
automatically balance the columns on the last page.
We need another flag
\CC**
\newif\iffirstindexpage@
**
since the first page of the index is special, having a header `{\bf INDEX}'
that extends across both columns.

\section{\CS{makeindex}}
The *\makeindex* routine begins 
\setbox0\hbox{\<all previous definitions enclosed in dotted lines}
\setbox1\hbox{\qquad(including the definition of *\Entry*)\>}
**
\def\makeindex{\checkmainfile@\par\vfill\break
 \begingroup
 "box0
 "box1
 \hsize=3in
**
Of course all *#*'s in any of those \<previous definitions\> are changed to
*##*'s. 

Next we set 
**
\global\vsize=\doublepageheight@
**
so that we will have
accumulated slightly more than we need to fill both columns of the page
before the *\output* routine is called (we use *\global* here because
it will be required later, when we set *\vsize* within the *\ouput* routine).
And
we set
**
\maxdepth=\maxdimen
**
 so that the depth of
*\box255* will always be the actual depth of its last line; this is
needed at one point later (compare {\it The \tex book}, page~262@--263).

Then we set 
**
\global\firstindexpage@true
\global\advance\vsize by -60pt
**
The 
60~points is need to leave room for a 30~point heading above both columns.

Next,
 we
set 
**
\everypar={}\parindent=0pt
**
just as a precaution, and then
**
\rightskip=0pt plus3em \spaceskip=.3333em \xspaceskip=.5em
**
for ragged
right setting (we allow even more ``raggedness'' than the definition of
*\raggedright* in *plain* \tex)@. 

And then  we want to change the *\output* routine to one called
**
\doublecolumns@
**
before reading in the appropriate *.xdx* file; after this file has been
read we will issue an empty *\mark{}*,
change the *\ouput* routine to one called
*\balancecolumns@*, for the final page of the index, and then supply
the *\endgroup* that matches the *\begingroup* at the beginning of the
definition. For anything that follows the *\makeindex*, we will once
again have *\output="allowbreak{\plainoutput}*.  However, *\vsize* has
been globally changed, so we must reset it to *\pageheight@*.
\setbox0\hbox{\<definitions from before\>}
\CC**
\def\makeindex{\checkmainfile@
 \par\vfill\break
 \begingroup
 "box0
 \hsize=3in
"2
 \global\vsize=\doublepageheight@
"2
 \maxdepth=\maxdimen
"2
 \global\firstindexpage@true
"2
 \global\advance\vsize by -60pt
"2
 \everypar={}\parindent=0pt
"2
 \rightskip=0pt plus3em \spaceskip=.3333em \xspaceskip=.5em
"2
 \output={\doublecolumns@}%
 \input\mainfile@.xdx
 \mark{}%
 \output={\balancecolumns@}%
 \vfil\break
 \endgroup
 \global\vsize=\pageheight@}
**


\section{\CS{combinecols\@}}
Both *\doublecolumns@* and *\balancecolumns@* will store the two columns
in *\box0* and *\box2* and then
 use the routine
*\combinecolumns@*, which prints these boxes 
side by side, together with the proper headline and footline.
**
\def\makeindex@W{Index}
"slip
\def\combinecolumns@{%
"2
 \setbox\outbox@=\vbox{\makeheadline
"2
  \vbox to\pageheight@{\boxmaxdepth=\maxdepth
"2
   \iffirstindexpage@
"2
    \vbox to30pt{\vskip10pt
     \hbox to\pagewidth@{\hfil\bf
      \uppercase\expandafter{\makeindex@W}\hfil}\vfil}
"2
    \nointerlineskip
   \fi
"2
  \wd0=\hsize \wd2=\hsize
  \setbox0=\hbox to\pagewidth@{\box0 \kern.5in\box2}
  \dimen@=\dp0 \box0 \kern-\dimen@\vfill}
  \makefootline}
 {\noexpands@ \let\style=\relax
  \shipout@\box\outbox@
 }
    .  .  .
**

This is like the *\shipout@*  occurring in our definition of
*\plainoutput* (page~\ref{DEFPLOUT}),
except that the *\pagebody* must be replaced by
a *\vbox to*\linebreak*\pageheight@*,
 containing the two boxes with a separation
of *.5in*. There are also two minor adjustments to be made:  
\list
\item
We must explicitly declare the widths of *\box0* and *\box2*
to be *\hsize* (*\hsize* is simply the width of paragraphs within
these boxes; an inserted *\box* in vertical mode could be any width---compare
the footnote on page~\ref{MAXD}).
\item
Our *\vbox to\pageheight@* ends with the
**
\hbox to\pagewidth@{\box0 \kern.5in\box2}
**
followed by 
*\vfill* (preceded by a *\kern*).
  That is because on the last page, where we balance
columns, this *\hbox* will generally be smaller than *\pageheight@*.
Most of the time, of course, the *\vfill* will be irrelevant, except that
we have to be sure to insert the *\kern* before the *\vfill*, so that
the depth of the *\hbox* will not cause an *Overfull* box (compare
page~\ref{KMPR}).\pagelabel{USEKMPR}
\endlist

In addition, on the first page of the 
index, our two columns, *\box0* and *\box2* 
will have been made 30~points smaller
than *\pageheight@*, in order to accommodate the
**
\vbox to30pt{\vskip10pt
 \hbox to\pagewidth@{\hfil\bf
  \uppercase\expandafter{\makeindex@W}\hfil}\vfil}%
 \nointerlineskip
**
that we insert. We use *\makeindex@W*, so that *\newword* can be used
to determine the heading that will be printed.

 Notice that we have the *\noexpands@...\shipout@* in a
group, so that the *\noexpands@* won't interfere with
font change instructions in 
``continuation'' lines contributed later 
 (see page~\ref{CONLINES}) by the *\output* routine. (Compare 
page~\ref{SHIPOUTGROUP}.)

After all this, we simply declare *\iffirstindexpage@* to be false,
set *\vsize* to *\doublepageheight@*, its proper value for all index pages
after the first, and *\advancepageno*:
\CC**
\def\makeindex@W{Index}
"slip
\def\combinecolumns@{%
"2
 \setbox\outbox@=\vbox{\makeheadline
"2
  \vbox to\pageheight@{\boxmaxdepth=\maxdepth
"2
   \iffirstindexpage@
"2
    \vbox to30pt{\vskip10pt
     \hbox to\pagewidth@{\hfil\bf 
      \uppercase\expandafter{\makeindex@W}\hfil}%
    \vfil}%
"2
    \nointerlineskip
"2
   \fi
"2
   \wd0=\hsize \wd2=\hsize
   \setbox0=\hbox to\pagewidth@{\box0 \kern.5in\box2}%
"2
   \dimen@=\dp0 \box0 \kern-\dimen@\vfill}%
   \makefootline}%
 {\noexpands@ \let\style=\relax
  \shipout@\box\outbox@
 }%
 \global\vsize=\doublepageheight@
 \global\firstindexpage@false
 \advancepageno}
**


\section{\CS{doublecolumns\@}}
For the
 *\doublecolumns@* routine, used for all but the last page, we will need
a new \<dimen\> register
\CC**
\newdimen\prevcoldepth@
**
The routine
begins
with
**
\dimen@=\pageheight@
\iffirstindexpage@ \advance\dimen@ by -30pt \fi
**
so that *\dimen@* is the height of the columns we want for the page.

Now we have to consider the possibility that a *\columnbreak* or a\linebreak
*\newcolumn*
command caused the *\output* routine to be invoked. More precisely, we
want to insert the code
**
\ifleftcolbreak@
 \global\leftcolbreak@false
 . . .
\else
 _ _ _
\fi
**
The flag *\ifleftcolbreak@* is set true  (by  *\cbreak@*) when
a *\columnbreak* or *\newcolumn* command has been issued 
when we are setting the left column,
\footnote{I.e., when *\pagetotal* is
 $\le\hbox{*\pageheight@*}$.}
and it is used only in the current
test; since we immediately reset it to be false, this means that
*\ifleftcolbreak@* is true precisely when we have forced a break in the left
column. We will simply let `\hbox{*. . .*}' for this case be
**
\vbox to\dimen@{\dimen@=\dp255 \unvbox255 
 \ifnum\Ctype@=3 \kern-\dimen@\vfill\fi}
\allowbreak
**
In other words, when our *\output* routine has been forced while we
still have only enough material for the first column, we do not do any
*\shipout*, but simply put material back on the main vertical list.
What we put back is a *\vbox to\dimen@* (remember that *\dimen@* is
the desired height of columns for this page), containing all the material
in *\box255*, either stretched out, when we had a *\columnbreak* (so that
*\Ctype@* is~*2*), or filled with empty space at the bottom, when we had
a *\newcolumn* (so that *\Ctype@* is~*3*). As before (page~\ref{USEKMPR}),
 we need to add a
*\kern* before the *\vfill*.


  The next time the *\output*
routine is called, *\doublecolumns@* will use the rest of the routine, still
to be defined, which splits the full *\box255* into two boxes of height
*\dimen@*; the first part will then have to be this *\vbox to\dimen@* that
we have just added to the main vertical list.
\footnote{The only problem here is that the *\output* routine could
conceivably be *\balancecolumns* the next time it is called---see
the discussion on page~\ref{CBBAL}~ff.}

Having gotten that consideration out of the way, let's consider the
other situation, where we haven't forced a break in a left-hand column.
Now we want to *\vsplit* *\box255* into two boxes of height *\dimen@*.
During the process we will set *\splittopskip=\topskip* and
*\splitmaxdepth=\maxdepth* (this assignment will be local, since the
*\output* routine, *\doublecolumns*, is implicitly enclosed in a group).
Splitting off the first column requires no special work,
**
\splittopskip=\topskip \splitmaxdepth=\maxdepth
\setbox0=\vsplit255 to\dimen@
**
But for the second column, we can't simply
**
\setbox2=\vsplit255 to\dimen@
**
This works when *\Ctype@* is~*0* or ~*1* (no column-breaking commands,
except perhaps a *\nocolumnbreak*,
were given). But when *\Ctype@* is~
*2* or~ *3*
(a *\columnbreak* or *\newcolumn* 
command was given) the *\vsplit*'ing is irrelevant---we
should simply let *\box2* be *\box255*.
And when *\Ctype@* is~*3*
(the *\newcolumn* case), we need to add *\vfill* at the
bottom of the box.
For a later step, we also want to store the depth of the last line
of the second column in *\prevcoldepth@*.

Since the cases when *\Ctype@* is *0* and *1* are treated the same,
we consolidate the cases by first stating
**
\ifnum\Ctype@=0 \global\Ctype@=1 \fi
**
Then we can use
**
\ifcase\Ctype@ \or  % case 1 (originally 0 or 1)
 \setbox2=\vsplit255 to\dimen@
 \global\prevcoldepth@=\dp2
 \or % cases 2 and 3
  \global\prevcoldepth@=\dp255 % store the depth first
  \setbox2=\vbox to\dimen@{\unvbox255
   \ifnum\Ctype@=3 \vfill\kern-\prevcoldepth@\vfill\fi}
 \fi
**

Once we've determined the columns, *\box0* and *\box2*, in this way,
we use
**
\combinecolumns@
**
to *\shipout* the desired page.

Now we have reached the point where we want the *\output* routine to
add ``continuation'' lines\pagelabel{CONLINES}
 (these lines, inserted by the *\output* routine,
will go before anything remaining in *\box255*, since we will add these
lines before we *\unvbox255*; and both go before anything else that happens
to remain on the main vertical list when the page break was chosen).

The default routine adds continuation lines at the beginning of the left
column on
a new page
to reflect the *\mark*'s at the end of the right column on the previous page.
This means that we will want to use *\splitbotmark* when *\box2* was
obtained as a *\vsplit255 to\dimen@*, but *\botmark* otherwise.
The specific continuation lines to be constructed from these marks will
be contributed by a routine, to be defined shortly,
\setbox0\hbox{\<the *\mark*'s\>}
**
\continue@ "box0 \continue@
**
It will be convenient to consider *\continue@* to be followed by at least
~7 (possibly empty) arguments,
 and we will use
**
\ifcase\Ctype@ \or % case 1, where \vsplit was used
\expandafter\continue@\splitbotmark{}\relax\relax\relax
  \relax\relax\relax\continue@
\else % cases 2 and 3
\epxandafter\continue@\botmark{}\relax\relax\relax
  \relax\relax\relax\continue@
\fi 
**
As we will see in a minute, *\continue@* will also attend to an important
detail about spacing.

After these continuation lines, we simply use
**
\ifvoid255 \else \unvbox255 \penalty\outputpenalty\fi
**
to finish the *\else* clause of our definition.  And, finally, after the
entire *\if...\else...\fi* has been done, we reset *\Ctype@* to be~*0*:
\CC**
\def\doublecolumns@{%
 \dimen@=\pageheight@ 
 \iffirstindexpage@ \advance\dimen@ by -30pt \fi
"2
 \ifleftcolbreak@
  \global\leftcolbreak@false
  \vbox to\dimen@{\dimen@=\dp255
   \unvbox255 \ifnum\Ctype@=3 \kern-\dimen@\vfill\fi}%
  \allowbreak
"2
 \else
  \splittopskip=\topskip \splitmaxdepth=\maxdepth
  \setbox0=\vsplit255 to\dimen@
"2
  \ifnum\Ctype@=0 \global\Ctype@=1 \fi
"2
  \ifcase\Ctype@ \or
   \setbox2=\vsplit255 to\dimen@
   \global\prevcoldepth@=\dp2
"2
  \else
   \global\prevcoldepth@=\dp255
   \setbox2=\vbox to\dimen@{\unvbox255
    \ifnum\Ctype@=3 \kern-\prevcoldepth@\vfill\fi}%
  \fi
"2
  \combinecolumns@
"2
  \ifcase\Ctype@ \or \expandafter
    \continue@\splitbotmark{}\relax\relax\relax
     \relax\relax\relax\continue@
  \else
    \expandafter\continue@\botmark{}\relax\relax\relax
     \relax\relax\relax\continue@
  \fi
"2
  \ifvoid255 \else \unvbox255 \penalty\outputpenalty \fi
 \fi
 \global\Ctype@=0 }
**

\medskip
The *\continue@* routine is followed by at least~7 (possibly empty) arguments,
**
\def\continue@#1#2#3#4#5#6#7#8\continue@
**
Since *\continue@* is used in a combination 
\setbox0\hbox{\<value of *\splitbotmark* or *\botmark*\>}
**
\continue@"box0{}\relax\relax\relax
 \relax\relax\relax\continue@
**
the test
**
\def\next@{#1}\ifx\next@\empty
**
isolates the case where the *\mark* is empty (in all other cases the
mark will begin with a digit).
 When this is not the case,
we want
**
\noindent@#3 ({\it continued\/})\par
**
as the first continuation line.  The default style also introduces
slightly differently formatted continuation lines for any sub-entries, where
the number of levels of sub-entries is known from the value of *#1*,
**
\ifnum#1>1 \noindent@\enspace(#4 {\it continued\/})\par\fi
 . . .
\ifnum#1>4 \noindent@\enspace(#7 {\it continued\/})\par\fi
**


After these continuation lines are added, we have to attend to the detail
mentioned on page~263 of {\it The \tex book},  except that  
now we have to consider two different cases:

{\bf (1)} Suppose first that all of *\box255* has been used up, and that the
first box waiting to be placed
on the new current page
has height {\it h}.
This box
 will be preceded by interline glue {\it g}, since the page break
that created it broke right before the glue.  If
that box 
were the first thing to be placed on the new page,
 the  glue {\it g\/} would be irrelevant,
since \tex\ discards glue when the current page does not contain any
boxes ({\it The \tex book}, page~112); instead of this glue, \tex\ would
simply insert the glue determined by *\topskip*.
 But this glue will {\it not\/}
 be discarded if
continuation lines have already been added.

  We have stored the depth of the line
preceding this first box in\linebreak
 *\prevcoldepth@*; thus, the glue {\it
g\/} 
satisfies
\Math\hbox{*\prevcoldepth@*}+\hbox{\it g}+\hbox{\it h}
  =\hbox{*\baselineskip*}\endMath
But now we need new glue {\it g}$'$ such that
\Math
\hbox{*\prevdepth*}+\hbox{\it g}'+\hbox{\it h}=\hbox{*\baselineskip*}\endMath
So we need to add $\hbox{*\prevcoldepth@*}-
 \hbox{*\prevdepth*}$ glue; thus, when continuation lines are added,
we need to
**
\global\advance\prevcoldepth@ by -\prevdepth \kern\prevcoldepth@
**
(We can change *\prevcoldepth@* like this, instead of using the more
complicated code
**
"hskip-20pt\dimen@=\prevcoldepth@ \advance\dimen@ by -\prevdepth \kern\dimen@
**
because *\prevcoldepth@* won't be used any more.)

{\bf(2)} When *\box255* has not been used up, however, the situation is quite
different, since this *\box255* is what remains from a *\vsplit*,
so that the glue {\it g\/} is simply enough to make
\Math
\hbox{\it g}+\hbox{\it h}=\hbox{*\topskip*}
\endMath
We want glue {\it g}$'$ such that
\Math
\hbox{\it g}'+\hbox{\it h}+\hbox{*\prevdepth*}=\hbox{*\baselineskip*}
\endMath
so we need to add
\Math\hbox{*\baselineskip*}-\hbox{*\prevdepth*}-\hbox{*\topskip*}
\endMath
extra glue.  

Actually, in both cases {\bf(1)} and {\bf(2)}, *\baselineskip* should really
be\linebreak
$\hbox{*\baselineskip*}+\hbox{*\parskip*}$, though this
doesn't make any difference in the final result for {\bf(1)}.  

The whole definition is thus
\CC**
\def\continue@#1#2#3#4#5#6#7#8\continue@{%
 \def\next@{#1}\ifx\next@\empty
"2
 \else
  \noindent@#3 ({\it continued\/})\par
"2
  \ifnum#1>1 \noindent@\enspace(#4 {\it continued\/})\par\fi
"2
  \ifnum#1>2 \noindent@\enspace(#5 {\it continued\/})\par\fi
"2
  \ifnum#1>3 \noindent@\enspace(#6 {\it continued\/})\par\fi
"2
  \ifnum#1>4 \noindent@\enspace(#7 {\it continued\/})\par\fi
  \ifvoid 255
   \global\advance\prevcoldepth@ by -\prevdepth \kern\prevcoldepth@
  \else
   \skip@=\baselineskip \advance\skip@ by \parskip
   \advance\skip@ by -\prevdepth 
   \advance\skip@ by -\topskip
   \vskip\skip@
  \fi
 \fi}
**

\small If we had also 
wanted continuation lines at the top of right hand columns,
 *\doublecolumns@* would have to be more complicated:
\setbox0\hbox{\<the *\else* part of old *\doublecolumns@* routine\>}
\setbox1\hbox{\<set *\dimen@* as before\>}
\setbox2\hbox{\<corresponding part of old *\doublecolumns@* routine\>}
\setbox3\hbox{\<add continuation lines,}
\setbox4\hbox{\ \ \ adjusting space using *\leftcoldepth@*\>}
\setbox5\hbox{\ \ \ adjusting space using *\prevcoldepth@*\>}
**
\newif\ifleftcol@
\newdimen\leftcoldepth@
"slip
\def\doublecolumns@{"box1
 \ifleftcol@
  \global\leftcolfalse@
  \ifleftcolbreak@
   \global\leftcoldepth@=\dp255
    "box2
    "copy3
    "box4
"2
  \else
   {\splittopskip=\topskip \splitmaxdepth=\maxdepth
    \global\setbox1=\vsplit255 to\dimen@
    \global\prevcoldepth@=\dp1 }
    \box1 \allowbreak
    "copy3
    "box5
  \fi
"2
 \else
  \global\leftcol@true
  "box0
 \fi
 \global\Ctype@=0 }
**
  Thus, *\doublecolumns@* would
end up
being
 called twice for each page, even if there was no column break in the left
column. 
\endsmall




\section{\CS{balancecolumns\@}}
The *\balancecolumns@* routine basically
follows that of page~417 of {\it The \tex
book}, except that we have to be a little more careful about the final
glue (the routine in {\it The \tex\ book\/} was used for setting
{\it The \tex book}, where the balanced columns are then followed by
more material), and we also have to allow for a short last column.

We begin with
**
\setbox0=\vbox{\unvbox255 \unskip}
\dimen@=\ht0
**
using *\unskip* to completely eliminate *\vfill* that may have been
added by the *\bye* (this *\vfill* might not be there if the page break
actually occurs before the final line); this prevents the depth of *\box255*
from being counted in the height of *\box0*.

Now we basically want to divide *\dimen@* by 2, and split *\box0* into
two pieces of that height.  But we make a slight adjustment: 
When we split *\box0* into two pieces, the top line of the second piece,
which currently has *\baselineskip* glue before it, should only get
*\topskip* glue. So we use
**
\advance\dimen@ by \topskip
\advance\dimen@ by -\baselineskip
\divide\dimen@ by 2
**
---now *\dimen@* is the ideal height for the two pieces into which we
hope to split *\box0*.

Then we set
**
\splittopskip=\topskip
**
and use a *\loop* for splitting. This *\loop* will operate inside a group 
with *\vbadness=10000*, so that *Underfull \vbox*'es won't be reported
unless the columns are actually bad after the balancing act:
**
{\vbadness=10000
 \loop
 \global\setbox3=\copy 0
 \global\setbox1=\vsplit3 to\dimen@
 \ifdim\ht3 > \dimen@ \global\advance\dimen@ by 1pt
 \repeat}
**
Briefly, we try splitting to the ideal *\dimen@*, but if we can't get
two columns of the same height we want the left column to be the bigger;
so, if the right column turns out to be bigger, we keep increasing *\dimen@*
by 1~point until we get a split where the left column is at least as big as
the right column.
We always *\split* a copy of *\box0* rather than *\box0* itself, so that
*\box0* is always available for the next iteration of the *\loop*.

We used *\global\advance* here because we need to know the final value of
*\dimen@*.  But to keep assignments of *\dimen@* local, we will modify this
code to
**
\global\dimen@i=\dimen@
{\vbadness=10000
 \loop
 \global\setbox3=\copy 0
 \global\setbox1=\vsplit3 to\dimen@i
 \ifdim\ht3 > \dimen@ \global\advance\dimen@i by 1pt
 \repeat}
**
so that *\dimen@i* is the final dimension we are interested in.


Now we have to set each of 
*\box0* and *\box2*, which will be used by\linebreak *\combinecolumns@*,
to a *\vbox to\dimen@i* (at this point we may get an *Underfull \vbox* 
message):
**
\setbox0=\vbox to\dimen@i{\unvbox1}
\setbox2=\vbox to\dimen@i{\dimen@=\dp3 \unvbox3
 \ifshortlastcolumn@ \kern-\dimen@ \vfill\fi}
**
The second column, *\box2* is supplied with *\vfill* when we want
it to be short; as usual (compare page~\ref{KMPR} and~\ref{USEKMPR}),
 a 
 *\kern* is required before the *\vfill* to prevent the depth of
the box from being counted as part of the height, possibly producing
a spurious *Overfull* box.

The complete code is:
\CC**
\def\balancecolumns@{%
 \setbox0=\vbox{\unvbox255 \unskip}%
"2
 \dimen@=\ht0 \advance\dimen@ by \topskip
 \advance\dimen@ by -\baselineskip
 \divide\dimen@ by 2
"2
 \splittopskip=\topskip
 \global\dimen@i=\dimen@
"2
 {\vbadness=10000
  \loop 
"2
   \global\setbox3=\copy 0
   \global\setbox1=\vsplit 3 to\dimen@i
   \ifdim\ht3 > \dimen@i \global\advance\dimen@i by 1pt
  \repeat}%
"2
 \setbox0=\vbox to\dimen@i{\unvbox1}%
 \setbox2=\vbox to\dimen@i{\dimen@=\dp3 \unvbox3
  \ifshortlastcolumn@ \kern-\dimen@ \vfill\fi}%
 \combinecolumns@}
**

That completes all the routines from *lamstex.stb*, so we end, as in
*lamstex.tex* itself, with
\CC**
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
 \ch@ck#1#4#2\allocationnumber\count1#1
 \global#3#5\allocationnumber
 \wlog{\string#5\string#2\the\allocationnumber}}
\catcode`\@=\active
**

\small
Balancing an index can be problematical because of final letters with only a
few entries. \pagelabel{CBBAL}
 For example, an index might end
\bigskip
\setbox0\vbox{\hsize10pc
 \centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace 13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox1=\vbox to\ht0{\hsize10pc \advance\baselineskip 0pt plus2pt
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
}
\line{\hfil\box1 \kern1pc\box0 \hfil}
\bigskip
\noindent with the first column *Underfull*. 
This is the best *\vsplit*, for
if the left column were any
bigger  it would have
to include the {\bf Z} and the space after it, and at
least one more line  (not to mention all the extra space that would normally
go {\it before\/} the {\bf Z}).

  If we added a *\newcolumn* right before the *zebra* *\Entry*
in the *.xdx* file (and also specified *\shortlastcolumn*),
the output would look acceptable,
\bigskip
\setbox2\vtop{\hsize10pc
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox3=\vtop{\hsize=10pc
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
\vskip12pt
\centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
}
\line{\hfil\box3 \kern1pc\box2 \hfil}
\bigskip
\noindent
although we would get *Overfull \vbox* messages
(the *\newcolumn* causes the *\output* routine to be invoked
while we still have  *\output={\doublecolumns}*,  so the left column
will be made into a *\vbox to\pageheight@*).

If we added the *\newcolumn* before the
*\LETTER Z*
(and also had specified\linebreak *\shortlastcolumn*), we would get
\bigskip
\setbox0\vtop{\hsize10pc
 \centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox1=\vtop{\hsize=10pc
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
}
\line{\hfil\box1 \kern1pc\box0 \hfil}
\bigskip
\noindent (again with *Overfull \vbox*  messages). 


Of course, the most reasonable thing would probably be to add a
*\columnbreak* a little before the *yak* entry, so that the left column
on the final page would be a little longer.

\endsmall

\chapter The {\tt index} program\label{IPROG}\endchapter

The *index* program takes the raw data in an *.ndx* file and creates
an *.xdx* file. Specifically, it is invoked as
\setbox0\hbox{\<filename\>}
**
index "box0
**
to operate on \<filename\>*.ndx*, producing \<filename\>*.xdx*.
Among its many tasks, the *index* file essentially sorts entries
alphabetically.  As indicated below, the *"1a{*\<string\>*}*
 option is used to indicate
that for purposes of alphabetizing, the entry should be treated as if it were
 \<string\>.  


The *index* program
was originally written in Microsoft~C, for MS-DOS machines. Porting to other
machines will presumably be done by modifying this code.  However, this
chapter presents the complete specifications for the *index* program, in case
any one wants to write it from scratch.


It should be pointed out that currently
the alphabetizing part of the program is essentially set up for
English spelling, with the presumption that ``foreign''
words  (e.g.,  those with accented letters)
 will be given an *"1a{*\<string\>*}* option.  There should obviously
be versions (or perhaps switches)
for other languages  that will provide
transparent alphabetizing for words in those languages, so that the *"1a*
option will only be needed for words that are ``foreign'' to those languages.

It might also
be mentioned that the current version of the program specifically
assumes that the final line ends with a \<carriage-return\>, which should be
true of the *.ndx* files that \tex\ writes.  Some systems might want to
modify this assumption.

\def\controlseq{\hbox{\rm\<control sequence\>}}

\section{The {\tt.ndx} file}
The *.ndx* file may contain certain lines
**
\define"controlseq . . .
**
that come from  *\idefine*'s in the main file, as well as certain lines
**
\abbrev"1"controlseq{...}
**
that come from *\iabbrev*'s in the main file.  Moreover, as explained on
page~113 of the \lamstex~Manual, a sequence of commands of the form
\setbox0\hbox{\<pre page material\>}
\setbox1\hbox{\<post page material\>}
\setbox2\hbox{\<order\>}
**
"hskip-40pt\pageorder"controlseq{"box0}{"box1}{"box2}
**
may have been inserted
at the very beginning of the
*.ndx* file (after the *.ndx* file was automatically made by \tex); 
here each \controlseq\ is some
 numbering style command, and the \<order\>'s are
*1*, *2*, *3*, \dots, in that sequence. 


Aside from this, the *.ndx* file
should consist of pairs of lines
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\controlseq*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
"""box0"box1""
{"box2}{"controlseq}{"box4}{"box5}
**
where \<number\> is a decimal number, \controlseq\ is some numbering
style
control sequence
 (followed by a space, because \tex\ will always add the
space when it writes to the *.ndx* file),
 and \<prefix\> and \<postfix\> are arbitrary, possibly
empty, strings. The \controlseq\ is normally `*\arabic" *'.

Actually, the *index* program as currently written does not  assume
that *""* is the delimiter
appearing at the beginning and end of the \<entry\> lines.  It is
perfectly legitimate (compare section~\Sref{OTHERD})
to have something like
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\controlseq*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
<"box0"box1>
{"box2}{"controlseq}{"box4}{"box5}
**
Any left delimiter other than *{* or *\* may be used;
the *index* program takes the \<entry\>\<option\>
combination to be everything between the first
symbol and  the last non-space symbol on the line.


Each \<entry\> has one of the forms
\setbox1\hbox{\<entry\>$_{\text1}$}
\setbox2\hbox{\<entry\>$_{\text2}$}
\setbox3\hbox{\<entry\>$_{\text3}$}
\setbox4\hbox{\<entry\>$_{\text4}$}
\setbox5\hbox{\<entry\>$_{\text5}$}
**
"copy1
"copy1, "copy2
"copy1, "copy2, "copy3
"copy1, "copy2, "copy3, "copy4
"copy1, "copy2, "copy3, "copy4, "copy5
**

The \<options\> are a possibly empty sequence of
 the following types of entries, where \<n\>
stands for *2*, *3*, *4* or *5*. Actually, *1* is also allowed, but simply
treated as if the *1* weren't there.
There are optional spaces between such
entries, including an optional space at the beginning and end of the
\<options\>:
\Math
\vcenter{\halign{#\hfil&\qquad#\hfil\cr
 *"1a{*\<string\>*}*&(alphabetize as)\cr
 *"1*\<*n*\>*a{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
 *"1-{*\<string\>*}*&(print before entry)\cr
 *"1*\<*n*\>*-{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
 *"1+{*\<string\>*}*&(print after entry)\cr
 *"1*\<*n*\>*+{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
 *"1e*\<control sequence\>&(apply control sequence to entry)\cr
 *"1*\<*n*\>*e*\<control sequence\>&(same for subentry at level \<*n*\>)\cr
 *"1p*\<control sequence\>&(apply control sequence to page number)\cr
 *"1f*&(begin page span)\cr
 *"1F*&(begin page span, variant form)\cr
 *"1t*&(end page span)\cr
 *"1x{*\<string\>*}*&(cross reference as)\cr
 *"1X{*\<string\>*}*&(list and cross reference as)\cr}}
\endMath

In each
**
\abbrev"1"controlseq{...}
**
line, the `*...*' string should also be a sequence of these possible options,
and error messages should be given if it is not, or if *\abbrev* is otherwise
used incorrectly.

The *"1x* and *"1X* options are meant to be mutually exclusive, so an error
message should be given if both occur in the same \<options\> list.



\section{The {\tt index} program}
Here now are the steps taken by the *index* program.

\medskip

\noindent({\bf I}) {\bf Preprocessing:}

\smallskip

(1) The *index* program first uses any *\pageorder* lines at the beginning,
\setbox1\hbox{$_{\text1}$}
\setbox2\hbox{$_{\text2}$}
\setbox3\hbox{pre\copy1}
\setbox4\hbox{post\copy1}
\setbox5\hbox{pre\copy2}
\setbox6\hbox{post\copy2}
**
\pageorder"controlseq"copy1{"copy3}{"copy4}1
\pageorder"controlseq"copy2{"copy5}{"copy6}2
 . . .
**
to 
set up an ordering for  arrays of the form
\setbox2\hbox{\<number\>}
\setbox3\hbox{\<controlseq\>}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
{"box2}  {"controlseq}  {"box4}  {"box5}
**
Namely, all arrays
\setbox1\hbox{$_{\text1}$}
\setbox2\hbox{$_{\text2}$}
\setbox3\hbox{pre\copy1}
\setbox4\hbox{post\copy1}
\setbox5\hbox{pre\copy2}
\setbox6\hbox{post\copy2}
\setbox7\hbox{\<number\>}
**
{"copy7}{"controlseq"copy1}{"copy3}{"copy4}
**
come first, with the ordering then determined by the \<number\>'s,
all arrays
**
{"copy7}  {"controlseq"copy2}  {"copy5}  {"copy6}
**
come next, \dots. All other arrays come after these, and are simply ordered
first by the order of the \<number\>, and then purely alphabetically by
the remaining fields.
 
Error messages presumably 
ought to be given if any *\pageorder* line has the wrong
form, if the \<order\>'s don't occur in the proper order, or if two different
\<order\>'s are assigned to identical material.

(2) Next we consider all lines
**
\abbrev"1"controlseq{...}
**
(which may appear anywhere in the *.ndx* file). 

In each case, any
occurrence of *"1"controlseq* in any entry line is replaced by
`*...*'; then the *\abbrev* lines are eliminated.


(3) All *\define* lines anywhere in the *.ndx* file are stored
in a safe place, before being removed; they will be written at the beginning
of the *.xdx* file.

\medskip

\noindent({\bf II}) {\bf Sorting:}

\medskip

\def\1{$_{\text1}$}\def\5{$_{\text2}$}
\def\3{$_{\text3}$}\def\4{$_{\text4}$}\def\5{$_{\text5}$}
\def\n{$_{\text\it n}$}

\def\entrybar{$\overline{\hbox{\rm entry}}$}


(1) For each
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
**
"""box0"box1""
**
line,
if *"1a{*\<string\>*}* appears, replace \<entry\1\> by \<string\>,
and define \<\entrybar\1\> to be the old \<entry\1\>.
 Otherwise define
\<\entrybar\1\> to be empty.

Similarly, if
*"1*\<*n*\>*a{*\<string\>*}* appears, replace \<entry\n\> by \<string\>,
and define \<\entrybar\n\> to be the old
 \<entry\n\>. Otherwise define \<\entrybar\n\> 
to be empty.



\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\nstyle*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}

\smallskip

(2) Each pair of lines
**
"""box0"box1""
{"box2}{"controlseq}{"box4}{"box5}
**
now gives rise to a collection $\Cal F$ of fields:

*E1* is \<entry\1\> followed by one space.

*E1+* is empty unless *"1-{*\<string\>*}* appears, in which case it is
\<string\> followed by one space (note that
\<string\> may already have one space at
the end).

*E1-* is empty unless *"1+{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.

*E2* is \<entry\5\> followed by one space (hence just a space if
\<entry\5\> is empty).

*E2-* is empty unless *"12-{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.

*E2+* is empty unless *"12+{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.

*E3*, *E3+*, *E3-*, \dots, *E5*, *E5+*, *E5-* are similar.

*P#* is \<number\>.

*Pn* is \controlseq\ (usually `*\arabic" *').

*P-* is the \<prefix\>.

*P+* is the \<postfix\>.

\def\EE{$\overline{\hbox{\tt E}}$}

*"EE1*, \dots, *"EE5* are  \<\entrybar\1\>, \dots, \<\entrybar\5\>.

*E1c* is empty unless *"1e*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.

*E2c* is empty unless *"12e*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.

*E3c*, *E4c*, *E5c* are similar, using *"13e*, *"14e* and *"15e*.

*Pc* is empty unless *"1p*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.

*PT* (page type) is *f* if *"1f* appeared, *F* if *"1F* appeared, *t*
if *"1t* appeared, and *s* (for single page) otherwise.

*x* is empty unless *"1x{*\<string\>*}* appears, in which case it is
\<string\>, followed by one space.

*X* is empty unless *"1X{*\<string\>*}* appears, in which case it is
\<string\>, followed by one space.


\medskip
(3)
We first sort these collections $\Cal F$
alphabetically on *E1*, then  among those with
identical *E1* on  *E1-*, then on *E1+*, then on *E2*, \dots, *E5+*.
If we ignore the *-* and *+* fields for the moment,
this just alphabetizes the entries and subentries.
  The spaces that were added after each
\<entry\n\> are meant to ensure that these entries are really sorted
alphabetically; for example, it produces the order
**
Time
Time table
Time tables
Times
Times tables
**
which will eventually appear in the index as
\bigskip\begingroup\parindent0pt\parskip0pt
\hskip30pt Time\par\nobreak
\hskip30pt \hskip10pt table\par\nobreak
\hskip30pt \hskip10pt tables\par\nobreak
\hskip30pt Times\par\nobreak
\hskip30pt \hskip10pt tables\par\nobreak
\endgroup\bigskip


The other fields, *E1-*, *E1+*, \dots,  allow entries with
additional elements to appear in the proper order.  For example, for the entry
**
""Time "1-{``} "1+{''}""
**
*E1* is *Time* and *E1-* is *``*. This
will come after the entry line
**
""Time"" 
**
where *E1* is also *Time* but *E1-* is empty,
 so that we will obtain the order
\bigskip\begingroup\parindent0pt\parskip0pt
\hskip30pt Time\par\nobreak
\hskip30pt ``Time''\par
\endgroup\bigskip
\noindent in the  index.


After using these fields for sorting, we next use the fields
**
P#  Pn  P-  P+  
**
where 
 the sorting order for these arrays
is just that described in step (1) of ({\bf I}).

There may be certain collections $\Cal F$ that are distinct, but agree for
all the fields so far.  They can be left in any order, say the order in which
they appear in the *.ndx* file, or further sorted purely alphabetically
according to the remaining fields *"EE1*, \dots, *"EE5*, *E1c*, \dots,
*E5c* and *Pc*.

The *PT*, *x* and *X* 
 fields are important for further processing, but need not be
considered in the sorting.

After the sorting is completed, the additional spaces added to various fields
are no longer needed, and they are deleted in the next step.

\medskip


\noindent ({\bf III}) {\bf Writing the *.xdx* file:}
\medskip

(1) First, as indicated in step (3) of part ({\bf I}), all *\define* lines
originally in the *.ndx* file are written to the *.xdx* file.

(2) The remaining material in the *.xdx* file will be in sections, each
preceded by a blank line, then  a line
**
\LETTER ...
**
and then another blank line.
The line
**
\LETTER A
**
will normally be the first of these, and will precede all entries that begin
with *a* or *A*;
**
\LETTER B
**
will precede all entries that begin with *b* or *B*; etc.  No such line 
appears for a letter if there are no entries beginning with this
letter.  Things like \hbox{*\LETTER !*} can appear if entries begin with
~ *!* (though normally one would expect the *"1a* option to be used for such
entries). 



(2) In most cases,
each collection $\Cal F$ gives rise to a pair of lines in the *.xdx*
file:
\def\di{{\it d}$_{\text1}$}
\def\dii{{\it d}$_{\text2}$}
**
\Entry  "di"dii{...}{...}{...}{...}{...}
\Page {...}
**
except that if several collections have the exact same *\Entry* line, then
the corresponding *\Page* lines are  listed under it in order, with
modifications to be mentioned in a minute, involving
the  *PT*, *x* and *X* fields.

For the first *{...}* in the *\Entry* line, `*...*' is
\def\F#1.{\hbox{\rm\<field #1\>}}
**
{E1-}{E1c{E1}}{E1+}
**
except that *E1* is replaced by *"EE1* 
if this is non-empty.

Note that there are braces around *E1* (or *"EE1*)
so that it will be the 
argument of the control sequence *E1c*. However, these braces are 
omitted if *E1c* is empty.  Moreover, 
all other unnecessary
braces are omitted: the first set of braces is omitted if *E1-* is
empty, the third set is omitted if *E1+* is empty, and the middle set is
also omitted if both are empty.
 (Remember that this entire sequence, with
extraneous braces removed, is enclosed in the first set of braces in the 
*\Entry* line.)

The second *{...}* in the *\Entry* line is similar, using fields 
*E2-*, *E2c*, *E2* and *E2+*. And similarly for the other groups.


\di\ is the number of *{...}* that are non-empty, i.e., not of the form
*{}*. 

\dii\ is the number of *{...}* {\it that agree with the most recent *\Entry*
line}. 

\medskip


Normally,
the *\Page* lines have the form
\def\FF{$\overline{\hbox{\rm\<field 17\>}}$}
**
\Page {Pc{{P-}{Pn{P#}}{P+}}}
**
But  *Pn* is omitted when it is `*\arabic" *' (the usual case).
  Moreover, superfluous braces are removed, as before, when
fields are empty.

Duplicate *\Page* lines for the same entry are eliminated.  But if 
duplicates actually come from lines for which *Pc* is different, then
each  *\Page* line after the first is printed as
{\advance\litindent-60pt
**
%% ////////////////////////////////////////////////////////////////////////
%
% \Page {Pc}{...}}
% Duplicate page number formatted differently
%
%% \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
**
where *Pc* is the control sequence for that line. For readability,
there should be
a blank line before and after this ``error message''
(the current version of the *index*
program actually prints things slightly differently).}


When *PT* is *f*, however, *\Page* is replaced by *\Pagespan*. And
if *PT* is *F*, then *\Page* is replaced by *\PageSpan*; moreover, the
line is then written in the form
**
\PageSpan {Pc}{{P-}{Pn{P#}}{P+}}
**
with the *Pc* as a separate argument.
 Extraneous braces are removed, as usual.

When *PT* is *t*, *\Page* is replaced by *\Topage*.  However, if it was
preceded by a line for which *PT* is *F*, then once again we write
**
\Topage {Pc}{{P-}{Pn{P#}}{P+}}
**
with the *Pc* as a separate argument.

When a *\Page* line for which *PT* is *s* is encountered between lines
for which *PT* is *f* or *F* and the corresponding line for which *PT* is
*t*, it is ignored, {\it unless it has\/} a different *Pc*.  In this case
the new *\Page* line is printed as the error message
{\advance\litindent-60pt
\setbox0\hbox{new}
\setbox1\hbox{old}
**
%% ////////////////////////////////////////////////////////////////////////
%
% \Page {"copy0 Pc{...}}
% Page {"copy0 Pc{...}} within span starting at "copy1 Pc{...}
%
%% \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
**

Other such error} messages that should be issued
are indicated on pages 118@--119 of the \lamstex~ Manual.


\bigskip
This description is complete only 
for entries that do not have an *"1x* or *"1X* option.  For entries that do
have these options, the processing is somewhat different.
Recall that 
*"1x* indicates a cross-reference without a reference to the page on
which the entry is marked, while *"1X* indicates a cross-reference together
with a reference to the page. 

The situation where at least one occurrence of \<entry\> has an *"1x* or
*"1X* option can happen in different ways:

\medskip

\noindent Case 1: Every occurrence of the \<entry\> involves *"1x* (and thus
 not
 *"1X*):
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<string\1\>}
\setbox2\hbox{\<string\5\>}
\setbox3\hbox{\<string\3\>}
**
"copy0 ... "1x{"copy1}
"copy0 ... "1x{"copy2}
"copy0 ... "1x{"copy3}
**
In this case the *.xdx* file 
should contain
**
\Entryxref "di"dii{...}{...}{...}{...}{...}{\See {"copy1}}
\Morexref {\See {"copy2}}
 . . .
**

\medskip

\noindent Case 2: The opposite case, in which at least one of the following
occurs: 

(1) \<entry\> occurs at least once with the *"1X* option, so that the
corresponding page number should appear.  Other occurrences of \<entry\>
 may or may not have
*"1x* options.

(2) \<entry\> occurs at least once with {\it neither\/} *"1x* nor *"1X*, and
thus there is at least one page number that should appear because no
cross-referencing is involved at all. Other occurrences of \<entry\> may have
either  *"1x* or *"1X* options.

\smallskip
In these cases, 
let \<string\1\>, \<string\5\>, \dots, be all the \<string\>'s, in
alphabetical order,  that
occur in either *"1x* or *"1X* options, and
let 
**
\Page {...}
\Page {...}
 . . .
\Page {...}
**
be the lines that would be written considering all instances that do not
involve the *"1x* option (but possibly the *"1X* option). These lines
may actually involve  *\Pagespan*, *\PageSpan* and *\Topage*.


Then the *.xdx* file should contain
\setbox1\hbox{\<string\1\>}
\setbox2\hbox{\<string\5\>}

**
\Entry "di"dii{...}{...}{...}{...}{...}
\Xref {\See {"copy1}}
\Morexref {\See {"copy2}}
 . . .
\Page {...}
\Page {...}
 . . . 
\Page {...}
\Xref {\See {"copy1}}
\Morexref {\See {"copy2}}
 . . .
**




