The

LazS-TrX

Wizard's Manual

Copyrighit (c) 1991 by Michael Spivak

All Rights ReservedA note on the

Laws-TEX's 'Wizard's Manual

At present the Wizard's Manual is available only in this form, laboriously printed on a laser printer: The manual was divided into several sections, and for each section two.dvi files were produced, one for : :inting the odd-numbered pages, one for the even-numbered pages.

As a result of this procedure, which was carried out fairly hastily, several anomalies may occur, like running heads o: otherwise blank pages, or two footnotes on a page both numbered 1: these anomalies are artifacts that do not occur when the file is handled normally.

In the unlikely event that there is sufficient interest in this Wizard's Manual to warrant publication as a book, a special rate will be given to those who have ordered the manual in its current form.

Meanwhile, updates will be issued as bugs are discovered and corrected, or as new features are added.

The idea of making an index is toc horrible to contemplate--many, many entries would probably have dozens of citations. However, when the manual seems to have reached a stable state I will provide a "source" code. This will not be a.tex file, but a sort of ASCII representation: of the book, so that one can use a text editor to search for anything.

Meanwhile, of course, please report any misprints, mistakes, omissions, bugs, etc., either by mail,

TEXplorators

370: W. Alabama, Suite 450-273

Hcuston, 'X, 77127 (U.S.A.)

or by e-mail,

spivak@rice.edu


**ii**

**Chapter 8. Special considerations for** **everypar**

**Chapter 9.** **page**

**Chapter 10. Indexing**

10.1 The.ndx file

10.2 Undergproofing

10.3 Converting tokens to type 12

10.4 The **stargparts@** and **windex@** routines

10.5 Indexing

10.6 Changes to the **law@**-**Tex** Manual

10.7 Invisibility

10.8 Other delimiters for index entries

10.9 \(\backslash\)**idefine and **liabbrev**

**Part II** **Labels and Cross References**

**Chapter 11. The** **label mechanism**

69

11.1 Constructions that can be given (label)'s

69

11.2 Restrictions

71

11.3 Consequences of these restrictions

71

11.4 \(\backslash\)**Initialize**

72

11.5 The question of fonts

73

11.6 Storing \(\backslash\)**(label)'s**

74

11.7 \(\backslash\)**ref and its relatives

76

11.8 \(\backslash\)**label**

76

11.9 \(\backslash\)**pagelabel**

77

**Chapter 12. Beginning the document**

80

12.1 Preliminaries

80

12.2 \(\backslash\)**document**

81


iv

###### Contents

* 18.6 \runinitem@
* 18.7 \inlevel
* 18.8 \outlevel
* 18.9 \endlist
* Chapter 19. \describe and \margins
* 19.1 \describe
* 19.2 \margins
* Chapter 20. \nopunct, \nospace, and \overlong
* 20.1 \nopunct, \nospace, and \overlong
* 20.2 \sing the flags
* Chapter 21. \demo
* Chapter 22. \claim's
* 22.1 Preliminaries
* 22.2 \claimformat@
* 22.3 Further preliminaries
* 22.4 Starting a \claim
* 22.5 Starting a \claim@c
* 22.6 Starting a \claim@q
* 22.7 Finishing off
* 22.8 \endclaim
* 22.9 \newclaim
* 22.10 \shortenclaim
* 22.11 Customizing \claim's
* Chapter 23. Heading levels
* 23.1 The.toc file
* 23.2 Preliminaries
* 23.3 Different levels of \HL
* 23.4 The \HL construction
* 23.5 The \hl construction
* 23.6 Other elements of heading levels
* 23.7 Writing long token lists

#### Part IV Miscellaneous Constructions

**Chapter 26. Literal mode** 261

26.1 In-line literal mode 261

26.2 Displayed literal mode 264

26.3 Notes for the wary 266

26.4 Prohibiting page breaks 267

26.5 Indentation 268

26.6 TAB's 268

26.7 Widow control 270

26.8 Page breaks 272

26.9 Litbox 274

26.10 The general definition 275

26.11 Nicer syntax 281

**Chapter 27. Literal mode in heading levels**
288
27.1 Literal mode in NHL and hl1
289
27.2 The general definitions
294

**Chapter 28. Title, author, etc., in the default style**
298

**Chapter 29. The bibliography**
301
29.1 \cite
302
29.2 Features of IAAS-TEX's bibliography macros
303
29.3 Storing the fields
313
29.4 Starting the bibliography macros
315
29.5 \bibinfo@
318
29.6 Additional flags
320
29.7 \bib
321
29.8 The basic construction
323
29.9 \no,\key, \
325
29.10 Manipulating the vbox'cs
328
29.11 Line breaking commands
329
29.12 Adding punctuation before a field
332
29.13 \endbib@
334
29.14 \endbib,\morebib,\anotherbib, and\transl
341

**Chapter 30. Interfacing with BIBITEX**
345
30.1 \UseBibTeX
346
30.2 The bibtex.tex file
351

**Chapter 31.**purge'ing and\unpurge'ing**
358

_Part V Islands and the Output Routine_

**Chapter 32. Packaging figures, tables,, with captions**
363
32.1 Preliminaries
363
32.2 Starting an\island
366


**viii**

**Chapter 36. The \output routine: Ta-ran-ta-ral Ta-ran-ta-ral Ta-ran-ta-ral**

**36.1** \plainoutput

**36.2** \pagebody

**36.3** \pagecontents

**36.4** And we are done!

**36.5** When \box255 is too small

**36.6** The endgame

**36.7** The endgame once again

**36.8** The endgame once again

**36.9** The endgame once again

**36.10** The endgame once again

**36.11** The endgame once again

**36.12** The endgame once again

**36.13** A final warning

_Part VI Front and Back Matter_

**Chapter 37. Front Matter (Table of Contents, List of Figures,**

Tables, etc.)**

\begin{tabular}{l l l}
37.1 & lamster.stf preliminaries & 471 \\
37.2 & Setting an entry & 472 \\
37.3 & Further preliminaries for the table of contents & 477 \\
37.4 & Starting the \makettoc command & 479 \\
37.5 & Redefining \HL and \h1 & 480 \\
37.6 & \WamenHL and \Wamehl & 483 \\
37.7 & \makettoc & 484 \\
37.8 & Lists of Figures, Tables, etc. & 485 \\
37.9 & Fini & 490 \\
**Chapter 38. Back matter; the index** & 491 \\
38.1 & Preliminaries & 491 \\
38.2 & \LETTER and \Entry & 495 \\
38.3 & \Page, etc. & 502 \\ \end{tabular}



_Part 1_

_Preliminaries_* [15]

## Chapter 1 Introduction

This manual is intended for TeX wizards pondering the intricacies of various \(\mss\)-TeX constructions, as well as for TeXnicians designing style files for \(\mss\)-TeX who need more detailed information than that provided by the \(\mss\)-TeX Style File Designers Manual. Although certain points about TeX receive detailed explanation, many sections presuppose considerable TeXpertise, which it would be impractical to try to provide within the scope of this already lengthy manual.

Despite the manual's lengthiness, the division into chapters and sections allows specialized constructions used for one part of \(\mss\)-TeX to be separated from those used in other parts. Of course, the various chapters are not completely independent, and Part I should probably be perused by everyone.

### 1.1 \(\mss\)-TeX Conventions

We will not be analyzing the file amstex.tex itself, since a detailed description of \(\mss\)-TeX is given in the file amstex.doc. Nevertheless, certain \(\mss\)-TeX conventions must be mentioned here, because they are used throughout lamstex.tex.

First of all, \(\mss\)-TeX uses the "scratch" tokens next, \next@, \nextii@,... In order to keep the number down, many definitions will, for example, define \nextiw@ back in terms of \next@, \nexti@, etc.

The amstex.doc file mentions the peculiar contortions that are used to avoid difficulties that might arise when a definition has a clause like

\def\next@{... \next... } since a previous \futurelet\next may have let \next be something that is \outer.

In \(\mss\)-TeX, on the other hand, it is simply quite out of the question to allow anything to be \outer. Something like \claim can't be outer, for example, because then things like \newpre\claim wouldn't work. But even something like \bye can't be \outer because it might easily occur right after a point where \(\mss\)-TeX has to subject the next token to some sort of test (see the small print notes on pages 100 and 146). Consequently, although we will continue to reserve \next as the token of choice in all \futurelet constructions, we will finesse this whole problem by making sure that _nothing_ in \(\mss\)-TeX is \outer.



that occur later (compare _The TeXbook_, pp. 382-383).

Testing \amstexloaded@ also allows other macro packages to tell whether amstex.tex has already been loaded, which is important for \(\mss\)-TeX, as we will see in the next chapter.

\(\mss\)-TeX also introduces two new counters, and a new token list,

\newcount\count@@ \newcount\count@@@ \toksdef\toks@@@=2 in addition to the counter \count@ and token list \toks@ provided by plain.tex; these are also used in \(\mss\)-TeX (see section 3 for the choice of 2 in the \toksdef).

Furthermore, \(\mss\)-TeX introduces the abbreviations

\def\FN@{\futurelet\next} \def\DN@{\def\next@} \def\DNii@{\def\nextii@} \def\WRITE@{\relax}ifmmode} \def\RIfMIfI@{\relax}ifmmode} \def\setboxzz@h{\setbox\z@\hbox} \def\wdz@{\wdz@\} \def\{\boxzz@\{\box\}}

These are used throughout \(\mss\)-TeX also. When we show lamstex.tex code, however, we will usually expand out these definitions, to make things easier to read. Similarly, certain control sequences from plain, like \z@, \p@, etc., will usually be expanded out for the sake of readability. Moreover, in constructions like

\count@=... \let\next@=\relax and so forth, we will often add the optional = signs that are normally omitted in the code.

We will frequently use the \(\mss\)-TeX control sequence \eat@ defined by

\def\eat@#1{}


have been inserted, so that 'height', 'width' and 'depth' can be replaced by the corresponding single tokens in the specifications for various \hrules and \vrules; these replacements save even more memory space in lamstex.tex, where rules occur much more frequently.

Finally, I have now conscientiously adhered to _The TeXbook_'s recommendations (see pages 301 and 346) that assignments of variables either always be global or always be local. In most cases, the necessary changes have been minor (like changing some \xdef's to \odef's, or vice versa), but somewhat more extensive changes were required to ensure that \setbox_n_ is always local for \(n\) even and global for \(n\) odd; these changes occur in the definitions of \insplit@, \randsplit@, \length\impl@, \lmultline@@@, \rmultline@@@@, \binrel@, \sideset@, \r@@@t, \pmb@@, and perhaps one or two other places.

We will exercise comparable care regarding assignments of variables throughout \LANS-TEX.

## Chapter 2 Getting started with \(\mathcal{U}\mathcal{U}\mathcal{S}\)-TeX

The first thing in lamstex.tex, after the copyright notice, is

\catcode^\@=11

to make @ a letter, in order to create "private" control sequences that the casual user cannot type, as well as to access such private control sequences from plain.tex and amstexl.tex.

We will always adhere to the convention introduced here, using horizontal lines when we print actual lamstex.tex code, as opposed to examples, pieces of code, etc. We will often use different line breaks from the actual lamstex.tex code, so that it will fit better on these printed pages. (It should also be noted that when we give preliminary pieces of code we will often omit % signs at the ends of lines, although they are meticulously added when needed in the code itself.)

Since \(\mathcal{U}\mathcal{S}\)-TeX is not supposed to be loaded unless \(\mathcal{U}\mathcal{U}\mathcal{S}\)-TeX has already been loaded, the next code,

\ifx\amstexloaded@\relax\else \errmessage\amstex\be loaded before Lam5-TeX\fi

produces an error message if it hasn't--see the discussion of the code (A) on page 5.

We will adopt a different scheme for preventing lamstex.tex from being read in twice, one that doesn't create a new control sequence name, by using the fact that lamstex.tex will eventually define the control sequence \laxread@ (see page 80), while \(\mathcal{U}\mathcal{S}\)-TeX makes certain that \undefined is always undefined (see amstex.doc):

\ifx\laxread@\undefined\else\catcode^\@=\active\endinput\fi

[Other macro packages that need to know whether or not \(\mathcal{U}\mathcal{U}\mathcal{S}\)-TeX has been loaded can use a similar test, or, if the status of \undefined isn't clear, they can use the test

\expandafter\ifx\csname\laxread@\endcsname\relax



## Chapter 3 Changes to \(\mathcal{M}\mathcal{S}\)-TeX

The next part of \(\mathcal{M}\mathcal{S}\)-TeX contains various changes to \(\mathcal{M}\mathcal{S}\)-TeX. Some of the changes should, and probably eventually will, be made in \(\mathcal{M}\mathcal{S}\)-TeX, though they didn't get included in \(\mathcal{M}\mathcal{S}\)-TeX version 2, while other changes are relevant only for \(\mathcal{M}\mathcal{S}\)-TeX. (Further changes to \(\mathcal{M}\mathcal{S}\)-TeX will be made later, at the relevant points.)

### \Err@. \(\mathcal{M}\mathcal{S}\)-TeX's definition of \Err@,

\def\Err@#1{\errhelp}defaulthelp@\errmessage{AmS-TeX error: #1}}

has been deleted in amstexl.tex, because it can obviously be shortened to

\def\Err@#1{\errhelp}defaulthelp@\err@{#1}}

(\mathcal{M}\mathcal{S}\)-TeX's original mechanism for defining the active @ character can be improved considerably.

First of all, we want the active @ to mean

\futurelet\next\at@

the problem being that we need to make this definition while @ is active

\catcode'\@=\active

\def\{...}

even though we want to allow @ as part of the control sequence name \at@.

Now we can easily name \at@ even when @ is active, as

\csname at\string@\endcsname

Of course, we can't simply say

\def@{\futurelet\next\csname at\string@\endcsname}

since @ would then simply \let\next=a--we need to have the combination \csname...\endcsname expanded out before the \futurelet\next takes effect.

We could do this with

\def@{\def\next{\futurelet\next}\expandafter\next

\csname at\string@\endcsname}

but that's somewhat unsatisfactory, since it requires the active @ to make a subsidiary definition each time it is used.

Another possibility is to use the triple \expandafter trick (see _The TeXbook_, page 374), which we will be using later on. But for the present problem the simplest strategy is to use the code

\edef\next{\gdef\noexpand@{\futurelet\noexpand\next}

\csname at\string@\endcsname}

next

Here the \edef makes \next mean

\gdef\@{\futurelet\next}\nat@}

where the boxed control sequences are not expanded out either because they are primitives or because they are preceded by \noexpand; the \csname... \endcsname_is_ expanded out in the \edef, but the control sequence \at@ that it expands to is made equal to \relax, since \at@ hasn't been defined previously--so \at@ isn't expanded further in the \edef. (Here we are using the fact that \lastex.tex won't be read in twice [Chapter 2].)

Consequently, when we then call \next we get this \gdef. Thus, to get the desired definition of the active @ we just need

\catcode'\@=\active \edef\next{\gdef\noexpand@{\futurelet\noexpand\next}

\csname at\string@\endcsname} \next \The definition of \at@ itself is now easy, with @ back as a letter. We will call the very same routine, \at@, when the next token is a letter, other character, or control sequence (or active character); for any other type of token we will call \at@@, which will be an error message:

\def\at@{% \ifcat\noexpand\next a\let\next@=\at@@\else \ifcat\noexpand\next@\let\next@=\at@@\else \let\next@=\at@@@@\if\if\next@\} The error message \at@@@ is simply

\def\at@@@{\errhelp\athelp@\err@{Invalid use of @}} using the help message \athelp@ from \(\mathcal{A}\)\(\mathcal{N}\)\(\mathcal{S}\)-TEX.

On the other hand, \at@@ \token\ will simply be the control sequence

\(\langle\)token\(\rangle\)at' if it has been defined, or an error message otherwise. Here we put quotes around \token\@at to emphasize that it is a single control word, even when (token) isn't a letter; in practice, of course, such control words have to be constructed using \csname...\endcsname:

\def\at@@#1{\expandafter \ifx\csname\string\#1@at\endcsname\relax \let\next@=\at@@@@ \else \def\next@{\csname\string\#1@at\endcsname}% \fi \next@} Note that we use \string#1 so that the token #1 can be a control sequence or active character, as well as a letter or other character.

Finally, \atdef@, the mechanism for defining the value of the active @ on various tokens, is the same as in \(\mathcal{A}\)\(\mathcal{N}\)\(\mathcal{S}\)-TEX, except that we add a \string:
### 3.3. Tests

There are two noteworthy things about this redefinition:

1. The original definition of \atdef@ remains in amstexl.tex, because it is used for \atdef@:{...} \atdef@:{...} \atdef@:{...} \atdef@?{...} \atdef@.{...} \atdef@-{...} These \atdef@'s give the same results as the new \atdef@ would give, since for these characters the \string is simply redundant--once @ is active, @; and @: and so forth will work just as before. (The \atdef@@\vert is irrelevant: it is deleted in amstexl.tex, and not used in \at\$-TEX.)
2. Later in \at\$-TEX we are going to make " active. Nevertheless, \at\$-TEX's \atdef@" will still make the combination \@" work correctly, because \string" for " active gives the same result as \at\$-TEX's " when " is not active. Actually, we are going to give a new \atdef@" (section 8), but that will be done before " is made active, so the same principle still applies.

3. Tests. \at\$-TEX has the flag \ifin@, which is set only by the routine \in@, a test to determine whether a particular token appears in any sequence; this test, in turn, is used only by the routine \tagin@ to check for the presence of \tag in a sequence. \at\$-TEX has numerous tests that are always performed independently, so it is economical to have a single flag that will be used by all of them; this flag will also replace \ifin@ from \at\$-TEX. So amstexl.tex deletes the line

\newif\ifin@


is replaced by

\err@{\noexpand\define must be... } The next occurs in the definition

\define@@#1

which takes a control sequence #1 as its argument, where, for example

(A) \err@{\string#1 is already defined}

is changed to

\err@{\noexpand@\is already defined}

with no space before the 'is', since it will appear when the error message is given. [amstex.tex actually has

\err@{\string#1\space is already defined}

which is unnecessary complicated, though it has the same number of tokens as (A).]

Similar replacements are made in the definitions of

\vmdoeerr@#1 \mathmodeerr@#1 \matherr@#1 \nondmatherr@#1 \nondmatherr@#1 \nondmatherr@#1 \nnonvmdoeerr@#1 \textonlyfont@#1#2

Finally, in the definition of \boldkey (which is actually redefined in lamstex.tex--see page 31) the

\Err@{\string\boldkey}space can't...}

is replaced by

\Err@{\noexpand\boldkey can't...}

with a similar change for \boldsymbol.

Note, by the way, that these substitutions cannot be made in

\newhelp\athelp \newhelp\defahelp

which end up putting things inside \csname...\endcsname.

### Line breaking

The original \(\mathcal{A}_{\mathcal{N}}\mathcal{S}\)-TEX definition of \nolinebreak had an extra element \refskip@, which was initially \relax, but which was changed for the bibliography. In version 2, that aspect of the bibliography macros (sections 29.3 and 29.11), as well as the indexing macros (section 38.3), has been improved. Consequently, the four control sequences

\nolinebreak \allowlinebreak \linebreak \newline

will all have something added; it will suffice to add the same thing, which we will call \lkerns@, to the first three, and something that we will call \nkerns@ to the fourth; like the old \refskip@, these are both initially \relax. The definitions of these four line-breaking macros are deleted in \amstex.tex, and we now add the new definitions. They differ from the original definitions (see \amstex.doc) in the inclusion of \lkerns@ and \nkerns@; however, these do not occur in quite the place that \refskip@ occurred in the original definition of \nolinebreak--that was, in fact, incorrect. We have also simplified the definition of \newline--as indicated in \amstex.doc, the case of \newline\par really isn't worth worrying about.

\let\lkerns@=\relax

\def\nolinebreak\relax \ifmathmode@ \mathmodeerr@\nolinebreak\else


After redefining \alloc@, \_M_S-TEX also uses

\let\alloc@@=\alloc@

to make \alloc@ _that_ version of \alloc@, even if called after \alloc@ has been redefined at the end. In the definition of \loadmsam, for example, the code

\alloc@@@\fam\chardef\sixt@@n\msafam

functions as a replacement for \newfam\msafam; this not only gets around the problem that \newfam is still \outer in \_M_S-TEX, it also ensures that nothing gets written to the.log file even if \loadmsam is used after \alloc@ is restored to its old definition.

In the definition of \accentedsymbol, however, a non-outer \newbox is needed, because it appears in a construction like

\expandafter\newbox\csname... \endcsname

where we can't simply use the code for \newbox. So amstex.tex used \newbox@ as a non-outer version of \newbox. However, the \_M_S-TEX definition,

\def\newbox@{\alloc@4\box\chardef\intsc@unt}

because it used \alloc@ rather than \alloc@, wasn't really the right choice anyway.

In \_M_S-TEX we rectify this situation. First of all, the definitions of \newbox@ and \accentedsymbol are deleted in amstex1.tex. Then in lamster.tex, we

\def\newbox@{\alloc@@4\box\chardef\intsc@unt}

and also, for later use,

\def\newcount@{\alloc@@0\count\countdef\intsc@unt}



### 3.7. Lists

This test may compared with the test on page 379 of _The TeXbook_. Using \let\next@ instead of \def\next@ allows the test

\ismember@#1\next

to be used after \next has been \let equal to some control sequence by a \futurelet, which will be important in section 7.2 (on some occasions we will also be using \ismember@#1#2 when #2 is an explicit argument). But two precautions are then in order:

* Although actual lamstex.tex code usually omits = signs after \let's, in the above code we need both the boxed = sign _and the space after it!_ Reason: Our \futurelet may have \let\next be a space token, which is thus a (space token) in the notation of _The TeXbook_, page 369. According to the syntax rule on page 377, one such space (but only one) will be ignored after the = sign; if we simply had

\let\next@=#2\def\\\...

then the (space token) #2 would be ignored, and \next@ would end up being the \, which would then disappear, causing infinite confusion later on.
* Another important precaution is the \let\next@=\relax at the end. That is needed because the \futurelet\next may have \let\next equal something equivalent to \ifftrue or \ifffalse, so that \next@ would then also be equal to \ifftrue or \ifffalse. If that situation were allowed to continue, havoc might ensue the next time we used a macro containing \next@ within it.

As an example of this latter phenomenon, note that the original plain TeX definitions

\catcode'\'=\active\gdef'{\bgroup\prim@s}\def\prim@s{\prime\futurelet\next\prim@m@s}\def\pr@m@s{\ifx'\next\let\next\pr@0@s\else\ifx'\next\let\next\pr@0@t. \else\let\next\group\fifi\next}

later had to be modified by changing \pr@m@s to \def\pr@m@s{\ifx'\next\let\next\pr@@s \else\ifx'\next\let\next\pr@@t \else\let\next\group\if\if\next\} For example, we might have $a'\iffirstset x\else y \if$ where \iffirstset is some user-defined construction, and then the \futurelet\next in \prim@s would \let\next=\iffirstset. Note that the appearance of \next after an \ifx test causes no problem, but its appearance within an \if... clause, even following a \let or \def, would make things go haywire. Similarly, in the definition of \ismember@, the \next@ appears in safe places.

To avoid such problems in general, after any \futurelet we will use only the token \next, and otherwise \next will not appear in any macros except after \ifx tests (or \ifcat tests). One definition in amstex.tex requires modification to adhere to this rule: the definition

\gdef\comment@@@@#i\comment@@@@{\ifx\next\comment@@@@\let\next\comment@ \else\def\next\oldcodes@\endlinechar='\^M\relax\% \if\next\} has been changed in amstexl.tex to \gdef\comment@@@@#i\comment@@@@{\ifx\next\comment@@@@\let\next\comment@ \else\def\next@{\oldcodes@\endlinechar='\^M\relax\% \if\next@}

### 3.8. Skipping spaces in \futurelet's

On page 3.8 we mentioned \(\mathcal{M}\mathcal{S}\)-TEX's device for skipping over space tokens in \futurelet constructions. Instead of using this device directly, which requires somewhat long definitions each time, \(\mathcal{M}\mathcal{S}\)-TEX uses a special "futurelet-next-skipping-spaces" construction

\FNSS@\foo




### 3.10. A la franeais

Finally, certain changes are made to amstex.tex to accommodate French styles that make some or all of ; and : and! and? into active characters. In this case, various \(\_\)\(\mathcal{A}\)\(\mathcal{A}\)\(\mathcal{S}\)-TEX macros that involve tests like

\(\backslash\)ifx\(\backslash\)next!

need to be changed.1

Footnote 1: In addition, in lamstex.tex we have the problem that certain control sequences, notably those for commutative diagrams and tables, use certain punctuation as part of their syntax. For example, the \(\mathcal{A}\)s option for arrows in a commutative diagram is typed in the form \(\mathcal{A}\)s(h;v) (see page 155 of the 14\(\mathcal{A}\)\(\mathcal{S}\)-TEX Manual). If we make a definition like \(\backslash\)def\(\backslash\)ds(#1;#2){...}, then TEX incorporates a type 12 ; as part of the syntax for \(\mathcal{A}\)s. So in a document where ; is active, the ; that the user types will not be recognized as the proper syntax element. The devices for handling this problem will be discussed at the appropriate time (in Volume 2).

Our goal is to allow all necessary changes to be indicated in a reasonably short file, say french.tex, which can be read in _after_ lamstex.tex (so that it can be loaded on top of a 14\(\mathcal{A}\)\(\mathcal{S}\)-TEX format file).

The most reasonable approach is to have certain control sequences that have been \let equal to the active punctuation symbols, so that we can use these in an \(\backslash\)ifx\(\backslash\)next... test. Of course, this can only be done after the active punctuation symbols have been defined, not in amstexl.tex. To get around this problem, we will insist that the definition of the active punctuation symbols in french.tex are not made with an ordinary \def, but with a special \APdef, which will manage things properly for us.

For the control sequences that will be \let equal to the active punctuation symbols we will use the following control words (which have to be created using \(\backslash\)csname...\(\backslash\)endcsname): '\(\backslash\)A@;' and '\(\backslash\)A@:' and '\(\backslash\)A@?' and '\(\backslash\)A@!'. We begin by assigning the non-active characters as default values:

\(\backslash\)expandafter\(\backslash\)cnsname A@;\(\backslash\)endcsname=; \(\backslash\)expandafter\(\backslash\)let\(\backslash\)csname A@:\(\backslash\)endcsname=: \(\backslash\)expandafter\(\backslash\)let\(\backslash\)csname A@?\(\backslash\)endcsname=? \(\backslash\)expandafter\(\backslash\)let\(\backslash\)csname A@!\(\backslash\)endcsname=!

When

\(\backslash\)APdef:{... }




so that we can then use things like

\expandafter\ifx\csname A@\string!\endcsname\next

to check for an active 1. The new code is:

\def\boldkey#1{\ifcat\noexpand#1A%  \ifcmmibloaded@{\fam\cmmibfam#1}\else  \Err@{First bold symbol font not loaded}\fi  \else \let\next[\=\#1\% \ifx#1!\mathchar"\5\bffam@21 \else \expandafter\ifx\csname A@\string!\endcsname\next

\[\mathchar"\5\bffam@21 \else] \ifx#1(\mathchar"A\bffam@28 \else \ifx#1)\mathchar"\5\bffam@29 \else \ifx#1+\mathchar"\2\bffam@2B \else \ifx#1:\mathchar"\3\bffam@3A \else \expandafter\ifx\csname A@\string:\condcsname\next

\[\mathchar"\3\bffam@3A \else\ \ifx#1;\mathchar"\6\bffam@3B \else \expandafter\ifx\csname A@\string:\condcsname\next

\[\mathchar"\6\bffam@3B \else\ \ifx#1=\mathchar"\3\bffam@3D \else \ifx#1?\mathchar"\5\bffam@3F \else \expandafter\ifx\csname A@\string?\condcsname\next

\[\mathchar"\5\bffam@3F \else\ \ifx#1[\mathchar"\4\bffam@5B \else \ \ifx#1]\mathchar"\5\bffam@5D \else \ifx#1,\mathchari@63B \else \ifx#1-\mathcharii@200 \else \ifx#1.\mathchari@03A \else \ifx#1/\mathchari@03D \else \ifx#1<\mathchari@33C \else \ifx#1>\mathchari@033E \else \ifx#1*\mathcharii@203 \else


### Chapter 4. Numbering styles

Next we define the standard _LMS-TEX_ numbering styles: \arabic, \alph, \Alph, \roman, \Roman, and \fnsymbol.

These numbering styles are meant to be applied to a _number_, not to a counter (in the _LMS-TEX_ macros they are usually applied to \number(counter) for some (counter)). \arabic is consequently quite trivial:

\def\arabic#1{#1}

The definition of \alph#1 uses the fact that the lower-case letters a-z have positions 97-122 (if some one were to design a perverse font for which this wasn't true, then \alph would have to be defined differently).

\alph begins by setting the scratch counter \count@ to the value of #1:

\def\alph#1{count@=#1}relax

We always add the \relax as a precaution in such situations, even if it may not be strictly necessary (_The TEXbook_, page 208, recommends a space, but \relax seems best, to avoid any anomalous situations where an unwanted space might somehow intrude itself into the token stream).

Then we add 96 to the value of \count@ and we print the character \char\count@, but we give an error message if this would give us a character past 122 (this could easily happen if some one caused the counter to be augmented more than 25 times):

\def\alph#1{count@=#1\relax\advance\count@ by 96 \ifnum\count@>122 \Err@{\noexpand\alph invalid for numbers > 26}else\char\count@\fi}

(See section 3.4 for the use of \noexpand\alph rather than \string\alph.)

We don't bother giving an error message if \count@ ends up having a value less than 97, since reasonable macros will normally start the counter for a particular construction at 1. (So there is the possibility that some one will perversely \Reset some construction to 0, say, and then have \alph produce a left quotation mark '! If this really seems bothersome, another check can easily be added to the code.)The definition

\def\Alpha#1{\count@=#1\relax\advance}count@ by 64 \ifnum\count@>90 \Err@{\noexpand\Alpha invalid for numbers > 26}else\char\count@\fi}

is exactly analogous, using the fact that the letters A-Z should have the positions 65-90.

For \roman we just have to

\def\roman#1{\romanumeral#1\relax}

since TEX provides the \romanumeral primitive. (The \relax is essential here; otherwise something like \roman{10}3 would be expanded into \romannumeral103, giving the result '\init'.)

But \Roman is more complicated,

\def\Roman#1{\uppercase\expandafter{\romanumeral#1}}

Here the \expandafter causes expansion after the left brace {. Without the \expandafter, something like \Roman3 would become

\uppercase{\romanumeral3}

which is just \romanumeral3, and thus '\init'. With the \expandafter, we get

\uppercase{(expansion of \romanumeral3)}

i.e., \uppercase{iii}, or '\III'.

Note that we don't need to add \relax after the #1 in his definition, because \romanumeral#1 is expanded within the \uppercase{...}.


_A__N_S_-TEX has already defined \dag, \ddag, VP, and \S, so that they can be used either in text or in math mode, where they will change size properly; \text{$\|$} simply does the same for the \| symbol (# needs no special treatment). Modifications of \dag,... may be necessary for fonts with different layouts.

In the above definition we put the \loop inside a group just in case \fnsymbol happens to be used inside some \loop itself, a somewhat finicky precaution, since a nested \loop involving \fnsymbol will never be produced by any \d_A__N_S_-TEX construction. The same precaution will be used for any \d_A__N_S_-TEX loop that might conceivably occur within another \loop.

## Chapter 5 Printing cardinal and ordinal numbers

This chapter is in some sense a companion to the previous one.

First we define \cardnine@#1 for printing the final part of the name of a cardinal number; it will be applied to a counter with a value from 1,..., 9:

\def\cardnine@#1{ifcase#1lor onelor twolor threelor fourlor sixlor sevenlor eightlor nine}fi

The number 10 will be used so often in the macros of this chapter that we want to use \newcount to introduce a counter having that value.

As we mentioned in section 3.6, amstex.tex (and amstex1.tex) redefine \alloc@ so that it doesn't write anything to the.log file; and

\let\alloc@@=\alloc@ is used so that \alloc@@ is _that_ version of \alloc@, even if called after \alloc@ has been restored to the old definition from plain TEX at the end.

We now want to reinstate the new definition until the end of lamstex.tex. Instead of redefining it directly, we just have to

\let\alloc@=\alloc@@ since \alloc@@ was permanently given the new definition.

Since \newcount is defined in terms of \alloc@, which we have just made equivalent to \alloc@@, the next code

\newcount\ten@ \ten@=10

does not produce anything in the.log file of a file that has \input lamstex (nor will any of the other \new... constructions to follow).

Although \cardinal{...} will normally be applied when... is a number, to be on the safe side, we first safely store the value in a counter,

\def\cardinal#1{\count@=#1}relax


)

The ordinal numbers < 100 can be treated in a manner exactly like the cardinal numbers. But a problem arises for ordinal numbers like '100th', '101st', '102nd', '103rd',..., '109th', '110th', '111th', '112th',...--now the proper suffix depends not only on the last digit of the number, but also on whether the next-to-last digit is a 1.

The routine \ordsuffix@ selects the right suffix in these cases, assuming that the number in question has been stored in \count@. The first part of the routine below divides \count@ by 10, and then calculates \count@00 to be \count@ (mod 10) [compare the previous calculations for \cardinal]. If this is 1, so that the next-to-last digit of the number in \count@ was 1, 'th' is selected. Because the original value of \count@ is needed for the second part of the routine, we need to store it in yet another counter, \count@000, which we have to declare.

This second part simply computes \count@00 as \count@ (mod 10) [for the original value of \count@]; if this second part of the routine ends up being invoked, the correct choice of the suffix depends only on this value of \count@00:

\newcount\count@000



\let\/=\relax was added to \noexpandtokos@ because \/ will often occur in "style" commands (pages 50, 74, 104, et al.) that appear in \edef's or \xdef's and \write's (pages 71, 76, et al.) and \/ is no longer a primitive in \(\mathcal{A}\!\!\mathcal{S}\)-TEX or \(\mathcal{L}\!\!\mathcal{A}\!\!\mathcal{S}\)-TEX (page 5). Similarly \let\null=\relax was added because \null sometimes occurs in "style" commands (see page 58, for example).



### 7.2 Special considerations for invisible constructions

[A precautionary \relax after the \hskipipt is not needed here--the \fi will stop the scanning of \hskip.] As a result of this definition,

\flushpar\invisible{...}\_u

becomes

\par\nonident\nobreak\hskip-1pt\hskipipt\invisible{...}\_u

(and similarly for \flushpar\label{...}, and any other "invisible" constructions that we will eventually define, and add to \vanishlist@).

Consequently, the \prevanish@ removes the \hskipipt and then sets \saveskip@ to 1pt. Then the \postvanish@ adds back the \hskipipt once again, canceling out the \hskip-1pt. Moreover, since \saveskip@ is now positive, the space token after the \invisible will be thrown away, so that \invisible{...} will really be invisible.1

Footnote 1: If some one has typed \define\foo{\invisible{...}} and then used \flushpar\foo, this presents no problem, since in this case no space after \foo will appear. (But, of course, \define\foo/{\invisible{...}} would make \flushpar\foo/\_u’ behave incorrectly; this didn’t seem worth worrying about)

Note, by the way, that \ismember@ was defined in such a way that the test \ismember@\vanishlist@\next sets \iftest@ to be true when \next has been \let equal to a control sequence in \vanishlist@ (page 23).

[In the above definitions, it might seem that we could simply add the \hskip-1pt\hskipipt in all cases. But that wouldn't quite work, because the next construction might begin with an \unskip (e.g., \linebreak or \dots). Aside from such a case, however, the \hskip-1pt\hskipipt doesn't do any harm.]

Since some users might type \noindent instead of \flushpar, we might as well add the \futurelet\next\pretendspace@ to \noindent also.

\let\noindent@=\noindent

\def\noindent{\par\noindent@\futurelet\next\pretendspace@}

\def\pretendspace@{\ismember@\vanishlist@\next\,\



## Chapter 9. \page

In _LMS-TEX_ the control sequence \page can be manipulated like \tag, \claim, etc. Thus, we can use \Reset\page, \newpre\page,.... But we want \page by itself to give an error message:

\def\page{\Err@\noexpand\page has no meaning by itself}}

(Again, see section 3.4 for the use of \noexpand.)

As we will see in Chapter 11, associated with the _LMS-TEX_ construction \tag we have

\tag@C the counter associated with \tag \tag@P the "pre" material for \tag \tag@Q the "post" material for \tag \tag@S the style for \tag \tag@N the numbering style for \tag \tag@F the font for \tag

Likewise, \claim and all other _LMS-TEX_ constructions that can be given a (label) have similar counters and control sequences associated with them.

At present, we simply want to consider the counter and control sequences associated to \page. For \page@C we just use plain TEX's \pageno

\let\page@C=\pageno

and then we introduce default values (\empty is defined in plain.tex by \def\empty{}, so \let\page@P=\empty is just a briefer way of saying \def\page@P{}:

\let\page@P=\empty \let\page@Q=\empty \def\page@S#1{#1}\def\page@F{\rmrm} \def\page@N{\arabic} \% cannot be \letThe V/ in page@S might be useful if page@F is ever chosen to be a slanted font.

We want to have \def\page@F{\rm} rather than \let\page@F=\rm, because \rm may actually change definitions. For example,

\fontstyle\page{...}

expands out (page 227) to

\page@F...}

and if we are in 9-point type at the time, we would expect to get 9-point roman type, not the 10-point roman type that is in effect at the time that \page@F is specified.

And, as we will see later (page 59), it is even more critical that we have \def\page@N{\arabic} rather than \let\page@N=\arabic.


### 10.2 \indexproofing

Then (compare section 3.6), since we used \alloc@@ rather then \alloc@, nothing will be written to the.log file, even though \indexfile is used after \alloc@ itself has been redefined at the end of lamster.tex.

### 10.2 \indexproofing

We will need an insertion class, called \margin@, for index entries that are to appear in the margin if \indexproofing has been specified. So we would like to say '\newinsert\margin@'. But \newinsert is defined differently than all other \new\new\corrections in plain, and it will write something to the.log file, despite our redefinition of \alloc@. So we instead simply restate everything from plain in the definition of \newinsert except for the \wlog part:

\global\advance\insc@unt\m@ne

\ch@ck@\insc@unt\count

\ch@ck\insc@unt\dimen

\ch@ck2\insc@unt\skip

\ch@ck4\insc@unt\box

\allocationnumber\insc@unt

\global\chardef\margin@\allocationnumber

Notice that although this takes up a lot of space in the file, it takes up hardly any space within TeX itself, just like \newinsert\margin@.

We put no limit on the number of marginal notes on a page, and they take up no space (compare _The TeXbook_, page 415):

\dimen\margin@=\maxdimen

\count\margin@=0

\skip\margin@=Opt

The flag \ifindexproofing@ will tell us whether \indexproofing (and/or \noindexproofing) appears:

\newif\ifindexproofing@

\def\indexproofing\indexproofing\indexproofing\indexproofing\indexproofing\index


braces. Nevertheless, it alleviates considerably the problems that arise when we want to \write the string #1 to a file without having control sequences expanded. We simply have to write \macdef@ instead!

More precisely, for some output stream, like \ndx@, instead of using an \immediate\write like

\immediate\write\ndx@{#1}

we can

\def\next@{#1}

\expandafter\unmacro@\meaning\next@\unmacro@

\immediate\write\ndx@{\macdef@}

For delayed \write's we have to be more careful, since \macdef@ may have been redefined by the time the \write occurs. Instead of

\write\ndx@{\macdef@}

we must use

\edef\next@{\write\ndx@{\macdef@}}

\next@

The \next@ is not expanded in this \edef, since it was created with \chardef; such control sequences aren't expanded in \edef's. Consequently, the \edef simply makes \next@ mean

\write\ndx@{\expansion of \macdef@}}

so that \next@ then produces this \write.

Notice that it is irrelevant that we are writing type 12 tokens to the.ndx file: once they are written to that file their category codes are completely irrelevant--if \TEXT reads this file later, they will simply be given the category codes that are in force at the time.

### 10.4. The \starparts@ and \windex@ routines

In version 1 of \(\mss\)-TeX, only invisible entries could have * optional entries, but now even visible entries can have them.

We will use a construction \starparts@#1 that determines if #1 contains a * and defines

\stari@ to be all of #1 \starii@ to be the part of #1 before the first * (or all of #1 if there is none) \starii@ to be the part of #1 after the first * (or empty if there is none)

We begin by choosing the values that will hold when no * appears:

\def\starparts@#i{\def\starii@{#1}\def\starii@{#1}\let\starii@=\empty

Then we perform a test that sets \iftest@ to be true if * appears in #1 and false if it doesn't (compare the definition of \tagin@ in section 3.3):

\test@false \def\next@##1*#2#3\next@{\ifx\starparts@##2\test@false \else\test@true\ti} \next@#1*\starparts@\next@

If no * appears we are done; otherwise we will have to call another routine that separates the two parts:

\def\starparts@#1{\def\starii@{#1}\def\starii@{#1}\% \let\starii@=\empty \test@false \def\next@#1*#2#3\next@{\ifx\starparts@##2\test@false \else\test@true\ti}\% \next@#1*\starparts@\next@ \iftest@\def\next@{\starparts@##1\starparts@0}\% \else\let\next@=\relax\{\fi\next@\} \def\starparts@0@1*\#2\starparts@@{\def\starii@{#1}\% \def\starii@{*2}}

Once our "..." and ""..." constructions, to be defined in section 5, have used \starparts@ to determine \stari@, \starii@, and \stariii@, we will use \starii@ to typeset '...' in the case of a visible index entry, and then we will use the "write-index" routine \windex@.

When we are making an.ndx file, this routine will first

\expandafter\unmacro@\meaning\starii@\unmacro@

to convert '...' to type 12 tokens. Then

\edef\macdef@\string"\macdef@\string"\

will add " at each end, for the sake of the index program; \string" is needed since " will be active.

Then we will use the \edef of page 55 to write these tokens to the.ndx file. This will be followed by the page number. Actually, instead of writing just the page number, we write four groups, the first containing the page number, and the next three containing the page numbering style, the "pre-page" material, and the "post-page" material (Chapter 9),

\write\ndx@\{\number\pageno\{\page@N\}-\{page@P\}-\page@Q\} This allows the index program to deal with all sorts of special page numbering possibilities.

In addition, when \ifinderproofing@ has been set true, we want to

\insert\margin@\hbox\rm\vrule\height9pt\depth2pt\widthOpt...

where the \hbox begins with a "strut", designed to keep baselines of successive entries 11 points apart (see page 7 for the use of \height,...).1This \hbox should contain all material before any * in '...' typeset in \rm, but all material after the first * should be converted to type 12 tokens, and typeset in the \tt font,1 since it contains things like *\it, which are not supposed to be acted upon, but merely convey information to the index program.

Footnote 1: Other styles (compare Part VII) may use smaller print for these side notes.

This is all accomplished with the following code:

\def\window&{\ifindexing@ \expandafter\unnmacro@\meaning\stari@\unnmacro@ \odef\macdef@{\string"\macdef@\string"\% \edef\next@{\write\ndx@\{\macdef@\}\next@ \write\ndx@\{\number\pageno\{\page@N\}\{\page@P\}\{\page@Q\}\}\% \fi \ifindexproofing@ \ifx\starii@empty\else \expandafter\unnmacro@\meaning\stariiig@\unnmacro@\fi \insert\margin@{\hbox\{\rmrm\wrrule\}\height9pt\depth2pt \widthOpt\starii@ \first\{\rm\starii@empty\}\else\{\tttt\macdef@\}\%fi\}\% \fi\}\)\(\}\)

At the time that our \write is performed, we will want \noexpands@ to be in effect, partly to prevent expansion of any font control sequences that might appear in \page@P and \page@Q, but mainly because we want to be sure that \page@N isn't expanded during the \write, since the index program expects to see a numbering control sequence in this second group.

But there's no point putting

\norexpands@ \write\npg@{{\number\pageno}\{\page@N\}\{\page@P\}\{\page@Q\}\}\)

in our definition, because this delayed \write is simply added to the main vertical list and does not take place until a \shipout. Instead, we will have to be careful to specify \noexpands@ during any \shipout (section 36.1).

Nevertheless, this is an appropriate time to discuss the problems that would be encountered if expansion were not prohibited. Expansion would clearly 


We should note that as a consequence of the definition of quote@@@@#1, the indexed word #1 may be followed by an insert and/or a "whatsit", namely, the \write produced by \window@. But either an \insert or a "whatsit" can appear _after_ a word without suppressing hyphenation--see _The TeXbook_, third paragraph from the bottom on page 454. (This should be compared to the \makexref macro on page 424 of _The TeXbook_, where the \insert appears _before_ the word, and therefore suppresses hyphenation of the word.) Similarly, as we will see in a moment, an invisible index entry simply supplies an \insert and/or a \write. The warning on page 100 of the \(\LAN\)-TeX Manual is therefore inaccurate: an invisible entry will suppress hyphenation of a word only if it immediately precedes it, not if it follows it. Similarly, the warnings on pages 31 and 33 are inaccurate; only a \label or \pagelabel immediately preceding a word will interfere with its hyphenation--in particular, the example given on page 33 won't interfere with hyphenation.

\quote@@ is not that much different from \quote@@, except that we want it to swallow the next ", and begin with \prevanish@@, so that it will be invisible:

\def\quote@@@@"#1"{prevanish@@\starparts@@{#1}\window@} \futurelet\next\quote@@@@@@}

The \futurelet\next\quote@@@@@@ is needed to see whether yet another " occurs after the third " that caused all this to happen. If a fourth " didn't occur, we insert the \postvanish@@, and if a fourth " did occur, we simply swallow it up, and then insert the \postvanish@@:

\def\quote@@@@@{\ifx\next"\def\next@@"{postvanish@@}\else\letnext@@=\postvanish@@{if}\next@@}

### 10.6 Changes to the \(\LAN\)-TeX Manual

Because of changes in the indexing macros, almost every caveat on page 101 of the \(\LAN\)-TeX Manual is wrong.

The first paragraph is wrong: index entries within heading levels _will_ show up in the margins when \indexproofing has been specified. (Of course, one had better not type something like

\HL1 "Disappearing" words\endHLsince "Disappearing" would then be interpreted as a "quoted" number for \HL1! Something like \HL1\"Disappearing" is needed.)

The third paragraph is wrong, because only the parts after the first * will be typeset in the typewrite font, with characters of type 12.

The fourth paragraph is wrong: \(\verb|"|\) can be used within an invisible entry.

The fifth paragraph is wrong: invisible entries can now appear anywhere.

It is true, as the final paragraph claims, that index entries in \footnote's won't appear in the margin (they are \insert's within an \insert, and won't migrate out). However, no special efforts are required in the \footnote macros to get indexing to work within \footnote.

_10.7. Invisibility._ After all this, we want to add " to \vanishlist@:

\rightadd@"\to\vanishlist@

This probably looks wrong, since it is only the double mark \(\verb|"|\) that indicates an invisible entry, but

\nobreak\hskip-ipt\hskipipt"\..."

and

\nobreak\hskip-ipt\hskipipt"\..."

will both work out just right: before the visible index entry \"\..." the \hskip-ipt\hskipipt will simply be irrelevant, while before an invisible index entry \verb|"|\..."| it provides the right clues for the \prevanish@ called by \quote@@ (compare page 47).

_10.8. Other delimiters for index entries._ The use of \(\verb|"|\) as a delimiter for index entries conflicts with its use in German styles (this will probably remain true even when the international font layouts are in use, although then the \(\verb|"|\) will presumably no longer be active for German). However, it is not very hard to set up other delimiters for this purpose.

For example, suppose we want to use <...> delimiters, so that

\[\verb|Beauty<<beauty>>|>|\,is<truth>|.\]


since Scandinavian keyboards have letters instead of < and >. There aren't too many possibilities left, however! The only reasonable candidates are _ and | (although + and = would also be possible, if we insisted that people never used them outside of math mode), and

\deeauty||beauty|| is |truth|, truth beauty doesn't look too bad. If only | weren't used for something else in German styles!)

_10.9._ \idefine_and_\iabbrev. A construction like

\idefine\cs(parameter text)\{replacement text} has to

\define\cs(parameter text)\{replacement text} and also send this definition off to the.ndx file.

\idefine first stores its argument, \cs say, in \next@, and also stores \noexpand\cs in \nexti@, for later use:

\def\next@{#1}\def\nextii@{\noexpand#1}%

Then we will apply the construction \idefine@ once we have suitably swallowed up the \(parameter text) and \replacement text):

\def\idefine#1{\def\nexti@{\noexpand#1}% \afterassignment\idefine@\def\nextiii@} Here the \def\nextiii@ will cause the following \(\langle\)parameter text\(\rangle\) and \(\langle\)replacement text\(\rangle\) to be digested into a definition of \nextiii@, after which assignment we will apply \idefine@.

Since \nextiii@ now has the definition that we want for \cs, the first thing \idefine@ must do is to

\let\cs=\nextiii@Since \next@ was \def'ed to be \cs, we can do this with

\expandafter\let\next@=\nextiii@

Then, if we are indexing, we need to recover the (parameter text) and (replacement text) for \cs, which is now that for \nextiii@. So we use

\expandafter\unmacro@\meaning\nextiii@\unmacro@

[This construction doesn't work if '->' appears in the (parameter text) of a definition, so let's hope no one ever makes such a definition.]

Now we want to write

\define\cs(parameter text)\{replacement text}}

to the.ndx file. Since \nextii@ was defined as \noexpand\cs, we can do this with

\immediate\write\ndx@{\noexpand\define \nextii@\macperf@{\macdef}}

--note that the \write will first expand \nextiii@ to \noexpand\cs, and then replace this with \cs, unexpanded. Since all tokens in \macpar@ and \macdef@ are type 12, we don't have to worry about their expansion (and note the remark on page 55).

Thus, the definition of \idefine@ reads:

\def\idefine@{\ifindexing@ \expandafter\let\next@=\nextiii@ \expandafter\unmacro@\meaning\nextiii@\unmacro@ \immediate\write\ndx@{\noexpand\define\nextiii@ \macpar@{\macdef@}}\}\tij}

\iabbrev is simpler. Recall that \iabbrev must be used in the form

\iabbrev*\cs{...}

### 10.9 \idefine and \iabbrev

so we define

\def\iabbrev*#1#2{\ifindexing@ \toks@={#2}% \immediate\write\ndx@ {\noexpand\abbrev*\noexpand#1{\the\toks@}}\fi}

* [15]_Part II_

_Labels and_

_Cross References_* [10]


undefined (unless the construction happens to lie within another construction that can be given a (label)). However, we will initially

\let\thelabel@=\relax

Then the simple test

\ifx\thelabel@\relax

will be true unless we are in a construction where \label is legitimate.

As a (somewhat contrived) example of how this works, suppose that in the third section of some document, \claim numbers are being printed as (3.i), (3.ii), (3.iii),..., and that before the tenth \claim we state

\offset\claim0 \newpost\claim{-A}

so that the number of the tenth \claim will be printed as '(3.ix-A)'.

Then within the tenth \claim

\claim@C will be 9 \claim@P will be 3. \claim@Q will be -A \claim@S#1 will be (#1) \claim@N will be \roman \claim@F will be \bf and, correspondingly

\thelabel@ will be \roman{9}

\thelabel@emptyset will be (3.\roman{9}-A)

\thelabel@emptyset will be 9 \thelabel@emptyset will be 3.\roman{9}-A

The value of the counter for \claim, the numbering style, the pre- and post-material, and the style for \claim are all involved in the values of \thelabel@,..., \thelabel@emptyset; see section 5 regarding the font style.

### Restrictions

The first concrete example of defining \thelabel@,..., \thelabel@@@@ occurs in Chapter 16. For the moment, we simply want to note that these control sequences will essentially be created using \edef's, to insure that they will contain the current values of the counter, numbering style, etc. Moreover, they will often occur in \xdefs's and \write's (see page 16). This means that

Any control sequences appearing in \...@P, \...@Q, \...@S, or \...@N must be ones that can appear in \xdef's and \write's.

Actually, we will use \noexpands@ (Chapter 6) to inhibit expansion during the \edef's, \xdef's, and \write's (pages 82, 84, et al.), so the proper strategy is to allow only control sequences for which \noexpands@ prevents expansion.

We've already noted (page 16) that \let\/=\relax was added to the token list \noexpandtoks@ because \ often appears in \...@S definitions; and \let\rmrm=\relax,... were added because font change control sequences often appear also--see, for example, pages 16 and 16.

Similarly, page 16 of the \(\LAM\)-\TEX Manual indicates that if a new font selection command \TimesRoman is ever going to be used in defining the style for anything that can be labelled, then \Nonexpanding\TimesRoman ought to be added, and if a new numbering command \Babylonian is ever going to be used to number anything that can be labelled, then we should add \Nonexpanding\Babylonian to the file.1

### Consequences of these restrictions

Since constructions like \newpre simply define various \...@P control sequences, the restrictions of the previous section also mean that in constructions like

\newpre\tag{...}

_any control sequences in '...' must be ones for which \noexpands@ prevents expansion._ And this means that some of the things stated, and implied, in the \(\LAM\)-TEX Manual are false.

While the illustrations of \newpost given for \tag and the illustrations of \newstyle and \newnumstyle given in connection with \list were quite legitimate, the small print on page 77 gives the example

\newpre\exno{\value}HL1.\value\hl1.}

for numbering a user-created construction. But this example is completely wrong! Things like \value can't be used for \newpre.

Instead, we need something like1

\Evaluate\HL1

\edef\HLvalue{\number\Value}

\Evaluate\hl1

\newpre\exno{\HLvalue.\number\Value.}

And the situation is even more complicated, because we need to restate this after every \hl1.

\Initialize. To handle such situations, \LANS-TEX now has the construction \Initialize (the details of which are described in sections 23.4 and 23.15). If you type

\Initialize\hl1{\Evaluate}HL1

\edef\HLvalue{\number\Value}%

\Evaluate\hl1

\newpre\exno{\HLvalue.\number\Value.}}

then the set of commands (A) will be executed each time an \hl1 occurs.

Similarly,

\Initialize\HL1{\newpre\hl1{\}}

would make the pre-material for \hl1 be empty even for the default style, which normally makes the pre-material for \hl1 be '1.' in the first \HL1, and '2.' in the second, etc.

If \chapter and \section have been introduced as names for \HL1 and \h11 (see Chapter 23 for details), then we can substitute \chapter for \HL1 and/or \section for \h11 in the \Initialize command, e.g.,

\Initialize\chapter{\newpre\section{}}

[Different \Initialize commands don't accumulate, so if you later want to add \newpre\h12{}, then you must use

\Initialize\HL1{\newpre\h11{\newpre\h12{}}}

This shouldn't be much of a problem, since such commands are rather special, and would probably go near the beginning of a document; moreover, if they did accumulate, it would quite dicey to _cancel_ any such command.]

As an extra bonus, within the \Initialize construction, \pref may be used with a special significance. For example, in something like

\Initialize\h11{\newpre\exno{\pref.}}

the '\pref' will give the value that \pref would have for a (label) in the \h11 that has just been executed. Consequently, in the default style this will have the same effect as (B).1

Footnote 1: More precisely, it will have the same effect as if we had used \Evaluatepref, as suggested in footnote 1 on page 72.

#### The question of fonts

Note that the font for \claim is not recorded anywhere in \thelabel0,..., \thelabel0000--it is relevant only when the \claim number is actually printed.

Thus, as we'll see in Chapter 24, \Ref{(label)} will not print '(3.ix-A)', but simply '(3.ix-A)' [or '(3.iv-A)' if we are using italic type, etc.]. But we can get '(3.ix-A)' by typing \fontstyle\claim{\Ref{\label}}, which expands out (page 227) to

\claim@F\Ref{(label)}}

This seems like the optimal arrangement, giving the option of using the same font or not.



Thus, whenever a.lax file already exists, we will start with all the information obtained on the previous run. Of course, we will have to make sure that " has category code 11 while reading in the lines of the.lax file so that it will have that category code when it is used in defining the corresponding control sequence (compare the remark on page 11).

### 11.7 \ref and its relatives

It should be pretty obvious how \ref#1, \Ref#1, and other cross-referencing commands will work: The test

\expandafter\ifx\csname#1@L\endcsname\relax

is true precisely when #1 has not yet been used as a (label). If the test is true, we simply give an error or warning message. Otherwise, the value of \csname#1@L\endcsname will be

\ref will return V1, \Ref will return V2, etc.

The really interesting question is how we are going to keep the \label and \pagelabel information updated.

### \label

Whenever we encounter a \label.{(label)}, we will first check that we are in a construction that allows \label's, using the test (page 11)

\ifx\thelabel@\relax

If the result if true, so that we are in a construction not allowing a \label, we will simply give an error message. Otherwise, we will use the test

\expandafter\ifx\csname#1@L\endcsname\relax

which is true if and only if #1 has not already been used as a \label.

If #1 has not already been used as \label, we will use

\expandafter\xdef\csname#1@L\endcsname{V1~V2~V3~V4~0}

the 0 at the end indicating that \label comes from a \label added on the current run. In addition, we will

\immediate\write\laxwrite@{@#1^V1~V2~V3~V4~1}

with a 1 at the end. When this line of the.lax file is read by \document on the next run, '\(\{\label\}@L\)' will then be defined so that its value has a 1 at the end, indicating that it represents "previous" information.

On the other hand, if \label has already been used, we need to examine the whole sequence

\[\emptyset\{\label\}\char 94\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\]

and determine the value of the \type indicator.

If this value is 0 or 2, then \label has already been used on the current run, and we will just give an error message saying that \label has already been used.

But if the value is 1 or 3, then the information for \label was compiled during the previous run. Since we want to allow the previous value to be changed, we will change the definition of '\label' so that the sequence

\[\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\]

that currently appears in the definition is replaced by the appropriate

\[\text{V}_{1}\text{``V}_{2}\text{``V}_{3}\text{``V}_{4}\text{''0}\]

the 0 once again indicating that \label now comes from a \label created on the current run. And, once again, we will write appropriate information to the.lax file, but with 1 replacing 0.

\[\text{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{ \LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LARGE{\LGE{\LARGE{\LGE{\LGE{\LGE{\L}}}}}}}}}}}}}}}}}}\]

test, because \pagelabel's are allowed anywhere.

So we simply start with the test

\expandafter\ifx\csname#1@L\endcsname\relax

If this test is false, then then \label has never been used, and now we define '\label' to be

\[\text{V}_{1}\text{``V}_{2}\text{``V}_{3}\text{``V}_{4}\text{''2}\]


1 to a 3, however, so that when it is read in again on the next run, it will be recognized as information coming from a previous \pagelabel.

On the other hand, a 3 indicates that in the previous run \label was used for a \pagelabel. In this case, as indicated above, this previously obtained information is more likely to be the correct one. Consequently, we will _not_ change the definition of '\label(\ell\)'. But we will still write this appropriate new information (using a delayed \write) to the.lax file, keeping the final 3, so that it will appear once again as "previous" information on the next run.

The label mechanism in version 2 of \LAM\_S_-TEX is entirely different, and much more efficient than, the one used in version 1 of \LAM\_S_-TEX, which was designed using a TeX that allowed 3,000 control sequence names. Since \LAM\_S_-TEX itself uses up about 2,700 names, not counting additional control sequences introduced by style files, it seemed imprudent at that time to use a labelling method that introduces a new control sequence name for each (label). But with that old mechanism, main memory was usually exhausted after only about 40 or 50 (label)'s had been created (necessitating the stratagems explained in section 4.8 of the \LAM\_S_-TEX Manual), so this excessive wariness was clearly counterproductive. Moreover, more generous TeXs, allowing at least 3,500 control sequence names, are now quite common (and there's always tinylams.tex for the truly parsimonious).

### 12.1. Preliminaries

Since we have to read an existing.lax file at the beginning of the document, and then write to a new.lax file during the document, we first declare

\newread\laxread@ \newwrite\laxwrite@

\(\LANS\)-TEX makes use of a special sort of list, initially defined to be empty,

\let\fnpages@=\empty which is used for fancy footnote numbering. As we will see in Chapter 25, when \fancyfootnotes is in effect, each \footnote will cause \(\LANS\)-TEX to write a special line to the.lax file: If the first footnote occurs on page 7, say, then

F7 will be written to the.lax file. If the second and third footnotes occur on pages 12 and 14, then the lines

F12 and

F14 will each be written (sometime later on). These lines are always written with a (delayed) \write, and the corresponding information is _not_ recorded internally. On the other hand, when we read in an existing.lax file, any such F\number\ lines will be incorporated into \fnpages@, which will end up looking like

\17\12\14.


If the test is false, so that \next@ is not one of the special lines for fancy footnote numbering, then it will be of the form \[\langle\text{label}\rangle^{\text{-}}V_{1}^{\text{-}}V_{2}^{\text{-}}V_{3}^{ \text{-}}V_{4}^{\text{-}}(\text{type indicator})\] and we want to make the appropriate definition \[\langle\text{def}^{\text{-}}\langle\text{label}\rangle\text{@}L^{\text{-}} \langle V_{1}^{\text{-}}V_{2}^{\text{-}}V_{3}^{\text{-}}V_{4}^{\text{-}}(\text{ type indicator})\rangle\] To do this we use \[\langle\text{expandafter}\rangle\text{@}\text{getparts@}\backslash\text{next@}\] and then \[\langle\text{edef}\backslash\text{next@}\{\langle\text{gdef}\backslash\text{csname}\backslash\text{nextiv@}\text{@}\text{@}\text{L}\backslash\text{endcsname}\] \[\langle\text{nextiii@}\backslash\text{number}\backslash\text{ count@}\rangle\] \[\langle\text{next@}\] Here the \[\rangle\] def makes \[\langle\text{next@}\] mean \[\langle\text{gdef}\rangle\text{@}L\langle\text{label}\rangle\text{@}L\langle \text{[}V_{1}^{\text{-}}V_{2}^{\text{-}}V_{3}^{\text{-}}V_{4}^{\text{-}}( \text{type indicator})\rangle\] The control sequence '\[\langle\text{label}\rangle\text{@}L^{\text{-}}\] is not expanded further because it has been made equal to \[\langle\text{relax}\]. As noted on page 71, any control sequences appearing in \[\langle\text{next@}\] should be ones whose expansion is inhibited by \[\langle\text{noexpands@}\] ; so \[V_{1}^{\text{-}}V_{2}^{\text{-}}V_{3}^{\text{-}}V_{4}^{\text{-}}\] will not be expanded further, because we will be doing all this within a group with \[\langle\text{noexpands@}\]. In addition, as we mentioned on page 76, we will want to make @ and ~~ have category code 11 within this group. Finally, we will set \[\langle\text{endlinechar=-1}\rangle\] within this group, so that \[\langle\text{next@}\] will not contribute a blank space at the end because of the \[\langle\text{carriage-return}\rangle\] at the end of the line. There is one further detail that we have to worry about. Many files, especially files that have been written by TEX itself, have a \[\langle\text{carriage-return}\rangle\] at the end of the line.

end. In this case, the last \next@ before the end of the file will be empty (if we hadn't set \endlinechar=-1 it would be \par). Consequently,

\expandafter\Finit@\next@\Finit@

and

\expandafter\getparts@\next@

would give error messages. So, before any of our tests, we will first make sure that \next@ isn't empty.

After having read \jobname.lax, and thus obtaining all the information form the last run of the file, we re-open the file, to record information produced with this run:

\def\document{\let\fontlist@=\empty \immediate\openin\laxread@=\jobname.lax\relax \endlinechar=-1 \noexpands@ \catcode'\@=11 \catcode'\"=11 \loop\ifeof\laxread@\else \read\laxread@to\next@ \ifx\next@empty \else \expandafter\Finit@\next@\Finit@ \ifx\next@\rightadd@\nextiii@\to\fnpages@ \else \expandafter\getparts@\next@ \edef\next@\gdef\csname\nexti@\endlcsname \next@ \fi \repeat\% \immediate\closein\laxread@ \immediate\openout\laxwrite@=\jobname.lax\relax}

## Chapter 13 Labels

### 13.1 \label.

We begin by setting

\let\thelabel@=\relax (see pages 70 and 76). Since the combination

\thelabel@ ^\thelabel@@@ ^\thelabel@@@@ ^\thelabel@@@@@ ^\thelabel@@@@@ ^\

occurs several times in our constructions, it will save time and space to introduce an abbreviation for it:

\def\thelabel@{\thelabel@ ^\thelabel@ ^\thelabel@@ ^\thelabel@@@@ ^\thelabel@@@@ ^\thelabel@@@@@ ^\

The definition of \label@1 begins with \prevanish@, since \label's are supposed to be invisible, and then gives an error message if \thelabel@ is \relax, so that we are not in a construction that allows \label's. Otherwise we first use the test

\expandafter\ifx\csname#1@L\endcsname\relax

which is true precisely when #1 has not already been used as a (label). In this case, we simply use

\expandafter\xdef\csname#1@L\endcsname\thelabel@0\immediate\write\laxwrite@{@#1^\thelabel@1} to define '\#1@L' and to write to the.lax file. Of course, this must be done within a group with \noexpands@.

If #1 has already been used as a (label), then we need to look at the (type indicator) of \#1@L'. To do this we use

\edef\next@{@^\csname#1@L\endcsname} \expandafter\getparts@\next@so that \count@ will have the value of (type indicator). We need the \edef\next@ so that \next@ will contain the actual value that the control sequence \csname#1@L\endcsname expands out to; naturally, we also need to perform this step in a group with \noexpands@.

If, as a result of our test, \count@ is even, we issue an error message that label #1 has already been used. Otherwise, we simply use

\expandafter\xdef\csname#1@L\endcsname{\thelabels@0} \immediate\write\laxwrite@{@#1^\thelabels@1} to define the control sequence and write to the.lax file:

\def\label#1{\prevanish@ \ifx\thelabel@\relax \Err@{There's nothing here to be labelled}% \else \noexpands@ \expandafter\ifx\csname#1@L\endcsname\relax \expandafter\xdef\csname#1@L\endcsname{\thelabels@0}% \immediate\write\laxwrite@{@#1^\thelabels@1}% \else \edef\next@{@^\csname#1@L\endcsname}% \expandafter\getparts@\next@ \ifodd\count@ \expandafter\xdef\csname#1@L\endcsname{\thelabels@0}% \immediate\write\laxwrite@{@#1^\thelabels@1}% \else \Err@{Label #1 already used}% \fi \fi \if \if \postvanish@} For simplicity, we used a single group to enclose all the constructions that require a \noexpands@.

Finally, having defined \label we now 
#### 13.2. \pagelabel.

There are several differences between the definition of \pagelabel and that of \label.

(1) First of all, we don't have to check the value of \thelabel, since \pagelabel is allowed anywhere.

(2) Instead of \thelabel,..., \thelabel@@@@, which are defined by constructions that can be given a (label), we use the values we want for a page label. Again, it will save time and space to introduce an abbreviation:

\def\thepages@{\page@N{\number\page@C}^% \page@S{\page@P}\page@N{\number\page@C}\page@Q}^% \number\page@C ^\page@P\page@N{\number\page@C}\page@Q ^\}

(As with \thelabel8, we will be using \thepages@ within a group where we have stated \noexpands@.)

(3) Instead of an \immediate\write\laxwrite@, we must use a (delayed) \write\laxwrite@. This is necessary to be sure of getting the proper value of \page@C into the.lax file.

When we encounter a \pagelabel#1, we again first use the test

\expandafter\ifx\csname#1@L\endcsname\relax

which is true if #1 has not already been used as a \label; in this case, we simply use

\expandafter\def\csname#1@L\endcsname\thepages@2\write\laxwrite@{\#1^\thepages@3}

If the test is not true, we again need to look at the type indicator with

\edef\next@{\csname#1@L\endcsname} \expandafter\getparts@\next@

### 13.2. \pagelabel

If this test sets \count@ to be even, we issue an error message. But if \count@ is odd we always

\write\laxwrite@{@#1^\thepages@@3}

moreover, we also

\expandafter\xdef\csname#1@L\endcsname{\thelabels@2}

if \count@ is 1 (but not if it is 3):

\def\pagelabel#1{\prevanish@ \expandafter\if\csname#1@L\endcsname\relax {\noexpands@ \expandafter\xdef\csname#1@L\endcsname{\thepages@2}}% \write\laxwrite@{@#1^\thepages@3}% \else {\noexpands@ \edef\next@{@@^\csname#1@L\endcsname}% \expandafter\getparts@\next@ \ifodd\count@ \ifnum\count@=1 \expandafter\xdef\csname#1@L\endcsname{\thelabels@2}% \fi \write\laxwrite@{@#1^\thepages@3}% \else \Err@{Label #1 already used}% \fi \% \fi \postvanish@}

For simplicity, we have again used a single group for all constructions that require the \noexpands@. The \write happens to appear in this group, but as before (page 58), that is irrelevant, since the \write only happens during a \shipout.

Finally, we add \pagelabel to \vanishlist@:
Page 39 of the _LMS-TEX_ Manual mentions that for a counter, say '\someccounter', we want to allow such things as

\pagelabel{thispage}number\someccounter}

In version 1 of _LMS-TEX_, special manipulations were required for this, but now both \label and \pagelabel automatically allow this, because in both cases the argument #1 is expanded out in all parts of the definition.

## Chapter 14 Cross-Referencing

### 14.1 Preliminaries

We need a flag \ifreferr@ to tell whether we want error messages or merely warning messages when a (label) #1 for a \ref isn't found:

\newif\ifreferr@true \def\RefErrors\global\referr@true\def\RefWarnings\global\referr@false}

And we want to define a routine that prints either the desired error message or the desired warning message. For TeX version 2, the best we can do is the following, where \W@ from \(\mathcal{M}\)\(\mathcal{M}\)\(\mathcal{S}\)-TeX stands for '\immediate\write16 ':

\ifreferr@\Err@\No\noexpand\label found for #1\else\W@\Waring:No\noexpand\label found for #1.\}\{\if\} (As before, compare section 3.4 for the use of \noexpand.)

But in TeX version 3, we can mimic an error message more closely by printing the line number after the warning, using \inputlineno:

\W@\Warning:No\noexpand\label found for #1.\W@\W@\inputlineno\space... #1}

(We have to settle for '\(\ldots\)' since we can't actually capture the contents of the input line.)

It looks even better to print something like

1.3... \ref\#1\

when a \label for \ref isn't found, and

1.3... \Ref\#1\

when a \label for \Ref isn't found, etc. So we will actually be creating a control sequence with two arguments, the first corresponding to the \ref or)

\Ref, and the second to the \label, so that we will print

\We{Warning: No \noexpand\label found for #2.}

\We{L.number\inputlineno\space... \string#1{#2}}

Since we can't be sure when people will be switching to version 3, it seems best to use different code for the two versions. We can check for the version of TeX with

\setbox0=\hbox{\global\count@='^^30} (here 0 is 'zero', not 'oh')

In TeX version 3, \count@ will then have the value 48, but in TeX version 2, it will have the value 115 (and \box0 will also contain the character 0). Instead of running this test each time we have to print a warning, we will simply let '\versionthree@' be undefined in version 2 and \relax in version 3:

\setbox0=\hbox{\global\count@='^^30}

\ifnum\count@=48 \let\versionthree@=\relax\fi

Then we can use a message of the form

\ifreferr@\Err@{No \noexpand\label found for #2}\else \W@{Warning: No \noexpand\label found for #2.}%

\ifx\versionthree@\relax \W@{L.number\inputlineno\space... \string#1{#2}}\fi

(The \global\count@ assignment here doesn't really contradict the policy of section 1.3 because this \global assignment is made just once, at the top level, not within a macro.)

The simpler looking test

\setbox0=\hbox{\global\count@='^^00}

has all sorts of insidious complications, because in version 3 of TeX, ~~00 stands for the ASCII NUL, which is usually an _ignored_ character in TeX! Since ~~30 is the code for the number 0, it is unlikely to be special.

14.2. \ref and its relatives

14.2. \ref and its relatives.For \ref#1 we simply have to use the test

\expandafter\ifx\csname#1@L\endcsname\relax

to check whether #1 is a label, and then pick out the relevant portion of the value of \csname#1@L\endcsname.

With this in mind, we might first define \nolabel@ by

\def\nolabel@#1#2{\expandafter\ifx\csname#2@L\endcsname\relax

\ifreferr@\Err@\No \noexpand\label found for #2}else

\We{Warning: No \noexpand\label found for #2.}%

\ifx\versionthree@\relax

\We{L.number\inputlineno\space... \string#1{#2}}\fi

\fis

\else}

so that \nolabel@#1#2 would give an error or warning message if #2 hasn't been used as a label, and otherwise do whatever follows. However, it will be a little more convenient to define \nolabel@#1#2#3, with an extra argument, #3, that is often given the value \relax:

\def\nolabel@#1#2#3{\expandafter\ifx\csname#2@L\endcsname\relax

\ifrefer\Err@\No \noexpand\label found for #2}else

\W@{Warning: No \noexpand\label found for #2.}%

\ifx\versionthree@\relax

\We{L.number\inputlineno\space... \string#1{#2}}\fis

\fis

\fis

\else}

We also want a routine that sets a scratch token to the actual value of the control sequence \csname#1@L\endcsname; because this will have to be defined within a group, we use the scratch token \Next@, reserved for \global assignments (page 22):

\def\csL@#1{{\noexpands@\xdef\Next@{\csname#1@L\endcsname}}}

Now \ref#1 should print an error or warning message if #1 is not a (label),

\def\ref#1{\nolabel@\ref{#1}\relax

Otherwise, it should print everything up to the first ~ in the value of the control sequence \csname#1@L\endcsname. If we define

\def\nextii@#1^#2\nextii@{#1}

and also use

\csL@{#1}

to set \Next@ to the value of \csname#1@L\endcsname, then we just have to use

\expandafter\nextii@\Next@\nextii@

So the definition of \ref is

\def\ref#1{\nolabel@\ref{#1}\relax

\def\nextii@\ref{#1}\%

\csL@{#1}\expandafter\nextii@\Next@\nextii@\fi}

Similarly for

\def\Ref#1{\nolabel@\Ref{#1}\relax

\def\nextii@\#1^#2^#3\nextii@{#2}\%

\csL@{#1}\expandafter\nextii@\Next@\nextii@\fi}

and

\def\nref#1{\nolabel@\nref{#1}\relax

\def\nextii@\#1^#2^#3^#4\nextii@{#3}\%

\csL@{#1}\expandafter\nextii@\Next@\nextii@\


### Chapter 15. Reading auxiliary files

Although \readlax is similar to \document, there are a few significant differences.

1. \readlax. \readlax#1 first opens the file #1.lax for reading, giving a conspicuous message if the file isn't found, i.e., if the test \ifeof is true at the beginning. (Note that \document _doesn't_ give a message if \jobname.lax isn't found.) Like \document, it then processes the contents of this file one line at a time, except that it will read the line into the control sequence \nextv#. Again, this is done with a \loop that repeats until \ifeof detects the end of the file.

As with \document, we want to ignore the case where \nextv# is empty. Now, however, we also want to ignore the lines beginning with F, because information about the numbering of footnotes from another file would conflict with information gathered for the current file.

So the definition of \readlax#1 begins

\def\readlax#1{\immediate\openin\laxread@=#1.lax\relax \ifeof\laxread@\We{\}W@{File #1.lax not found.}\We{\}\Vi \endlinechar=-1 \noexpands@ \catcode^\@=11 \catcode^\^=11 \loop \ifeof\laxread@ \else \read\laxread@ to\nextv# \ifx\nextv#empty \else \expandafter\Finit@\nextv#\Finit@ \ifx\nexti# F% \else

When a suitable line \nextv# has been found, we use

\expandafter\getparts@\nextv#

to stores the \label part of \nextv# in \nextiii@, the value of the \type indicator) in the counter \count@, and the rest of \nextv#, except for the initial ^, in \nextiii@.

### 15.1 \readlax

Then we have to use the test

\expandafter\ifx\csname\nexxtiv@@L\endcsname\relax to see if the \label part of \nextv@ has already been used, because this represents a conflicting use of \label, so that we need to issue an error message (remember that \readlax can be used at any time, possibly after some \label's have already been made).

If this test is true, so that the \label does not appear, we will define '\label' to be the remainder of \nextv@, _except that we will change the \type indicator\ to 0 if it is 1 and to 2 if it is 3. For this we can use

\edef\next@{\gdef\csname\nexxtiv@@L\endcsname \[\nextiii@\ifnum\count@=10\else2\fi\] \next@ (within a group with \noexpands@).

As a consequence of this arrangement, any \label from the auxiliary file that we read in with \readlax will count as a "current" label, so that if \label(\label) accounts later in the file we will get an error message, rather than changing the data for this \label. That seems like the reasonable arrangement, since we use \readlax to get information from what is presumably a different part of the same document, and the same \label(\label) shouldn't appear in two different parts of the document (at least, not if we intend to combine the labels in the two parts with \readlax).

Our whole definition is

\def\readlax#1{\immediate\openin\laxread@=#1.lax\relax \ifof\laxread@\W@{\W@{File #1.lax not found.}\W@{\}\fi \[\{\endlinechar=-1 \noexpands@ \catchode^\@=11 \[\loop\ifof\laxread@\else \readlaxread@\to\text{\nonextv@ \}\if\text{\lnextv@\}empty \else \[\verb|expandafter\{\}Finit@\text{\}nextv@\}Finit@ \verb|ifx\text{\}retii@F\% \text{\}\]}else \expandafter\getparts@\nextv@ \expandafter\ifxcsname\nextv@@L\endcsname\relax \edef\nextv@\csname\nextv@L\endcsname {nextiii@ifnum\count@=10\else2\if1}% \nextv@else \Erre\Label\nextv@\spacein#1.\axalreadyused}% \fi \fi \repeat\% \immediate\closein\laxread@} ```
At this point we are finished with all definitions that involve ~ with category code 11:
``` \catcode'\"=\active ```
#### 15.2 Style files

Control sequences to read in style files are simple:
``` \def\docstyle#1{\input#1.st\relax} \def\predocstyle#1{\input#1.st\relax} \def\postdocstyle#1{\input#1.st\relax} ```Part III

Particular

Constructions

Allowing Labels

and their associates


## Chapter 16. Displayed formulas

The next part of La_A_S_-TeX is concerned with displayed formulas and the \tag mechanism; it is the first place where we define \thelabel@.... However, numerous special considerations for \tag are also required, and sections 2 and 3 are the only ones specifically related to the \label mechanism.

_16.1. Invisibility._ An "invisible" construction following a display, in a case like

\label{...}_more text

or even

\label{...}_more text

presents the same problem as an invisible construction following \noindent (section 7.2): The \prevanish@ sets \saveskip@ to Opt (even in the second case, because TeX ignores a space after the \$$ that end a display). Consequently, the \postvanish@ does not skip the space following the \label{...}, and we end up with an extra space before'more text'.

There doesn't seem to be any correction that we can add to \prevanish@ to address this problem, because there is apparently no way to tell when a TeX construction happens to appear immediately after a display. To get around this problem, whenever La_A_S_-TeX encounters the \$$ that begin a display, it calls a control sequence that reads in everything up to the closing \$$ as its argument, and then puts back both this argument and the closing \$$, together with the proper compensating mechanism:

\everdisplay{\csname displaymath \endcsname}

\expandafter\def\csname displaymath \endcsname#1$${\#1$$\FNSS@\pretendspace@}

Note that here we need \FNSS@ (section 3.8), not just \futurelet\next, since we have to skip over any space after the final \$$.

We will introduce the abbreviation

\def\FNSSP@{\FNSS@pretendspace@}

not only because it will save numerous tokens, but also because at one point (section 25.2), it will be essential to have it. So we use

\everdisplay{\csname displaymath \endcsname}

\expandafter\def\csname displaymath \endcsname#i$$\FNSSP@}

The control sequence

\csname displaymath \endcsname

(compare \csname align \endcsname etc., as explained in amstex.doc) shows up on the screen as

\displaymath\

so if a blank line occurs before the closing $$, we will get the error message

! Paragraph ended before \displaymath\null\was complete.

[If we defined \displaymath\null\ to be \long, we would get basically the same error message that TEX normally gives,

! Missing $ inserted.

but it would be presented in a much more confusing way, since "context lines", involving the argument of \displaymath\null, would also be presented.]

\begin{tabular}{c} Notice that a construction like

\$.. $$ \\ \bye \\ \end{tabular}

16.1. Invisibility

will eventually \let\next=\bye and then call \pretendspace@, which uses the test \ismember@\vanishlist@\next. If \bye were \outer we would get an error message

! Forbidden control sequence found while scanning use of \ismember@.

Unlike the situation for \noindent (section 7.2), which is presumably used only when some text is going to follow, if we have something like

A line of text.

$$

\label{...}

Another line of text.

the \hskip-ipt\hskipipt added by the \prevanish@ in \label will have a dire effect: it will cause a _blank line_ to be typeset after the display. Since there will be \baselineskip glue before this blank line, the next line, 'Another line of text.' will be separated from the display by too much space.

But there's really nothing that can be done about this. Even in plain TEX,

A line of text.

$$

\write{...}

Another line of text.

will create a spurious blank line after the display. So users just have to be warned against using "invisible" constructions after a display that ends a paragraph.

Because of this (admittedly convoluted) approach to this (admittedly rather special) problem, constructions that change category codes won't work within a displayed formula. If that needs to be allowed (as it sometimes was for the \_M_S-TEX Manual), one can

\def\Math{\begingroup\everyday\$$}

\def\endMath{$$}endgroup\futurelet\next\pretendspace@}




### 16.3 \tag

As in the case of \pageOF (page 51), we use \def\tagOF{\rm} rather than \let\tagOF=\rm, so that \fontstyle\tag will work correctly. In \tag\gs we specified roman parentheses even if\tagOF is changed (compare page 54); of course, \tag\gs could be changed if we didn't want this.

Unlike the situation for \page\W, we can \let\tagON=\arabic, because \tag\gs\W appears only in certain \xdef's (page 106), and then this value of \tag\W will simply disappear, resulting in a shorter string than if we kept \arabic unexpanded.

**NOTE: Nevertheless, we must use \def instead of \let for other numbering styles.** Note that \newnumstyle does this (Chapter 24).

\(\mathcal{A}\_{\mathcal{N}}\)-TEX already defines the combination \tag\tig\tig\tig\tig\t to be \leqno or \eqno followed by \maketag@\t\maketag\gs, and we just have to redefine \maketag\gs for \(\mathcal{A}\_{\mathcal{N}}\)-TEX, although the argument \(\tig\) will now have a rather different significance: in \(\mathcal{A}\_{\mathcal{N}}\)-TEX, \(\tig\) would be the tag number that we want to use, but now \#1 could instead involve things like \label or \pagelabel, or even \Reset\tag (to affect the next \tag), as well as a "quoted" tag number "\(\cdots\)", again followed by things like \label or \pagelabel.

The action of \maketag\ will depend on whether or not it is followed by a " for a "quoted" \tag.

\def\maketag@{\futurelet\next\maketag@\gs} However, for reasons that will be explained in section 4, if \maketag\gs is followed by \relax\({}^{\rm in}\_\cdots\)" we will want to get the same result as if it were followed simply by \({}^{\rm in}\_\cdots\)". So we will call \maketag@\gs@\gs\gs\gs\gs\gs\gs\gs\) if \maketag\gs is followed by \({}^{\rm in}\) and \maketag@\gs\gs\gs\gs\gs\gs\) if it is followed by anything else other than \relax. But if \maketag\gs\gs\gs\gs\) is followed by \relax, we call a control sequence that swallows this \relax and then reiterates the process:

\def\maketag@1. First we globally advance the tag counter, tag@C, by one.
2. Then we \xdef the values of \Thelabel@,..., \Thelabel@@@@@ appropriately, using the current values of \tag@C, \tag@P, etc.
3. Then we use \locallabel@ to (locally) set the values of \thelabel@,..., \thelabel@@@@.
4. Then we actually typeset the tag, using \tag@S for the style, and in the font \tag@F (which will be irrelevant if we have \TagsAsMath).

In step 2 we will be doing something like

\noexpands@ \xdef\Thelabel@@@@{number\tag@C} \xdef\Thelabel@{\tag@N{\Thelabel@@@@@}} \xdef\Thelabel@@@@@@{\ifmathtags@$\tag@P\Thelabel@\tag@Q\else \tag@P\Thelabel@\tag@Q\fi} \xdef\Thelabel@@@@{\tag@S\Thelabel@@@@@@}}

All of the \LMS-TEX constructions that can be given a \label will define \Thelabel@,..., \Thelabel@@@@ in much the same way (with \tag@C replaced by the suitable \...@C counter, etc.). Consequently, it is worth introducing an abbreviation for the steps defining \Thelabel@ and \Thelabel@@:

\def\xdef\Thelabel@@#1{\xdef\Thelabel@{\#1{\Thelabel@@@@}}} \def\xdef\Thelabel@@@#1{\xdef\Thelabel@@@{\#1{\Thelabel@@@}}}

Thus, we define \marketag@@@@ by

\def\marketag@@@@@#1\marketag@@{\global\advance\tag@C by 1 \{\noexpands@ \xdef\Thelabel@@@@{number\tag@C}% \xdef\Thelabel@\tag@N \xdef\Thelabel@@@@{\ifmathtags@ \$\tag@P\Thelabel@\text@{\ttag@}@\}else \tag@P\Thelabel@\text@{\ttag@}@\}\% \xdef\Thelabel@@@{\tttag@S \} \}\% \}\]
### 16.3. \tag

\locallabel@ \hbox{\tag@F\thelabel@@}%
#1}

When \tag is followed by ", it might occur in constructions like

\tag "\style{...}" or \tag "\style{\pre 3}" etc.,

involving any of \pre, \post, \style, or \numstyle. In such situations, \pre must be interpreted as \tag@P, etc., when the tag is printed,

\let\pre=\tag@P \let\post=\tag@Q \let\style=\tag@S \let\numstyle=\tag@N \hbox{\tag@F...}

Moreover, \Thelabel@,..., \Thelabel@@@@@ must be suitably interpreted.

For this we use a routine that is also used by many other constructions:

\def\Qlabel@#1{{\noexpands@\xdef\Thelabel@@@{\#1}% \let\style=\empty\xdef\Thelabel@@@@{\#1}% \let\pre=\empty\xdef\Thelabel@{\#1}% \let\numstyle=\empty\xdef\Thelabel@@{\#1}}

For example, \Qlabel@{\#1} for \tag"#1" will be used after we have \let\pre=\tag@P, etc. So

(1) \Thelabel@ (which is what \Ref is supposed to produce), will give #1, with \pre interpreted as \tag@P, etc.

(2) \Thelabel@@@@ (what \pref is supposed to produce), will be the same, except \style will be ignored if it appears, since \pref is supposed to produce what \Ref produces, but without any of the \style formatting.

(3) \Thelabel@ (what \ref is supposed to produce), also ignores \pre and \post if they appear.

(4) \Thelabel@@@ (what \pref is supposed to produce), also ignores \numstyle if it appears.

\def\marketag@@@@"#1"#2\marketag@@{% {\let\pre=\tag@P \let\post=\tag@Q \let\style=\tag@S \let\numstyle=\tag@N \hbox{\tag@F#1}% \noexpands@@ \Qlabel@@{\#1}% \% \% locallabel@@ \#2} ```
It might seem unlikely that any one would use a \label for a "quoted" \tag, since then the tag is already known. But the label mechanism is provided nevertheless, and might even be of some use. For example,
``` $$... \tag"\style{\pre A}"\label{tagA}$$ might be used to produce the tag '(3.A)', where the user wouldn't know what precedes the 'A'. In this case, \Ref{tagA} or \pref{tagA} would be needed to print '(3.A)' or '3.A' in the text.

Because of the \def's in \Qlabel, any "quoted" number "..." following \tag (or any other construction that allows a (label)) must contain only things that can safely be used in \xdef's when \noexpands@@ is in force.

As a far-fetched example, in this manual Chapter 11 was labelled 'STARTLABEL' and Chapter 15 was labelled 'ENDLABEL'. If the next chapter were commentary on these chapters, and for some reason we wanted this commentary to be called

**Chapter 11'-15'. Remarks on Labels and Cross References**

we wouldn't be able to type

\chapter "\nref{STARTLABEL}$'$--\nref{ENDLABEL}$'$" Remarks...

Instead, we would have to use something like

\Evaluatenref{STARTLABEL} \edef\startlabel{\nref} \Evaluatenref{ENDLABEL} \edef\endlabel{\nref} \chapter "\startlabel$'$--\endlabel$'$" Alternate...





### 16.4. \align

Note that in a formula like

\align (formula) \newpre\tag{a}tag... \ \ where there is a line without any &, the definition of \tag in \align(page 110) means that this line will be interpreted as

\(formula) \newpre\tag{a}& \omit\global\rwidth@=Opt &\relax \repropost@ \maketag@...\maketag@ \cr} The \prepost@ in the first part of the preamble for \align globally defines \tag@P@ to be 'a', and the \repropost@ then makes \tag@ properly defined for \maketag@. But if the \omit were not inserted, then the \prepost@ for the _second_ part of the preamble would globally redefine \tag@P@ to be the default value of \tag@P, so that the new value would not be properly propagated to the \maketag@ part of the preamble.

Since we've added the \omit, we also have to add \global\rwidth@=Opt, which would normally be set by an empty formula. The extra clause

\ifdim\rwidth@>\marrwidth@ \global\marrwidth@=\rwidth@\fi appearing in the definition of \measure@ doesn't have to be duplicated, since it would be inoperative for an empty formula.

The \tabskip\centeringering@ also appears after the first & in the preamble, but we don't have to worry about that: once the preamble has been read, the various \tabskip glues are determined, and they remain the same for any row, even those that have \omit's in them.

(The \global\advance\and@ by 1' will also be omitted because of the \omit, but this is irrelevant, since the current value of \and@ has already been used to determine properly the meaning of \tag.)

The re-definition of \align\is exactly analogous:

\expandafter\def\csname align \endcsname@\endalign {\measure@#1\endalign\global\and@=0



}

\iftagsleft@ \toks@@={\tabskip\centering@&\Tag@\kern-\displaywidth \(\verb|rlap@{\@lign|\repprost@} \verb|maketag@\the\hashthoks@\maketag@)% \global\advance\and@ by 1 \tabskip\displaywidth\else \toks@={\tabskip\centering@&\Tag@ \verb|llap@{\@lign|\repprost@\maketag@ \verb|tthe\hashthoks@\maketag@}\global\advance\and@ by 1 \tabskip\z@skip}\fi \atcount@#1\relax\advance\atcount@ by -1 \loop\ifnum\atcount@>0 \toks@=\expandafter\{\the\thoks@\&\hfil \$\m@th\displaystyle\{\@lign|\the\hashthoks@\prepost@}\% \global\advance\and@ by 1 \tabskip\z@skip\$\m@th\displaystyle\{\}@lign|\the\hashthoks@ \verb|prepost@}\$\hfil \ifxat@\tabskip\centering@\fikglobal\advance\and@ by 1\% \advance\atcount@ by -1 \repeat \verb|xdef\preamble@{\the\thoks@\the\thoks@}\% \verb|xdef\preamble@@@\{\preamble@}\% \let\maketag@=\maketag@\letTag@=\{TAG@} \let\prepost@=\Prepost@\{\verb|Met\repprost@=\{\Reprepost@}\}

Now we must modify the definition of '\alignat\({}^{}\), which is called by \alignat, in several ways:

1. \tag must mean &\relax;
2. More generally, \tag must mean &\omit&\relax if used when one & has been omitted, or &\omit&\omit&\relax if used when two &'s have been omitted, etc.

Fortunately, when we define \tag for \alignat and \xalignat we don't have to worry about additional things appearing in the preamble, as was necessary for \align. On the other hand, whereas the first pass for \align simply had \eat@{\#} in the preamble for the \tag part, \alignat and \xalignat have \maketag@\




and to define \foo we use the same strategy that was used in section 3.2:

\def\next@{\def\noexpand\foo{\futurelet\noexpand\next} \csname\existing@\foo@Z\endcsname}} \next@

Now \foo@Z should increase the counter \foo@C by 1, and print the properly formatted number, in the proper font:

\def\foo@Z{\global\advance\foo@C by 1 \foo@F\foo@S{\foo@P{\foo@N{\number\foo@C}}foo@Q}}

(for the moment, let's not worry about how \foo@G,...are to be defined).

Moreover, if \foo is followed by \label{...}, then we need a way of getting this \label{...} properly recorded. To do this, we can simply use the code

\noexpands@\xdef\label@{...}...} \localabel@{...}

The \label in the second group will make sense, because the \locallabel@ will define \thelabel@; this \label will thus write to the.lax file, and append to \laxlist@. After the group containing \locallabel@ is finished, however, any values of \thelabel@,...will be restored to their previous values, so another \label will give an error message (unless \foo happens to appear within some other construction that itself allows a \label).

\def\foo@Z{\global\advance\foo@C by 1 \foo@F\foo@S{\foo@P{\foo@N{\number\foo@C}}foo@Q}}% \if\next\label \def\next@\label##1{\% \noexpands@ \xdef\label@{...}...\xddef\label@@@@{...}}% \locallabel@\label{##1}}% \else \let\next@=\relax \fi \next@}

### 17.1 \newcounter

Of course, these ##'s will all have to be *****s, since this whole definition appears within the definition of \newcounter. But that's only a minor problem. We are also going to have to treat this whole thing with an \edef\next@ (compare page 17), so it is going to look pretty complicated (in particular, now our *****s will all have to be *****s*s, since an \edef changes ## to #).

The control sequence \foo@C will be specified within this \edof\next@ as

\csname\exstring@\foo @C\endcsname and similarly for \foo@P,... In all cases, TEX will make these equivalent to \relax, so they will not be expanded further.

Finally, after all this, we can create \foo@C,...with their proper meanings,

\expandafter\newcount@\csname\exstring@\foo@ C\endcsname \expandafter\let\csname\exstring@\foo @N\endcsname=\arabic

Note that here we use \newcount@ (section 3.6), since it appears within a definition, and thus might be used after \alloc@ has been returned to its old definition. Note also that we use \let rather than \def, just as with \tag (page 17), but \def would be required for anything other than \arabic (and is supplied whenever \newnumstyle is used).

In the following code for \newcounter, note that \noexpand is required before \number, \ifx, \else and \fi because these primitives are "expanded" in an \edef:

\def\newcounter#1{\define#1{\% \edef\next@\def\noexpand#1{\futurelet \noexpand\next}csname\exstring@#1@Z\endcsname}\next@\def\{\def\csname\exstring@#1@Z\endcsname \{\global\advance}csname\exstring@#1@C\endcsname by 1 \csname\exstring@#1@F\endcsname \csname\exstring@#1@S\endcsname{\csname}exstring@#1@N\endcsname \(\{\noexpand\number\csname\exstring@#1@C\endcsname\}\% \csname\exstring@#1@Q\endcsname\}\% \noexpand\iff\nexpand\next\noexpand\label


### 17.2. \usecounter

Here we want

\example  to give {it Example \exno.}\\\\\\example"..."  to give {it Example {\exno@F......}.\\\\example\label{...} to give {it Example \exno\label{...}.\\\\\\\\} where \_ \_ \_ stands for

\let\pre=\exno@P... \let\numstyle=\exno@N

In the third case, the combination \exno\label{...} will itself take care of printing the right number, and labelling it.

Page 79 of the \(\LAN^{}\)-TEX Manual suggest that the user should modify (*) to read

\usecounter\exno\example#1{{\it Example #1.}\\\ignorespaces}

But that's silly--it's clearly better to have \usecounter automatically add the \ignorespaces. Actually, we really need to add \FNSSP( page 100) for cases where \ doesn't appear at the end of the definition, but an invisible construction, like \pagelabel, occurs after the use of the construction being defined.

So we really want

(E1)\example

to give {it Example \exno.}\FNSSP(E2)\example"..."

to give {it Example {\exno@F......}.\\FNSSP(E3)\example\label{...}

to give{it Example \exno\label{...}.\\\FNSSP(E4)

Clearly, \example is going to involve a \futurelet, so we expect that \usecounter\exno\example should expand out to something like

\def\example{\futurelet\next\exno@Z}

[Note that the subsidiary control sequence \exno@@Z is written entirely in terms of \exno. So if we later type

\usecounter\exno\otherexample

\otherexample will then be defined exactly the same way, as

\futurelet\next\exno@@Z

--though of course \exno@@Z will now end up being defined differently. This is a reasonable arrangement, since the same counter \exno shouldn't be allowed for two different constructions.]

In the use

\usecounter\exno\example#1{{\it Example #1.}}

we also have to somehow capture the \parameter text and \replacement text). This suggests that \usecounter\exno\example should expand out as

\def\example{\futurelet\next\exno@@Z}

\def\exno@@Z@ at the end will then swallow up the subsequent \parameter text) and \replacement text), and thus, in our case,

\def\exno@@Z@#1{{\it Example #1.}}

Once we have \exno@@Z@, it is easy to say what \exno@@Z should do:

(1) If \next is neither \label nor ", then (E1) we want

{\it Example \exno.}\FNSSP@

which can obtained as

\exno@@Z@{\exno}\FNSSP@

#### 17.2. \usecounter

(2) If \next is ", so that we have \example"...", then (E2) we want

\it Example {\exno@F \let\pre=\exno@P... \let\numstyle=\exno@N... }.\\FNSSP@

which can be obtained as

\exno@Z@{{\exno@F \let\pre=\exno@P... \let\numstyle=\exno@N...}}\FNSSP@

(3) If \next is \label, so that we have \example\label{...}, then (E3) we want

\it Example \exno\label{...}.\\FNSSP@

which can be obtained as

\exno@Z@{\exno\label{...}}FNSSP@

Thus, we want \usecounter\exno\example to expand as

\def\example{\futurelet\next\exno@Z}

\def\exno@Z{\ifx\next\label

\def\next@\label##1{\exno@Z@

\exno\label{\#1}\FNSSP@}

\else

\ifx\next"\def\next@"\##1"{\exno@Z@

\{\exno@F...\#1}}\FNSSP@}

\else

\def\next@{\exno@Z@{\exno}\FNSSP@}

\if\if\next@}

\def\exno@Z@

The general definition of \usecounter has the same features as that for \newcounter, with several \edef\next@'s. But there are some complications.

)

First, we need a way of inserting the

\exno@F

which we will specify as

\csname\exstring@#1@F\endcsname

except that after this is expanded to \exno@F, which is now _not_\relax, we need to inhibit further expansion of this \exno@F. This can be done with

\expandafter\noexpand\csname\exstring@#1@F\endcsname

because the primitive \expandafter is "expanded" in an \edef: the \csname...\endcsname is first expanded to \exno@F, and then this expansion is placed in front of \noexpand, and consequently _not_ expanded in the \edef!

Similar maneuvers are needed for \exno@P...; our \edef\next@ will

\let\noexpand\pre=

\expandafter\noexpand\csname\exstring@#1@P\endcsname

In addition, the control sequences \exno@Z and \exno@Z@ might already exist, if '\usecounter\exno' has already appeared (compare page 124). In this case, the control sequences

\csname\exstring@#1@0Z\endcsname

\csname\exstring@#1@0Z@\endcsname

would also _not_ be \relax, and therefore they would be expanded in \edef's, probably with disastrous results. So we will simply \let them be \relax to begin with.

Finally, we want to add an error message at the beginning if the first argument of \usecounter hasn't already been created by \newcounter.

\def\usecounter#1#2\expandafter

\ifx\csname\exstring@#1@Z\endcsname\relax

\Err@{\noexpand#inot created with \string\newcounter}\fi

\expandafter\let\csname\exstring@#1@Z\endcsname=\relax

\expandafter\let\csname\exstring@#1@Z@\endcsname=\relax




For the use of \noindent@@, see Chapter 8. Notice that if \everpar is non-empty, then new paragraphs within an \item (like the one shown on page 17 of the \(\mathit{\LAR}\mathcal{S}\)-\(\mathit{\LAR}\mathcal{\mathbbm{X}}\) Manual), will have this \everpar material before them. (If we wanted to prohibit that, we could simply set \everpar={} right after the \begin{tabular}{} \end{tabular}  the \begin{tabular}{} \end{tabular}  the \begin{tabular}{} \end{tabular}  the \begin{tabular}{} \end{tabular}  the \begin{tabular}{} \end{tabular}  simply causes the \item number to appear \begin{tabular}{} \end{tabular}  the left of the rest of the text; \begin{tabular}{} \end{tabular}  similarly, \itemii@ formats an \item number at the second level in 
\begin{tabular}{} \end{tabular}  exactly the same way; \(\ldots\).

**D.** Finally, we have some control sequences that are numbered differently:

1. \liste@ will be the formatting (usually vertical spacing and/or penalties) that goes at the end of the last \item at the _first_ level;
2. \listei@ will be the formatting that goes at the end of the last \item at the _second_ level; \(\ldots\).
3. \listeiv@ will be the formatting that goes at the end of the last \item at the \item level.

Thus, for reasons that will become clear (page 137) these control sequences are "numbered" one less than the level to which they apply.

\(\mathit{\LAR}\mathcal{S}\)-\(\mathit{\LAR}\mathcal{\mathbbm{X}}\) sets the default values

\(\{\)def\liste@{}penalty-50 \medskip\(\}\)

\(\{\)def\listeie@{}penalty-100 \smallskip\(\}\)

\(\{\)let\listeiei@=\relax\(\}\)

\(\{\)let\listeieiii@=\relax\(\}\)

\(\{\)let\listeiv@=\relaxThus, (D.1)liste@ will produce \penalty-50 \medskip at the end of the list; (D.2)listei@ will produce \penalty-100 \smallskip when we go from the end of the second level of the list back to the first level; but nothing will be added when we go from the end of the third level back to the second level, etc.

_18.2. Counters, etc._ Next we must create the counters '\list@C1',..., '\list@C5', which we initialize to 0:

\expandafter\newcount\csnamelist@C1\endcsname \csnamelist@C1\endcsname=0

We want '\list@C1', '\list@C2',..., in conformity with a general \(\LAM\$\)-TeX principle for handling constructions with more than one counter (see Chapter 24), but we use \listbi@, \listbi@,..., because there are a fixed number of such control sequences, which we will usually be mentioning explicitly, so there's no need to complicate matters by using names that combine letters and numbers.

Just as we use '\...@C1',..., '\...C5' to indicate counters at various levels, we also use '\...@P1',...for the pre-material at the various levels, and '\...@Q1',...for the post-material at the various levels. We initialize all of these to be empty:

\expandafter\let\csnamelist@P1\endcsname=\empty \expandafter\let\csnamelist@Q1\endcsname=\empty

Then come the styles at each level (compare page 74):

\expandafter\def\csnamelist@S1\endcsname#1\{\rmrm(\}\#1\/\{\rm\rm\{\rm\{\rm\{\rm\{\rm\{\}} \}\}}\}\}\)

Note that these styles determine the formatting of an item number, but the spacing after the formatted number is determined by \itemi@,... (page 130).

In conformity with this, style control sequences in \(\L_{\Psi}\mathcal{S}\)-TEX never address the question of the spacing after the formatted number, which has to be handled separately.

Then come the numbering styles at each level:

\expandafter\let\csname list@N1\endcsname=\arabic

Note that here we once again use \let rather than \def, just as with \tag (page 105), but \def would be required for anything other than \arabic.

Finally, we also need the font styles at each level:

\expandafter\def\csname list@F1\endcsname{\rm}

There will be occasions when we want to refer to the list counter, etc., for the current level, without having to know or to specify this level explicitly. For this purpose, we first create a counter;

\newcount\listlevel@

\listlevel@=0

which will always hold the current list level, and then we

\def\list@@C\csname list@C\number\listlevel@\endcsname}

\def\list@OP\csname list@P\number\listlevel@\endcsname}

\def\list@O@\csname list@Q\number\listlevel@\endcsname}

\def\list@O@S\csname list@S\number\listlevel@\endcsname}

\def\list@O@\csname list@N\number\listlevel@\endcsname}

\def\list@OF\csname list@F\number\listlevel@\endcsname}

so that, for example, \list@O@C will be '\list@C1' if we are at the first level, '\list@C2' if we are at the second level, etc.

#### Other preliminaries

Since, as we've already indicated in section 1, the first \item at each level needs to be treated specially, we need flags


although the L_M_S_-TEX Manual mistakenly indicated the usage

\continuelist

\item

\endlist

(which would conflict with the general 'foo... \endfoo' convention for L_M_S_-TEX constructions). This was a natural mistake to make, however, so now '\continuelist' has been replaced by '\keepitem'.

\keepitem itself will simply set a flag,

\newif\iflistcontinue@

\def\keepitem{\listcontinue@true}

while \endlist will always reset \listcontinue@false.

#### 18.4. \list

Unlike the case of \tag, whenever we start a \list we want to reset the list counters '\list@C1',... to 0, except if \keeping is in force, in which case '\list@C1' will not be changed. Then we want to begin a group, set \firstitemi@true, set the list level counter to 1, and define \item in terms of a \futurelet, since it needs to see if a "quoted" number follows:1

\def\list{%

\iflistcontinue@\else

\global\csname list@C1\endcsname=0

\fi

\global\csname list@C2\endcsname=0

\global\csname list@C3\endcsname=0

\global\csname list@C4\endcsname=0

\global\csname list@C5\endcsname=0

\begingroup

\firstitemi@true

\listlevel@=1


is something like 'Opt plus 1pt', with only stretchable space. In this situation, it is inadvisable to leave the stretchability, for, on a page requiring a fair amount of vertical stretching, this interparagraph stretch might easily end up looking too big compared to the other spacing that the style selects for \list's (I speak from experience!). This stretchability can be eliminated with the code

\dimen@=\parskip \parskip=\dimen@ (since \dimen@ is a dimension, the first assignment sets \dimen@ to the non-stretchable part of \parskip, and the second assignment resets \parskip to this non-stretchable part).

So the definition of \list@ might be

\def\list@{\ifx\next\runinitem \def\next@\runinitem{\futurelet\next\runinitem@}\else \def\next@{\par\dimen@=\parskip\parskip=\dimen@}\if\next@}

That's not quite good enough however, because we also want to allow a blank line before the \runinitem, since blank lines are generally allowed before \item's.1

Footnote 1: On the other hand, there’s no way we can allow a blank line to occur before \list in a ‘\list\runinitem’ combination; when a run-in \item is required, the \list must appear in the same paragraph as the previous text.

So if \next happens to be \par, we will call a construction that swallows this \par and then repeats the \futurelet\next\list@:

\def\list@{\ifx\next\par \def\next@\par{\futurelet\next\list@}\else \ifx\next\runinitem \def\next@\runinitem{\futurelet\next\runinitem@}\else \def\next@\par\dimen@=\parskip\parskip=\dimen@}\% \ifif\next@}

Leaving aside the definition of \runinitem@ for the moment, we consider the case where \item occurs next.

18.5.itemitemitem has already been set to \futurelet\next\item@. Before worrying about whether a quoted \item number follows, \item@ will take care of any needed formatting. This will involve two new flags

\newif\ifoutlevel@ \newif\ifrunin@

The first will be true if the \item was preceded by \outlevel (so that \item's at a higher level have just been completed). The second will be true if the present \item follows a \runinitem at the same level.. In either of these cases, the appropriate flag for first \item's at this level (\iffirstitemi@ or \iffirstitemi@ or \.) will be _false_.

The first thing \item@ adds is

\ifoutlevel@\List@\outlevel@false\fi

So, for example, if our \item occurs at the top level (\listlevel@ = 1), and we have just completed \item's at the second level, we will add \listei@-- recall (page 130) that this is the formatting that goes at the end of the last \item at the _second_ level.

The reason for this approach is that in a situation like

\list \item... \inlevel \item... \inlevel \item... \item... \item... where we go from third level \item's right back to first level \item's, the spacing before that next \item at the first level should be the spacing that goes after _second_ level items, not the spacing that goes after third level items (and certainly not the sum of the spacing that goes after the second and third levels). So we don't want the spacing to be put in by the \outlevel's; instead \outlevel will just set \outlevel@true, for use by \item.

Next, we consider the case where \ifrunin@ is true. In this case, we simply want to set \runin@false, end the current paragraph (which contains the previous \runinitem, which has not been indented any extra amount), add the same adjustments that were made for \list@, in case we are at the first level, and then add \Listm@ (the \listm...@ for the current level) to apply to the remaining \item's at the current level:

\ifrunin@\runin@false\par \dimen@=\parskip \parskip=\dimen@ \Listm@\fi

If neither of these cases occurs, we have to consider the possibility that the \item was the first at its level. At the first level, this means that we will add

\listbie \listmi@

if \iffirstitemi@ is true, also setting \firstitemi@false, but simply add a \par for other items:

\iffirstitemi@ \listbi@\listmi@\firstitemi@false \else\par\fi

Note that \listbi@ will be occurring after a \par supplied by \list, via \list@, or by \outlevel (section 8).

Analogous code is added for the situation where we are at the second level (\iffristitemii@...\fi); in this case, \listbi@ will be occurring after the \par supplied by the previous code. And similarly for the third through fifth levels.

Each of these \iffristitem...@ tests has to be made separately, and \listbi@,... appear only in such constructions; that is why there is no point having a \Listb@' construction.

We will use compressed format, as well as the K-method, for \item@, so that the definition ends

\ifx\next"\expandafter\next@\else\expandafter\nextii@\fi


would leave an extra space before the "Text...". The \pretendspaces@'s take care of this. In the case of \nextii@ we don't need FNSSP@, since a space token won't appear after \item (compare \endMath, page 102).

It should perhaps also be noted that something like \let\pre=\list@@P does not actually make \pre have the value of the appropriate '\list@P1' or '\list@P2' or..., but simply makes \pre expand out to the definition of \list@P, i.e., to

\csname list@P\number\listlevel@\endcsname

This is adequate, however, since we are not storing this value of \pre for later use: when this \pre gets used, either in printing the number,

\list@@F##1}

or in the \xdef's involved in

\Qlabel@{##1}

the current value of \list@P1' or '\list@P2' or..., will be inserted.

Thus, the definition of \item@ is:

\def\item@\% \ifoutlevel@\List@\outlevel@false\fi \ifrunin@\runin@false\par \dimen@=\parskip \parskip=\dimen@ \Listm@\fi \iffrstitemi@ \listbi@\listmi@\firstitemi@false \else\par\fi \iffrstitemiie@ \listbi@\listmi@\firstitemi@false \else\par\fi \iffrstitemiie@ \listbi@\listmi@\firstitemi@false \else\par\fi \iffrstitemiie@ \else\par\fi \iffrstitemiiv@\firstitemi@false \else\par\fi


) def\nnexti@{\global\advance\list@@Cby1 {\noexpands@ \xdef\Thelabel@@@@{\number\list@@@C}% \xdef\Thelabel@\list@@@N \xdef\Thelabel@@@@{\list@@@P\Thelabel@\list@@@Q}}% \xdef\Thelabel@@@\list@@@S \% \locallabel@@ \unskip\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\}\]

In other words, after suitably defining \\thelabel@,..., we leave a space after the preceding text, and then print the \item number, either as explicitly quoted, or as supplied automatically, and then add a space. In the case of \runinitem"..." we have to ignore any space that follows the "...". Notice, however, that in neither case do we have to worry about invisible constructions that follow, since now a real space has been inserted.

Thus, the definition of \runinitem@ reads:

\def\runinitem@{\ \runin@true \Firstitem@false \def\next@##1{{\let}pre=\list@@@P\let\post=\list@@@Q \let}style=\list@@@S\let\numstyle=\list@@@N \unskip\spacespace\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\space\}\]

\noexpands@ \(\verb|@\@label@@|\@{\#1}\%\) \locallabel@@ \ignorespaces\% \def\nextii@@{\global\advance\list@@@Cby1 \{\noexpands@@ \xdef\Thelabel@@@{\number\list@@@C}% \xdef\Thelabel@@@\list@@@N \xdef\Thelabel@@@@@@{\list@@@P\Thelabel@@@\list@@@Q}}% \xdef\(\verb|\@label@@@\{\verb|\@label@@@\{\verb|\@label@@@Q}}\verb|\{\verb|\@label@@@Q}}\verb|\{\verb|\@label@@@Q}}\verb|\{\verb|\@label@@@S}}%


\outlevel. Similarly, \outlevel gives an error message if we are at level 1. Otherwise, we want to end the paragraph and provide an \endgroup to match the \begingroup provided by the previous \inlevel. Nothing has to be done to \listlevel@, since it will simply return to the value it was already given before this new group had been entered. Note that it is important to end the paragraph before the \endgroup; otherwise, the current value of \leftskip provided by \Listm@ would no longer be in force when the paragraph ended. In addition, before the \endgroup we need to globally reset the counter for the current level back to 0 (in case we go down to this level by another \inlevel). Finally, we want to set \outlevel@true, for use by the next \item (page 137 ff.).

\def\outlevel{\ifnum\listlevel@=1 \Err@{At top level}\else \par\global\list@@@C=0 \endgroup\outlevel@true\fi}

\endlist. \endlist first ends the current paragraph:

\def\endlist{\par...

Note that it's quite possible for \endlist to occur after several consecutive \inlevel's--there may not be \outlevel's to match all these \inlevel's. Consequently, \endlist must not only supply an \endgroup to match the \begingroup supplied by \list, but it must also supply enough \endgroup's to match any \inlevel's that do not having matching \outlevel's; this is accomplished by the following code:

\global\toks1=C\% \count@=\listlevel@ \loop \ifnum\count@>0 \global\toks1=\expandafter{\the\toks1 \endgroup}% \advance\count@ by -1 \repeat\ \the\toks1

(The possibility that an \inlevel does not have a matching \outlevel is the reason why we reset the counters for all levels at the beginning of a \list[page 134], even though \outlevel resets the counter for its level [see the previous page].) The \loop is enclosed within a group for the unlikely eventuality that some \list...\endlist occurs within a \loop construction (compare page 137). Because of this, we need a \global assignment of the token list, so we use \toks1 (compare section 1.3); and for consistency, we begin with the \global assignment \global\toks1={}. We don't make an abbreviation for \toks1 because it is used so infrequently.

The \endgroup's are followed by

\liste@

(page 130), and then by

\listcontinue@false

since \listcontinue@true is set by \keeplisting, which appears before a \list.

The final step is to take care of the fact that a \list...\endlist is not supposed to start a new paragraph at the end, unless a new paragraph actually appears in the file. For this we add

\vskip-\parskip

\noindent@@@

If text follows immediately after the \endlist, it will start an unindented paragraph, with no extra space, except that provided by \liste (and so it will appear that the \list...\endlist has merely "interrupted" the paragraph).

On the other hand, when \endlist is followed by a \par or blank line before new text, so that we have

\vskip-\parskip

\noindent@@

\par

the "empty paragraph" \noindent@@@...\par doesn't produce a blank line, but we do get \parskip glue inserted before the \noindent@@@ and _also_ before the text following the \par. Together with the \vskip-\parskip, this meansthat the following text, which will start a new paragraph, will have the usual \parskip glue before it.

There is just one further detail: We need to add

\futurelet\next\pretendspace@

in case an invisible construction like \pagelabel happens to appear after the \endlist (compare page 139).

Thus, the definition of \endlist is:

\def\endlist{\par \global\toks1={}% \count@=\listlevel@ {\loop \ifnum\count@>0 \global\toks1=\expandafter{\the\toks1 \endgroup}% \advance\count@ by -1 \repeat}% \the\toks1 \liste@ \listcontinue@false \vskip-\parskip \noindent@@ \futurelet\next\pretendspace@}

As on page 100, note that if \bye were \outer, then \endlist\bye would give an error message.

Notice that a \par after \endlist doesn't have to appear explicitly for all this to work. For example, something like

\list \endlist \section{...}

where \section starts a new paragraph, will behave correctly. Consequently, this approach is preferable to one that would use a \futurelet to see if a 

#### 18.9 \endlist

\par comes next (such uses of \futurelet in sections 4 and 7 were quite different--they were meant only to _skip over_ any \par's that might appear). If somewhat different design decisions are required for the spacing after the \endlist, we could, for example, use

\edef\parskip@{\parskip=\the\parskip}

\parskip=(dimen1)

\noindent@@

\futurelet\next\pretendspace@

[The construction

\edef\parskip@{\parskip=\the\parskip}

is similar to the construction

\edef\@sf{\parskip2\generator}

used in plain TeX: the primitive \parskip is not expanded in the \edef, but '\the' _is_ expanded, so \parskip@ means

\parskip=(current value of \parskip)'

after the \edef is finished.]
**Chapter 19**.: \describe and \margins

Although \describe and \margins don't really come next by any logical imperative, they come next in \_IAS-TEX_ because they are so similar to \list.

_19.1._ \describe. Since \describe has only one level, it is simplest to incorporate all necessary style decisions directly into the definition, without using subsidiary control sequences like \listbi@, etc. In addition, \describe is much less complicated than \list because nothing gets numbered, \describe doesn't have to check for a \runinitem, and \item's in a \describe don't have to check to see if a " follows.

We require just one flag, for the first \item in a \describe:

\newif\iffirstdescribe@

\describe can immediately end the previous paragraph (unlike \list, which has to worry about a \runinitem following); then, like \list, it begins a group and sets \firstdescribe@true. (The default style doesn't bother adding \dimen@=\parskip \parskip=\dimen@', but other styles might want to add that here.) Then it simply has to define \item within \describe, which is simply a control sequence with an argument:

\def\describe\par \begingroup \firstdescribe@true \def\item##1\% \iffirstdescribe@ \penalty50 \medskip \vskip-\parskip \firstdescribe@false\par\fi \hangindent2pc \hangafter1 \noindent@@@{}bf##1\hskip.Sem}

(compare page 130 for the use of \noindent@@).

In the definition of \item, the

\penalty50 \medskip \vskip-parskip \hangindent2pc \hangafter1 \noindent \noindent@@{}bf##1\hskip.Semrepresent style decisions, which might be changed for other styles.

\enddescribe is also much simpler than \endlist: we simply end the previous paragraph, add spacing and penalties (style decisions) and end the group started by \describe:

\def\enddescribe{\par

\penalty-50 \medskip\vskip-\parskip

\endgroup}

Since \describe...\enddescribe _is_ supposed to start a new paragraph at the end (at least in the default style), we don't need the special machinations that were used for \endlist (page 145); of course, they could always be added for a style that wants to handle this question differently.

_19.2._\margins. The \margins construction uses the commands \pullin and \pullinmore, rather than \item. We might as well have these give error messages outside of a \margins...\endmargins construction (see section 1.1),

\Invalid@\pullin

\Invalid@\pullinmore

There is no special formatting before the first paragraph of a \margins construction. Nevertheless, we still need a flag

\newif\iffirstpull@

but this flag will play quite a different role than the analogous flag in \describe: Each \pullin command is going to start a new group, within which \leftskip and \rightskip will be determined by the arguments of this command; since a \pullin is usually followed by yet another \pullin, this means that each \pullin will also have to provide the \endgroup that matches the \begingroup from the previous \pullin, except that the \pullin should not provide this extra \endgroup.


### 19.2. \margins

Normally, \margins is meant to be used as

 \margins  \pullin{...}{...}  \endmargins but our definition allows text to intervene between the '\margins' command and the first '\pullin'; such text will just be treated as a paragraph with no special indentations.

Note that this definition of \pullin regards the arguments as 'absolute' dimensions, rather than as dimensions relative to values of \leftskip and \rightskip that may have already been set. Indeed, when one of the arguments is \ or \, we explicitly set the value of \leftskip or \rightskip to Opt, instead of simply leaving it alone.

Since no other \LWS-TeX macros fool with \leftskip and \rightskip, this seems like a reasonable design decision; a sophisticated user who knows about \leftskip and \rightskip will presumably have the sense either to adjust the arguments of \pullin appropriately (or to use \pullinmore), or to first set \leftskip and \rightskip to Opt before using \margins.

To make the arguments of \pullin relative dimensions, it would suffice to replace the '\leftskip' and '\rightskip' with '\advance\leftskip' and '\advance\rightskip', respectively. In this case, we could simply omit the '\leftskip=Opt\relax' and '\rightskip=Opt\relax' both times.

The definition of \pullinmore follows just such a scheme, except that we must store the current values of \leftskip and \rightskip before ending the previous group:

 \xdef\Next@{\leftskip=\}the\leftskip  \rightskip=\}the\leightskip The effect of this \xdef (compare page 147) is to make \Next@ mean

 \leftskip=(current value of \leftskip)  \rightskip=(current value of \rightskip)

We need \xdef rather than \edef, because this will be followed by an \endgroup; then, after the following \begingroup we can reinstate these


19.2.\margins

\iffirstpull@\firstpull@false\else\endgroup\fi \begingroup \Next@ \def\next@{##1}% \ifx\next@\empty\else\ifx\next@\space\else \advance\leftskipby##1\ifi\right \def\next@{##2}% \ifx\next@\empty\else\ifx\next@\space\else \advance\rightskipby##2\ifi\ignorespaces}

And \endmargins simply has to end the current paragraph, and supply two \endgroup's (one to match the \begingroup from the previous \pullin or \pullinmore, and one to match the initial \begingroup supplied by \margins):

\def\endmargins{\par\endgroup\endgroup}

**Chapter 20.** Unopunct, \nospace, and \overlong

In the next chapter we will consider \demo, because it uses some preliminary constructions for \claim, the subject of the chapter after that. Since both \demo and \claim involve punctuation and spacing that are normally supplied by a style, but which a user might want to override, this chapter is devoted to such considerations, which version 1 of \(\LMS\)-TEX handled with the \nofrills construction.

_20.1._\nopunct, \nospace, _and_\overlong. In \MS-TEX's \ansppt style, \nofrills was used in several, not entirely consistent, ways (unfortunately extended yet further by the AMS in their additions to the style), and this inconsistent usage was brought over to version 1 of \(\LMS\)-TEX (see the small print on page 209).

In version 2 of \(\LMS\)-TEX, \nofrills has been changed to \nopunct, so that it affects only punctuation. It then seems silly to allow \nopunct to also delete the spacing after the punctuation, with \usualspace required to put this spacing back. Instead, it seems more consistent to have '\nospace' to delete the space, so that removal of the punctuation and removal of the spacing are handled separately.

In addition to these two new control sequences, \overlong has been retained. Although no construction in the default \LMS\-TEX style happens to allow both \overlong and \nopunct or \nospace, other style might, so our macros will allow for the possibility that any combination of \nopunct, \nospace, and \overlong precedes some construction (however, we will assume that each of these is used just once).

In \LMS-TEX, \nopunct, \nospace, and \overlong all work in the same way, by checking whether the next control sequence after any of these is in an appropriate list, and setting a flag to be true if it is; it is then the prerogative of that next control sequence to deal with this information (and to reset the flags to false at the end).

We need three flags

\newif\ifinopunct@ \newif\ifinospace@ \newif\ifoverlong@

### 20.1. \nopunct, \nospace, _and_ \verlong

a list, initialized as

\let\nofrillslist@=\empty

of constructions to which both \nopunct and \nospace can apply, and a list, initialized as

\let\verlonglist@=\empty

of constructions to which \overlong can apply.

Because each of \nopunct, \nospace, and \overlong has to allow the possibility that it is followed by one or both of the others, the macros are complicated, though in no way interesting; basically, each will set the corresponding flag to be true, although the flag may be reset to false if we eventually find that an appropriate control sequence doesn't follow.

First of all, each of these construction begins with a \futurelet\next:

\def\nopunct{\nopunct@true\futurelet\next\nopunct@}

\def\nospace{\nospace@true\futurelet\next\nospace\}

\def\overlong{\overlong@true\futurelet\next\nverlong@}

If \nopunct is followed by \nospace or \overlong, it will swallow these control sequences, set the corresponding flags true, and then use yet another \futurelet:

\def\nopunct@\%

\ifx\next\nospace{\nospace@true\futurelet\next\nopnos@}%

\else

\ifx\next\overlong

\def\next\overlong{\overlong@true\futurelet\next\nopol@}%

\else

\let\next@=\nopunct@\emptyset

\ifif\next@\nopunct@\emptyset

\if\if\next@\nopunct@\emptyset

\if\if\next@\nopunct@\emptyset

\if\if\next@\nopunct@\emptyset

\if\if\next@\nopunct@\emptyset

\end{\nopunct@\emptyset}

We reach \nopunct@emptyset when neither \nospace nor \overlong follows our original \nopunct, so now we have to check whether the control sequencethat follows is in Unoffilllist@. If so, we simply execute this control sequence (the flag \ifinopunct@ has already been set true); otherwise we reset \ifinopunct@ to be false and give an error message, and still execute the control sequence:

\def\nopunct@@#1{\ismember@\nofrillslist@#1% \iftest@ \letnext@=#1% \else \def\next@\nopunct@false \Err@\nopunct@nopunct can't be used with \string@1}#1}% \ifinext@} (We use an argument #1 for \nopunct@0, rather than picking up the next control sequence with a \futurelet\next, so that we can properly include #1 in the error message.) For the use of \nopend in this, any future, error messages, compare section 3.4.

Temporarily leaving aside \nopnos@ and \nopol@, the other possible outcomes of \nopunct@, we use basically the same procedures for \nospace@ and \overlapping@:

\def\nospace@\% \ifx\next\nopunct \def\next\nopunct@\nopunct@true\futurelet\next\nopnos@}% \else \ifx\next\nverlong \def\next@\nverlong\futurelet\next\nosol@}% \else \let\next@=\nospace@\n\if\if\next@} (notice that we use the same \nopnos@ that appeared in \nopunct@)

\def\nospace@@#1{\ismember@\nofrillslist@#1% \iftest@ \let\next@=#1%
### 20.1. \nopunct, Unospace, and \nosol@

\else \def\next@{\nospace@false \Err@{\nopexpand\nospace can't be used with \string#1}#1}% \fi\next@} \def\overlapping@{\% \ifx\next\nopunct \def\next@\nopunct{\nopunct@true\futurelet\next\nopol@}% \else \ifx\next\nospace \def\next@\nospace\nopunct\futurelet\next\nosol@}% \else \let\next@=\overlapping@ \fi\first@} (notice that we use the same \nopol@ and \nosol@ that appeared in \nopunct@ and \nospace@)

\def\overlapping@@#1{\nmember@\overlappinglist@#1}% \iftest@ \let\next@=#1% \else \def\next@{\noverlapping@false \Err@{\nopexpand\noverlapping can't be used with \string#1}#1}% \fi\next@}

Now each of \nopnos@, \nopol@, and \nosol@ must look for the third of the triumvirate:

\def\nopnos@{\ifx\next\overlong \def\next@\overlong\overlong\nopnosol@}\else \let\next@=\nopnos@@\fi\next@} \def\nopol@{\ifx\next\nospace \def\next@\nospace{\nospace@true\nopnosol@}\else \let\next@=\nopol@@\fi\next@}



)

def\punct@#1{\ifinopunct@\else#1{fi} Similarly, we have

def\addspaceo@#1{\ifinospace@\else#1\fi} for adding the space.

Control sequences that allow \overlong are ones that normally might contain an \hss, like

\def\centerline#1{\line{\hss#1{\hss}}} Any such candidates will have the \hss replaced by \hss@, which is defined by

\def\hss@{\ifoverlong@ Opt plus1000pt minus1000pt \else Opt plus1000pt{fi} \ } So both stretch and shrink will be allowed when \ifoverlong@ has been set true, but only stretch will be allowed otherwise.



just in case #1 happens to end with an upper-case letter (although this will usually be irrelevant, since an \enspace, rather than a space, follows).

At this point, after we have determined whether or not the colon and \enspace should be added, we will reset \infopunct@ and \infospace@ to be false immediately, even though \enddemo will also do this, just to minimize problems if the user forgets the \enddemo.

Finally, we want to switch to \rm. However, we must also be careful to add a \FNSSP@, in case an invisible construction follows the \demo{...} (this will also throw away any extraneous space after the \). We can't simply say

\def\demo#1{\ifclaim@... \else \rm\FNSSP@\fi}

because \next will be \let equal to the \fi, rather than to the next non-space token after \demo{...}. So instead we have to use the definition

\def\demo#1{\ifclaim@ \Err@{Previous \expandafter\noexpand\claimtype@ has \no matching \string\end\exxx@\claimtype@}% \let\next@=\relax \else \par \ifdim\lastskip<\smallskipamount \removelastskip>smallskip\fi \begingroup \noindent@\@\%mc\ignorespaces#1\unskip \punct@\{null\colon@\}\addspace@\$\$\)\addspace@\$\$\)\nopunct@false\nospace@false \nopunct@false \rm\rm\prime\} \def\next@{\{\}FNSSP@}\% \fi \text@{\}\text@{\}next@\$\$\)}enddemo simply has to end the current paragraph, supply the }endgroup to match the }begingroup from }demo, reset the flags }ifnopunct@ and }ifnospace@, and insert a }smallskip: }def{enddemo{}par}endgroup \nopunct@false\nospace@false\smallskip} } ```


Now we can introduce \claimformat@ to indicate the general format of a \claim:

\def\claimformat@#1#2#3{\medbreak \noindent@{\smc#1 {\claim@@@F#2} #3% \punct@{\null.}\addspace@\enspace}\sl} (Compare page 162 for the '\null.' and Chapter 8 for the \noindent@@.) Arguments #1 and #3 for \claimformat@ are the two arguments that a user types in

\claim{...}{...}

while argument #2 is the \claim number, either produced automatically, or specifically "quoted" after \claim.

Section 11 explains how a style file can modify \claimformat@ to deal with numerous possibilities for formatting different sorts of \claims in different ways.

#### 22.2. \claimformat@0.

Since \claimformat@ is meant to be easily modified by a style designer, it omits several messy details:

1. Any extraneous spaces at the beginning and end of arguments #1 and #3 should be removed.
2. If #3 is empty, or a space (which occurs if the user types { } instead of {}), then the space before it must be removed.
3. #2 should be the properly formatted \claim number. Moreover, if this is empty (because the user typed \claim"), then the space before it should be removed.
4. A space following the \claim{...}{...} should be ignored; more generally, we need \FNSSP@, in case an invisible construction follows.

So instead of using \claimformat@ directly, we will use \claimformat@0, which calls \claimformat@ with all these details added. When we are using \claimformat@0, the control sequence \thelabel@0 will contain the properly formatted claim number.1 In the definition below, argument #2 corresponds to argument #3 for \claimformat@. Only the next-to-last line of code needs further amplification.

\def\claimformat@@#1#2{% \claimformat@{\ignorespaces#1\unskip}% {\ifx\thelabel@@\empty\unskip}else\thelabel@@\fi}% {\ignorespaces#2\unskip}% \let\claimformat@@={\claimformat@@ \FHSSP@} ```
Note that it wasn't necessary to add any special clause for the cases where #2 is empty or a space--in either case the space preceding #2 will end up being removed. (Section 11 illustrates how modifications may be made to the definition of \claimformat@. In some cases, \claimformat@@ might need some tinkering also.)

To explain the mysterious next-to-last line of code, we have to confess to a little white lie. \claim, and all related constructions, never actually use \claimformat@@. Instead they use \Claimformat@0, which we will initially set to be the same as \claimformat@@:
``` \let\Claimformat@@@=\claimformat@0 ```
This indirect approach has been implemented to deal with constructions produced with \newclaim and \shortenclaim. Suppose, for example, that we produce \Thm with
``` \newclaim\Thm\c{thm}{Theorem} ```
Roughly speaking, this defines \Thm as
``` \def\Thm{... \def\Claimformat@@{\claimformat@@@{Theorem}}... \claim } ```
The \claim in this definition will call \Claimformat@0, and hence
``` \claimformat@@{Theorem} ```


### 22.4. Starting a \claim

makes \Thm define \claimclass@ to be 'thm' also.

Now, when \claim\c{thm} is typed, we will use

\claim@Cthm

for the counter. More generally, we will use

\csname claim@C\claimclass@\endcsname

(As we will see later, the construction

\newclaim\Thm\c{thm}{Theorem}

creates \Thm@P, \Thm@Q, etc., directly, but it creates \Thm@C indirectly: first the counter \claim@Cthm is created, if it doesn't already exist, and then \Thm@C is made equivalent to this counter.)

Consequently, the counter \claim@@@C is simply defined by:

\def\claim@@@C{\csname claim@C\claimclass@\endcsname}

It is the \claimclass@ of a construction like \Thm, etc., that determines its numbering. Consequently,

\newclaim\Thm\c{thm}{Theorem}

\newclaim\Lem\c{lem}{Lemma}

produces \Thm's and \Lem's that are numbered independently, while

\newclaim\Thm\c{thm}{Theorem}

\newclaim\Lem\c{thm}{Lemma}

makes \Thm's and \Lem's share the same numbering.

### 22.4. Starting a \claim

First we introduce the other components of a printed \claim number:




#### 22.6. Starting a \claim@q.

For our definition of \claim@q we use \Qlabel@ from section 16.3 for defining \thelabel@,..., and we add a \FNSS@, since we have to see whether our \claim@q is followed by \c{...} (possibly after a space):

\def\claim@q"#1"{\begingroup {\let\pre=\claim@@@P \let\post=\claim@@@Q \let\style=\claim@@@S \let\numstyle=\claim@@@@N \noexpands@ \Qlabel@{#1}}% \locallabel@ \FNSS@\claim@q@}

Unlike the situations for \market@ and \item@, we are not yet ready to actually typeset the quoted \claim number; however, the number that we want to typeset has been safely stored in \thelabel@, which eventually finds its way into \claimformat@@.

In regard to the \let\pre=\claim@@@P,..., compare page 140.

#### 22.7. Finishing off.

Let's return to \claim@c, which ended with

\FNSS@\claim@c@

Here \claim@c@ must check to see whether \next is ". If \next is not ", we just call \Claimformat@@. If \next is ", we will call yet another routine \claim@cq. But we will also have to make an adjustment: Remember that \claim@c has already increased the appropriate counter \cname claim@C\claimclass@\endcsname by 1. If \claim@c@ finds a " next, so that the claim number is actually being quoted, then it must counteract this change:

\def\claim@c@{\if\next"% \global\advance\claim@@@C by -1 \let\next@=\claim@cq \else\let\next@=\Claimformat@@ \fi \next@}

The definition of \claim@cq is now fairly straightforward, using only devices already encountered; instead of \Claimformat@@ at the end, we use \FNSS@\Claimformat@@, just to get rid of a possible space following the second ":

\def\claim@cq"#1"{{\let\pre=\claim@@@P \let\post=\claim@@@QQ \let\style=\claim@@@GS \let\numstyle=\claim@@@ON \noexpands@ \Qlabel@{\#1}% \locallabel@ \FNSS@\Claimformat@@}

Similarly, our definition of \claim@q ended with

\FNSS@\claim@q@

where \claim@q@ can simply be defined by

\def\claim@q@{\ifx\next\expandafter\claim@qc \else\expandafter\Claimformat@@\fi} (the "K-method" again, see section 1.1).

We reach \claim@qc only when we have the combination

\claim"..."\c{...}

(never via a construction that has been created with \newclaim), which is actually pretty unlikely, since there's not much point indicating the class of a \claim if the number is being quoted (unless different classes of \claim's are going to be formatted differently, in which case the style designer has presumably already used \newclaim to introduce a new name), but we might as well carry it through.

Before calling \Claimformat@@, we just have to use the \c{...} part to define \claimclass@, and, just in case this particular class \c{...} of \claim's has never been used before, create the new counter '\claim@...', if necessary, and set it to 0 (not to 1, as in \claim@c, since the counter isn't going to be used now). And finally, we must again use \FNSS@\Claimformat@@ to skip over any space after the \cf...}:

\def\claim@qc\c#1{\expandafter \ifx\csnameclaim@C#1\endcsname\relax \expandafter\newcount@\csnameclaim@C#1\endcsname \global\csnameclaim@C#1\endcsname=0 \fi \FNSS@\Claimformat@@}

8 \endclaim. Finally, \endclaim simply ends the group begun by \claim (or \claim@c if called by something created by \newclaim or \shortenclaim), sets \ifclaim@ and \ifnopunct@ to be false, resets \Claimformat@@ to be \claimformat@@, and adds a \medbreak.

\def\endclaim{\endgroup}claim@false \nopunct@false \let\Claimformat@@=\claimformat@@\medbreak}

9 \newclaim. To finish off the entire \claim complex, we have to define \newclaim and \shortenclaim.

\newclaim allows \claimclause as optional syntax, and we do the standard thing to prevent its being used at inappropriate times (see section 1.1):

\Invalid@\claimclause

\newclaim itself will require a \futurelet to see if \claimclause comes next:

\def\newclaim{\futurelet\next\newclaim@}

If \claimclause does come next, we will swallow the \claimclause and incorporate the following argument into

\newclaim@@@{#1}

otherwise, the result will be the same as if we had typed

\newclaim\claimclause\relaxso we will simply call \newclaim@@\relax directly:

\def\newclaim@{\ifx\next\claimclause \def\next@\claimclause@\{\newclaim@@{\#1}}\}\else \def\next@{\newclaim@@\relax}\{\if\next@\}

Thus, we have reduced everything to the definition of \newclaim@@.

Several aspects of \newclaim@ are included for eventual use by the \shortenclaim construction. For example, something like

\shortenclaim\Thm\thm

should be allowed only if \Thm has already been created with \newclaim; for this reason, we are going to keep a list, \claimlist@, of all such possibilities, and we initialize it as:

\def\claimlist@{\\\claim}

We will also need two new token lists,

\newtoks\claim@i \newtoks\claim@v

and, as we'll see, one other auxiliary control sequence is going to be defined in the process of defining \newclaim@@. Finally, there will be a situation where we _don't_ want the \claimclause to be inserted, even if it has been specified. For this purpose, we initially

\let\noclaimclause@=F

In the special case where we want to suppress the claim clause, we will \let\noclaimclause@=T (this happens only once, and is more efficient than declaring \ifnoclaimclause@, which actually creates three control sequence names).

If \\ denotes an optional space, then \newclaim will appear in something of the form

\newclaim \claimclause \{(claim clause)}\{\_\}Thm \c{thm}\{\_\}{Theorem}


Notice that we use \def, rather than \let, so that when \newclaim\Thm is used, \Thm@P,... will be assigned the current values of \claim@P,... These may have been modified by some

\newpre\claim \newpost\claim \newstyle\claim \newnumstyle\claim \newfontstyle\claim

That was done because style files may quite well define \claim@P to be something like

\(\left(\text{chapter number}\right).\left(\text{section number}\right).\)

and we would presumably want such a numbering scheme to be carried through for our \Thm.

[A \newpost will usually be made only locally, so that \claim@Q probably won't change, except for individual \claim's. As for \claim@S and \claim@N, if the user changes them, presumably the change should be brought along also for \Thm. One could always change some of this code, to

\expandafter\let\csname\exstring@\Thm@S\endcsname=\claim@S

for example, if this doesn't seem like the best arrangement.]

We also make \endThm mean \endclaim:

\expandafter\def\csname end\exstring@#2\endcsname\endclaim\

The counter \claim@Cthm may already exist (because of a previous \claim\c{thm}); if not, we must create it, with \newcount@ (again, see page 121), and, for safety's sake, initialize it to 0:

\expandafter\ifx\csname claim@C#4\endcsname\relax \expandafter\newcount@\csname claim@C#4\endcsname \global\csname claim@C#4\endcsname=0 \fi
Then we have to \let\Thm@C=\claim@Cthm, which is accomplished by the code

\edef\next@{\let \csname}existing@#2@C\endcsname =\csname claim@C#4\endcsname\endcsname} \next@ Here the first \csname...\endcsname will be expanded to \Thm@C, which will be made equivalent to \relax, since \Thm@C isn't already defined; on the other hand, the second \csname...\endcsname will expand to \claim@Cthm, which has been created with \newcount@, and hence with a \countdef; such control sequences aren't expanded further in an \edef (compare page 55).

After all this, we will want to define \Thm:

\def\claimtype@{#2}% \def\Claimformat@@{\claimformat@@{\$5}}\claim@c\c{#4}} Thus, \Thm will not call \claim directly, but instead call

\claim@c\c{thm} This is where \claim\c{thm} usually gets us. The difference is that we first take the opportunity to define \Claimformat@@ as

\claimformat@@{Theorem} so that the argument 'Theorem' is automatically supplied, and we also take the opportunity to

\def\claimtype@{\Thm} In addition, for the sake of \shortenclaim we want to add

\global\claim@i={#1}\gdef\claim@iv{#4}\global\claim@v={#5}


#### 22.10 \shortenclaim

\def#2{\ifx\nocclaimclause@ T\else#1{\fi \global\claim@i{\#1}\gdef\claim@i{\#4}\global\claim@v{\#5}\% \def\claimtype@{\#2}\% \def\Claimformat@@{\claimformat@@{\#5}\}\claim@c\{\#4}\}\}\]

We \def\endThm{\endclaim} rather \let\endThm=\endclaim for situations where a style file changes \endclaim, and also uses \newclaim to create special claims, like \Thm. If we used \let, then the \newclaim\Thm_would have to come after the redefinition of \endclaim, or \endThm would have the wrong meaning.

On the other hand, even if \endclaim isn't changed, but the particular case of \endThm is supposed to be different (leaving extra space perhaps, or possibly even something more extreme, like an \hrule across the page), then one might have to

\redefine\endThm{\endgroup\claim@false\nopunct@false (special formatting after \Thm)}

But special formatting at the beginning of \Thm should be handled as in the case of \Gop in section 11.

#### 22.10 \shortenclaim

Finally, we come to \shortenclaim#1#2, a typical usage of which is

\shortenclaim\Thm\thm

The first thing \shortenclaim will do, when called this way, is

\define\thm{} to get an error message if \thm is already defined.

Next, \shortenclaim will try the test

\ismember@\claimlist@\Thm

If this is false, we will just give an error message

\Thm not yet created by \newclaim.

)

Otherwise, we will first add \thm to \nofrillslist@, and then make \thm@S be \Thm@S, etc:

\rightadd@#2\to\nofrillslist@ \expandafter\def\csname\existing@#2@S\endcsname \(\csname\existing@#1@S\endcsname\)

(The _LMS-TEX_ Manual incorrectly implies, on page 45, that \thm@S, etc., will actually be \claim@S, etc., on the grounds that these constructions for \Thm might be changed later on. That would indeed be a problem if we used \let instead of \def, but with the \def, any use of \newstyle\Thm, etc., will automatically carry over to \thm. A problem arises only if something like \newstyle\thm is ever used; in that case, any succeeding \newstyle\Thm's will no longer carry over to \thm.)

Then, as with \newclaim, we must make \endthm mean \endclaim, and let \thm@C be \Thm@C.

Finally, \shortenclaim will have to define \thm. The problem now is that we would like to

\def\thm{(claim clause) \def\claimtype@{\thm}% \def\Claimformat@@{\claimformat@@{Theorem}}% \claim@c\<{\thm}}

where \(\claim clause) is the claim clause for \Thm.

So we need a way of getting this (claim clause), as well as the 'thm' and "Theorem' that actually go with \Thm. The strategy for this is to set a box

(A) \setbox0=\vbox{\Thm^1^1}relax\endgroup} because the globally defined token list \claim@i will then contain our desired \claim clause, \claim@iv will be defined to be 'thm', and the token list \claim@v will contain 'Theorem'. We use an empty label \({}^{\it n}\) for the \Thm so that the counter won't be increased, and instead of \endThm, we just use \endgroup, since the other parts of \endThm will be irrelevant in this situation.

Once we have recovered these quantities, we will be in a position to globally \def\thm, but again we will need a somewhat indirect route:

\xdef#2{\the\claim@i \def\noexpand\claimtype@{\noexpand#2}% \def\noexpand\Claimformat@@ \{\noexpand\claimformat@@{\the\claim@v}\}% \noexpand\claim@c\noexpand\c{\claim@iv}} This works as before, noting that for a token list like \claim@i, the expansion of \the\claim@i is simply that token list. (We need token lists to store the (claim clause) and the part of the \claim exemplified by 'Theorem' because both of these might contain control sequences, which should remain unexpanded in the \xdef; on the other hand, the claim class, like a (label), is not supposed to have expandable tokens in it.)

But there is still one little fillip that we need to add: Instead of (A), we really want to use

\setbox0=\vbox{\let\noclaimclause@=T \Thm\"\relax\endgroup}

To see why, imagine a situation (compare section 11), where we have

\newclaim\Cor\c{cor}{Corollary} \newclaim\claimclause{\Reset\Cor1}\Thm\c{\thm}{Theorem} \shortencclaim\Thm\thm so that each \Thm and \thm resets the numbering of \Cor's to 1. If we were to declare these in a different order,

\newclaim\claimclause{\Reset\Cor1}\Thm\c{\thm}{Theorem} \shortencclaim\Thm\thm \newclaim\Cor\c{cor}{Corollary} then the \shortencclaim\Thm\thm will cause us to

\setbox0=\vbox{\Thm\"\relax\endgroup}




## Chapter 23. Heading levels

The "heading levels" \HL and \hl exhibit a strange mixture of the features of \list and \claim. They have levels, like \list, but these levels indicate separate entities, rather than parts of a single construction. And we can create new names, like \chapter and \section for, say, \HL1 and \hl1, but this is somewhat different than creating new \claim's with \newclaim, because \chapter is essentially just a synonym for \HL1, rather than a new class of heading levels.

Moreover, heading levels introduce yet another complication, since they are constructions that get written to the table of contents file, which we need to consider first.

_23.1. The.toc file._ In version 1 of \_LWS_-TEX, headings were written to the.toc file, while the corresponding page numbers were written to a separate.tpg file. Now, however, the page numbers are written together with the headings in the.toc file.

On the other hand, \island's, and their page numbers, will be written to a separate file, which I can't resisting calling the.tic file, even though it's not really a proper acronym. Corresponding to \indexfile (page 52), we have

\newif\ifitoc@ \def\tocfile\ifitoc@\else \alloc@@7\write\chardef\sixt@@n\toc@ \immediate\openout\toc@=\jobname.toc \alloc@@7\write\chardef\sixt@@n\tic@ \immediate\openout\tic@=\jobname.tic \global\toc@true\fi\

_23.2. Preliminaries._ To begin with, we want to add \hl to \nofrillslist@:

\rightadd@\hl\to\nofrillslist@

We don't need to add \HL to \nofrillslist@, since these heading levels don't have any punctuation in the default style (compare the small print section on page 209). But \HL can be preceded by \overlong, so we need to



where things like

\expandafter\def\csnameHL@1\endcsname#1\endHL{...}

\expandafter\def\csnameHL@2\endcsname#1\endHL{...}

are the basic data that a style file will provide.

(1) \next@ first stores ##2 in \entry@, for eventually writing to the.toc file.

\def\next@"##1"##2\endHL{\def\entry@{##2}.

Then \next@ must create \Thelabel@,..., \Thelabel@000. The preliminary step

\let\pre=... \let\post=...

must be divided into two cases, depending on whether we are using an ordinary \HL(number), so that \HLtype@ is \relax, or a substituted name, like \chapter, in which case \HLtype@ will be defined to be \chapter:

\ifx\HLtype@\relax

\let\pre=\HL@0P\let\post=\HL@0Q

\let\style=\HL@0S\let\numstyle=\HL@0N

\else

\let\pre=\HL@0@P\let\post=\HL@0@Q

\let\style=\HL@00S\let\numstyle=\HL@00N

\fi

\Qlabel@{##1}

Note that this would be much harder to state if we hadn't introduced \HL@@@P,..., and compare page 140.

After defining \Thelabel@,..., \Thelabel@000, we will want to store the value of \Thelabel@000 in \Thepref@. The reason for this is that after the appropriate

\HL(number)'... \endHLconstruction, we may perform other steps using the value of \label@@@@@, and it is possible (though unlikely) that the \HL...\endHLR construction contains some other construction allowing (label)'s, which would then create new values for \helabel@@@@.1

Footnote 1: tag{tag might seem like a candidate, except that displayed formulas aren’t allowed in headings actually they can easily be simulated by setting \dsize...\dsize...\dsize on a separate line, but it would be quite strange to expect such a formula to have a \tag over at the margin).

But this is one other detail that we need to worry about, in connection with writing information to the.toc file (section 8). Normally, we will be using \helabel@@@@@ for the properly formatted heading number that we will write to the.toc file. Thus, we will be writing the number, together with any pre- and post- material, but without extra formatting determined by the style, so that we can use a different formatting style in the Contents if we desire. For example, in the text we might print \hll numbers as '$1', '$2',... (compare the small print section on page 209), but we want the option of including or omitting the $ in the Contents.

If we do decide to print the $ in the Contents, then we will have a bit of quandary when we are dealing with a "quoted" number, like

\HL1 "B"...\endHLR

In this case, the printed number will appear as 'B' rather than '$B', so it should presumably also appear that way in the contents; on the other hand, "\style B" would appear as '$B', so should continue to appear that way in the Contents.

What this means is that quoted numbers should also appear quoted in the.toc file, and that any occurrence of \style in a quoted number should also appear in the.toc file, although occurrences of \pre and \post should simply be expanded out to their proper values.

(This is admittedly a rather piddling point; compare the small print section on page 206.)

To handle this, we introduce a new flag

\newif\ifquoted@which we will set true right after defining \entry@, and after the \Qlabel@{###} we will add

\let\style=\relax\dabel@@@@@@@@{###}

so that \style will remain unexpanded in \Qlabel@@@@@; on the other hand, \nextii@ will set \ifquoted@ to be false and won't define \Qlabel@@@@@.

After all this, we use

\csname HL\Hllevel@\endcsname###2\endHL

to actual typeset the heading.

[We use ###2 explicitly, rather than \entry@, because certain style files, like the book style, store the argument of \HL@1'...\endHL for use in running heads. In such cases, we want to store the actual heading that was originally typed, not simply \entry@, since \entry@ may have changed its meaning by the time the running head is typeset.]

Then we will use

\csname HL@I\Hllevel@\endcsname

to perform the proper "initializations", determined by the style file. For example, the default style file will basically make '\HL@I1' mean

\Reset\hll{i}

\newpre\hll{\Thepref@.}

(recall [page 190] that \Thepref@ holds the value of Thelabel@@@@@), so that in the first \HL1, the \hll1 numbers will be 1.1, 1.2,...; in the second \HL1, they will be 2.1, 2.2,...; etc. As we will see in Chapter 24, a \newpre will essentially do an \edef, so that the current value of \Thepref@ will be stored in the pre-material for \hll1.

And after that we will use

\csname HL@J\Hllevel@\endcsname

to perform "initializations" prescribed by the user, via \Initialize (section 11.4); as we will see in section 15, \Initialize simply defines things like '\HL@J1'.

Before performing these two routines we will

\let\pref=\Thepref@

so that any \pref that the user places in an \Initialize will be interpreted properly (this even allows the style file designer to use \pref in defining '\HL@I1'), and we will use \pref@ to restore the original definition of \pref:

\let\pref=\Thepref@

\csname HL@I\HLlevel@\endcsname

\csname HL@J\HLlevel@\endcsname}

\let\pref=\pref@

Then we will use

\HLtoc@

to write to the.toc file, if necessary. \HLtoc@ won't be defined until section 8.

After writing to the.toc file, yet other steps may be required, which we call \aftertoc@. Initially we

\let\aftertoc@=\relax

but various heading level definitions may change this (compare section 12).

Finally, after that we simply want to reset values that may have been set before the \HL@:

\let\aftertoc@=\relax\overlong@false

(2) \nextii@ is exactly analogous, except that for defining \Thelabel@,..., we will need

\ifx\HLtype@\relax

\global\advance\HL@@C by 1

\xdef\Thelabel@@@@{number\HL@@C}%

\xdef\Thelabel@{\HL@ON}%




\hltoc@ \aftertoc@ \let\aftertoc@=\relax \nopunct@false \nospace@false \FNSSP@}% \ifx\next"\expandafter\next@\else\expandafter\nextii@\fi} The \FNSSP@'s are added to deal with spaces and invisible constructions that might occur after the whole \hl(number){...} combination. (It wouldn't do any good to add the \FNSSP@'s to the definitions of \hl@1',..., since other material comes after them in the definition of \hl@.)

### Other elements of heading levels

In the default style, \newstyle can be used to change the style for printing \HL and \hl numbers, and \nopunct and \nospace can be used to control the punctuation and spacing that follows an \hl heading level (compare page 208).

On the other hand, most styles will have one further element of a heading level that we might want to control, namely, a word like 'Chapter' that is printed before the \HL number.

Someone writing in German would naturally want to replace 'Chapter' with 'Kapitel', etc. Although such a replacement could easily be made directly within the style file, there is considerable objection to this, on the grounds that additional style files shouldn't have to be made for such minor changes.

So, to the pantheon of constructions like \...@C, \...@P,..., we admit one more candidate, \...@W, the "word" associated with a construction. This will be complemented by a construction \newword, analogous to \newpre,..., (Chapter 24), allowing us to change its values, as well as \word, to print its value. From the point of view of the user, \word and \newword will work just like \pre and \newpre, etc., but they will be not be applicable to all constructions allowing labels, only to a select few (and also one or two constructions that do not allow labels--see section 29.4).

The idea of this device is that a style file can define '\HL@1' in terms of '\HL@W1', which might initially be defined to mean Chapter. Then if the user types

\newword\HL1{Kapitel} thereby redefining '\HL@W1', the word 'Kapitel' will be substituted for 'Chapter' in the \HL1 headings.

#### 23.7 Writing long token lists

As we saw in section 10.3, the construction

\expandafter\unmacro@\meaning\entry@\unmacro@

will make \macdef@ contain the tokens of \entry@, but with all non-space tokens converted to type 12.

This means that \macdef@ can be used in a \write, without worrying about expansions. But we still have to worry about the fact that a heading may be too long for a \write. This may be true even for implementations of TeX that allow rather long \write's, since there is no theoretical limit on the length of a heading; the problem is particular acute for \caption's (Part V), which might be quite long.

Consequently, we will simply arbitrarily split \macdef@ at every sixth space1 when we \write to the.toc file; to make the.toc file look better, we will add a space at the beginning of each piece.

Footnote 1: In version 1 of \(\L_{\_}\S\)-TeX, lines were split at every fifth space; but six seems safe enough, especially since, as we mention below, various spaces that didn’t count in version 1 will count now.

To do this quickly, we will make a definition like

\def\six@#1 #2 #3 #4 #5 #6 \def\next@{#1}%

\ifx\next@\empty\def\next@##1\six@\else

\write\toc@\u#1 #2 #3 #4 #5 #6\let\next@=\six@\fi

\next@}

and then use

\six@(material to be split)\six@

with 12 \'s added. Thus, \six@ will extract six pieces, write them to the.toc file, and then call \six@ once again, except when #1 is empty (in which case #2,..., #6 will also be empty). The first time this happens, everything has already been written, so we simply throw away everything up to and including the final \six@. (At the next-to-last stage, #1 might be the last piece, and thus the only non-empty argument of \six@. Then \six@ will use up 6 of the inserted \'s (unless this last piece of the \(\langle\)material to be split\(\rangle\) happened to end with a \(\utilde\) itself). So we need 6 more \(\utilde\)'s, to be used up by the next call to \six@.)





So we will use the \unnacro\meaning trick of section 7, within the triple \expandafter trick (page 162): the code

\expandafter\expandafter\expandafter\unnacro@ \expandafter\meaning\csnameHL@WHLlevel@\endcsname\unnacro@

will make \macdef contain the tokens of the \word, but with all non-space tokens converted to type 12.

So, altogether, we can use

\expandafter\expandafter\expandafter\unnacro@ \expandafter\meaning\csnameHL@WHLlevel@\endcsname\unnacro@ \noexpands@\let\style=\relax \edef\next@\write\toc@\noexpand\expandafter\noexpand \Hlname@\macdef\{\QxrThlabel@@\emptyset\} \next@} Note that, just as we will need to declare \noexpands@ before a \shipout, when the \write is actually done (pages 58 and 87), we will also need to declare \let\style=\relax before the \shipout.

Then we use

\expandafter\unnacro@\meaning\entry@\unnacro@ \Sixtoc@

to write the heading, with all non-space characters of type 12, and line breaks after every sixth space.

Finally, we add

\write\toc@\noexpand\Page\paper\page\page@N\% \page@P\page@Q\~~JJ where the extra blank line at the end is added to make the.toc file more readable.1



Chapter 3 are simply going be numbered 1, 2, 3,...under the Chapter 3 entry in the Contents. To handle such possibilities, the.toc file should probably get the whole set of information

{\Thelabel@}{\Thelabel@@@@}{\Thelabel@@@@@}

instead of simply {\Thelabel@@@@@}. Then front matter style files (Chapter 37) could decide which information to use. Since I've never actually seen a book in which formatting of this sort was used, it seemed silly to encumber I_W_S_-T_EX with this extra baggage. But if such a treatment were needed, it should be clear how to modify the definitions of \HLtoc@ and \hltoc@ accordingly.

\mainfile. When we have specified \tocfile in our main file, say paper.tex, the file paper.toc is written, but this file is not meant to be T_EX'ed directly. Instead, we will be making a "front matter" file, say paperfm.tex, and since this file will need to know the name of the original file, in order to \input the proper.toc file, paperfm.tex will begin with a line like

\mainfile{paper}

We define

\def\mainfile#1{\def\mainfile@{\#1}}

so that, at the appropriate time the macros for the front matter style can

\input mainfile@.toc

If the \mainfile command is omitted from paperfm.tex, we would like to produce an error message when \marketoc is encountered. So we add

\def\checkmainfile@{\ifx\mainfile@}undefined

\Err@{No\noexpand\mainfile specified}\fi}

(We put these definitions directly into lamster.tex so that front matter style files don't have to worry about them.) (See section 3.4 for the use of \noexpand.)

#### Creating heading levels

Although we now have the general mechanism for handling heading levels, no heading levels have actually been defined.

The default style makes NHL1 and NHL1 be defined, which will indicate the general procedure required.

We begin by adding the necessary counters and control sequences.

\expandafter\newcount@\csnameHL@C1\endcsname \csnameHL@C1\endcsname=0 \expandafter\def\csnameHL@S1\endcsname#1{#1\null.} \expandafter\let\csnameHL@N1\endcsname=\arabic \expandafter\let\csnameHL@P1\endcsname=\empty \expandafter\def\csnameHL@F1\endcsname{\bf} \expandafter\let\csnameHL@W1\endcsname=\empty \expandafter\newcount@\csnamehl@C1\endcsname \csnamehl@C1\endcsname=0 \expandafter\def\csnamehl@S1\endcsname#1{#1\} \expandafter\let\csnamehl@N1\endcsname=\arabic \expandafter\let\csnamehl@P1\endcsname=\empty \expandafter\let\csnamehl@Q1\endcsname=\empty \expandafter\def\csnamehl@F1\endcsname{\bf} \expandafter\let\csnamehl@W1\endcsname=\empty \expandafter\let\csnamehl@W1\endcsname=\empty

Using newcount@ (see page 121) rather than \newcount isn't necessary here, since these definitions are made within the file lamstex.tex, but they serve as a reminder that auxiliary files should use \newcount@ (unless they have stated \let\alloc@=\alloc@ at the beginning). We added the \null in 'HL@S1' in case #1 ends with an upper-case letter (compare page 162). (The proficient \(\mathcal{A}\)\(\mathcal{N}\)-TEX or \(\mathcal{A}\)\(\mathcal{N}\)-TEX user would type '@.' in such a case, but @ can't be allowed in a style command, since that would essentially be as bad as allowing it in a \(\{\rm label}\).)

Note, by the way, that the period after the heading number in 'HL@S1' is not considered to be punctuation that can be eliminated with \nopunct. There is no need for that, since a quoted heading level could always be used instead (and \newstyle\HL1 or \newstyle\hl1 could be used to make a permanent change). Basically, \nopunct only affects punctuation that the


2. We set a vbox consisting of centered lines. Let0, from \(\mathcal{A}_{\mathcal{M}}\mathcal{S}\)-TEX, is the device for letting \\\ be the same as \cr within this vbox. Normally we would use \tabskip\hfil or \tabskip\hsss to produce the centered lines; \tabskip\hsss to is used in case \overlong precedes the \HL (page 160).
3. At the beginning of the argument #1 we print \thelabel00 (the number, together with any pre- and post-material, plus anything produced by the style), in the proper font. Notice that we explicitly leave the space after \thelabel00, since the spacing is not made part of '\HL@S1' (compare page 132). Moreover, before \thelabel00 we print the (word) for '\HL@1' (empty in the default style).

However, there are a few details that we need to change:

1. The preamble should really contain \halign to\hsize{\bf\hfill\ignorespaces##\hmskip\hfill\cr to discard extraneous spaces at the beginning or end of each line of the heading.
2. In addition, we need to replace the \HLE@F\thelabel00} #1 by \HLE@F\thelabel00} \ignorespaces#1 to get rid of an extraneous space at the very beginning of the heading.
3. Moreover, if \thelabel00 is empty (from a \HL 1 "1"), then the space before the \ignorespaces should be eliminated. And if the \word is empty, then the space after it should be eliminated.
4. We don't really want our heading to be a \vbox, because \insert's (like \footnote) won't migrate out. So we will instead globally \setbox1 to be the \vbox, and then \unvbox1:

\expandafter\def\csnameHL@1\endcsname#1\endHL\bigbreak \locallabel)

\global\setboxi=\vbox{\Let@\tabskip\hss@\\halignto\hsize{\bf\fhfil\ignorespaces#\unskip\hfill\cr\expandafter\ifx\csnameHL@W1\endcsname\empty\else\csnameHL@W1\endcsname\space\fi{\HL@F\ifx\thelabel@@\empty\else\thelabel@@\space\f\ifx\g\ignorespaces#1\crcr\}% \% \vnovbox1 \nobreak\medskip} NOTE: The \nobreak here is absolutely essential--see section 12. The definition of \h11 for the default style is quite straightforward, using \punct@ and \addspace@, since \h1 is on \nofrillslist@: \expandafter\def\csnamehl@1\endcsname#1{\medbreak\noindent@@ \llocallabel@ \bf{\h1@F\ifx\thelabel@@\empty\else\thelabel@@\space\fi\% \ignorespaces#1\unskip \punct@{\null.\}addspace@\enspace\}} ```

See Chapter 8 for the use of \noindent@@. Notice that here we don't even print the (word), even if it has been changed by \newword. (Generally speaking, \HL heading levels will have words printed as part of them, while \h1 levels won't. Of course a style file could redefine \h1@1' to include the (word), if necessary.)

#### Initializations

In addition to defining \HL@1', we want a definition like

\expandafter\def\csnameHL@I\endcsname{\Reset\h11{1}% \newpre\h11{pref.}} so that these "initializations" are always performed after each \HL1 (though they may be overridden if \csnameHL@Ji\endcsname has been defined by an \Initialize [section 15]). Recall that \pref will mean \Thepref@ during this initialization.

But there is a little subtlety involved here, since \HL1 might be used with an empty label \HL1"". For example,

\HL1""Introduction\endHL


for writing to the.toc file.

**IT IS THEREFORE ESSENTIAL** that no breaks be allowed by any material at the end of the definition of 'HLEUR1'...|endHL, to insure that the proper page number will be written; thus, in the definition for the default style (page 210), the \nobreak before the \nmodskip would be necessary even if the style file design weren't particularly concerned about prohibiting a page break here.

It is quite possible that a style file won't try to prohibit a page break after the heading is printed. In fact, a style file might even _demand_ a page break at this point. For example, the style file for the \nmodS-TEX Manual uses \HLO for the Part pages, and in the definition of 'HLEUR0', we want a page break after typesetting the Part page; and then we want to \Offset\page2, since the next page is supposed to be blank. It would certainly not do to

\expandafter\def\csnameHL@0\endcsname#1\endHL\(\%\) (instructions for typesetting the Part page)

\vfill\break\offset\page2}

because in the.toc file the page number for this Part page would then be 1 more than it should be! Instead, the definition has the additional clause

\def\aftertoc@{\vfill\break\offset\page2}

--then the proper page is written by the \HLtoc@ command before we increase the page numbering by 1.

#### 23.13 Order of heading levels

The default style allows an \hll1 to appear before an \hll1, but we could easily disallow this. For example, we could first

\def\HLEvel@{0} and then use

\expandafter\def\csnamehl@1\endcsname\% \ifnumHLlevel@=0 \Err@{\string\hll1 not allowed before some \string\HL}

Similarly, if we created \hll2, we could

\def\hlllevel@{0}

and then

\expandafter\def\csnamehl@2\endcsname#1\%

\ifnum\hlllevel@=0

\Err@\string\h12notallowedbeforesome\string\h11\

...... For this to work properly, we should also add

\def\hlllevel@{0}

to our definition of "\HL@1'.

Note, by the way, that there's really no necessity for "higher" heading levels to have smaller numbers.1

#### Naming header levels

Now we come to the \NameHL and \Namehl mechanisms, by which, for example,

\NameHL1\chapter

makes \chapter...\endchapterfunctionlike\HL1...\endHL, and

\Namehl1\section

makes \section{...}functionlike\h11{...}. As the uppercase 'N' suggests, \NameHL and \Namehl will act globally.1

As a special case of

\NameHL#1#2

let us consider \NameHL1 \chapter.

First we will want to

\define\chapter{}

to get an error message if \chapter is already defined.

We will also want to

\rightadd@\chapter\to\overlappinglist@

And we will want to let \chapter@C be '\HL@C1', and \chapter@P be '\HL@P1', etc. For this we will need the old \odef trick (see, for example, page 82 and Chapter 17, and see pages 126 and 161 for the use of the '\expandafter\noexpand'):

\edef\next@{\let\csname\existing@#2@C\endcsname =\expandafter\noexpand\csname HL@C#1\endcsname}\next@

**NOTE:** Since we \let\chapter@C='\HL@C1', etc., it is therefore essential that \NameHL_n_ be used _only after_ '\HL@C1',..., '\HL@F1' have been defined.

Then we want to

\def\chapter##1\endchapter

\def\HLtype@{\chapter}

\def\HLname@{\chapter}

\gdef\HLlevel@{#1}

\FNSS@\HL@#1\endHL}

This definition will have to be done with an \edef also:

\edef\next@{\def\noexpand#2\####1\expandafter\noexpand \csname end\existing@#2\endcsname \def\noexpand\HLtype@{\noexpand#2}

\def\noexpand\HLname@{\noexpand#2}

\gdef\noexpand\HLlevel@{#1}

\ncoexpand\FNSS@\noexpand\HL@\ncoexpand\endHL}

\next@

[We used \FNSS@ rather than \futurelet\next simply because it takes fewer tokens, especially with the \noexpand required before it.]We also want to state '\Invalid@\endchapter' so that an improper use of \endchapter will give an error message (see section 1.1),

\edef\next@{\noexpand|Invalid@\expandafter\noexpand \csname end\existing@\endcsname} \next@

That is the main outline of the definition, but additional details are needed. With this much of the definition, \chapter would still not function just like \HL1, because, for example, \newpre\chapter and \newpre\HL1 would have entirely different effects: one would change \chapter@P, while the other would change '\HL@P1'--if a user typed \newpre\HL1 this would not affect the pre-material for \chapter. That might not seem like such a terrible problem--users could just be warned not to use \newpre\HL1 instead of \chapter--until we realize that our definition of '\HL@I1' has a \newpre\hli clause: if the user of the default style decided to

\NameHL 1 \chapter \Namehl 1 \section

then \section's would not have the proper pre-material determined by the \chapter in which they were used. (Similarly, \newfontstyle\chapter and \newfontstyle\section would have no effect.)

To get around this problem, we need a way of passing special information to the \new... constructions of Chapter 24, so that, for example, \newpre\chapter and \newpre\HL1 will each change _both_\chapter@P and '\HL@P1'. This will be done by means of two Replacement control sequences:

\HL@R1' will be defined to have the value \chapter \chapter@R will be defined to have as value the pair {HL}{i}

So we will add

\expandafter\gdef\csname HL@R#1\endcsname{#2} \expandafter\gdef\csname\existing@\2@R\endcsname{[HL]}{#1}

In some cases, some of this information must also be passed to the.toc file. For example, the default front matter style file lamstex.stf contains instructions for typesetting entries that begin

\HL {1}

but if \NameHL1\chapter appears in the main file, then \chapter will produces entries in the.toc file beginning

\chapter

In order for the lamstex.stf file to be able to deal with these lines, the information

\NameHL1\chapter

must be passed to it:

\iftoc@

\immediate\write\toc@{\noexpand\NameHL#1\noexpand#2~~J}

\fi

with a ~~J to give a blank line afterwards, to separate this from an entry line that might come next.

For all this to work properly when we get to front matter style files (Chapter 37), it will be essential, of course, that the user has placed the \tocfile command _before_ any \NameHL commands. Actually, in addition to its invocation by a user who wants names for heading levels that a style hasn't given names to, \NameHL can also be used by a style file designer. In the latter case, we really don't want any extra information written to the.toc file, since the style file designer will presumably also write special code for the front matter style files to deal with lines that begin with something like

\chapter

As we will see in Part VII, special precautions will be taken to insure that nothing is written to the.toc file even if a file contains \tocfile before the \docstyle command.

A style file might well want to NameHL1 twice. For example, in the book style file, the control sequence

\appendices

calls NameHL1\appendix to make

\appendix... \endappendix

work just like \chapter...\endchapter.1

Once \appendices has used NameHL1\appendix, we want a previous name for NHL1, say \chapter, to become undefined, and we also want \endchapter to become undefined, and we want \Offset\chapter, etc., to be disallowed. To test whether \NameHL1 has already appeared, we simply use the test

\expandafter\ifx\csname HL@R1\endcsname\relax

If this test is false, we want to \let

\...@C, \...@P, \...@Q, \...@S, \...@N, \...@F,, \...@W,

all be \relax, where... is the value of the control sequence \csname HL@R#1\endcsname, since, as we'll see in Chapter 24, this will disallow the corresponding \Reset,..., constructions.

Unfortunately, \csname...\endcsname is quite unsuitable for use in \expandafter constructions, which is just how we will need it, so we will first use the code

\def\nextiv@{\let\nextiii@=}

\expandafter\nextiv@\csname HL@R#1\endcsnamewhich makes the "nameable" control sequence \nextiii@ have the same value as 'HL@R#1'. Then we can use

\expandafter\let\nextiii@\undefined \expandafter\let\csname\exxx@\nextiii@@ CC\endcsname=\relax... \expandafter\let\csname\end\exxx@\nextiii@\endcsname=\undefined

So our whole definition is:

\def\NameHL#1#2{\define#2{}% \expandafter\ifx\csnameHL@R#1\endcsname\relax \else \def\nextivi@{\let\nextiii@=}% \expandafter\nextivi@\csnameHL@R#1\endcsname \expandafter\let\nextiii@\undefined \expandafter\let\csname\eexxx@\nextiii@ CC\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\@\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\@\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\@\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\@\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\@\nabla\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\nabla\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\nabla\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\nabla\endcsname=\relax \expandafter\let\csname\eexxx@\nextiii@\nabla\endcsname=\relax \expandafter\let\csname \end\exxx@\nextiii@\endcsname=\undefined \forall i \expandafter\get\csname\HL@R#1\endcsname\{\#2}% \expandafter\get\csname\eexstring@#2@\nabla\endcsname{\{HL}{#1}}% \liftoc@ \immediate\write\toc@{\noexpandNameHL#1\noexpand#2^^J}% \if \rightadd@#2\to\overlonglist@ \edef\next@{\let\csname\eexstring@#2@\nabla\endcsname =\expandafter\noexpand\csnameHL@C#1\endcsname\next@ \edef\next@{\let\csname\eexstring@#2@\nabla\endcsname =\expandafter\noexpand\csnameHL@P#1\endcsname\next@ \edef\next@{\let\csname\eexstring@#2@\nabla\endcsname =\expandafter\noexpand\csnameHL@0#1\endcsname\next@)

)

)

For Namehl we don't have to worry about an \end... construction. Moreover, Namehl doesn't worry about \...@W constructions, since words are seldom added to such heading levels.

)def\Namehl#1#2{\define#2{\expandafter\ifx\csnamehl@R#1\endcsname\relax \else \def\nextiw@{\let\nextiii@}% \expandafter\nextiw@csnamehl@R#1\endcsname \expandafter\let\nextiii@=\undefined \expandafter\let\csname\erexx\nextiii@\@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\C\endcsname=\relax \expandafter\let\csname\erexx\nextiii@\C\endcsname=\relax \forall i 
\Initialize. Finally, we want to consider \Initialize, which allows the user to prescribe additional "initializations" that are done at a heading level.

We want \Initialize\HL(number) and \Initialize\hl(number) to be allowed, and also \Initialize\chapter if \chapter has been created using \NameHL. So we will use one routine, \InitH0, if \Initialize is followed by a header level \HL or \hl, and another routine, \InitS0, if it is followed by a single name like \chapter:

\def\Initialize\futurelet\Init@}

}def\Init@{ifx\next\HL\let\next@=\InitH@ \else\ifxnext\hll\let\next@=\InitH@ \else\let\next@=\InitS@{if\if\next@} ```
The definition of \InitH@ is quite straightforward. For example,

\InitH@ \HL 1 {...}

is supposed to (globally) define 'HL@J1' to be '...'. But we want to give an error message if the corresponding heading level hasn't been defined:
``` \def\InitH@#i#2{\expandafter \ifx\csname\exstring@#1@C#2\endcsname\relax \def\next@{\Err@{\noexpand#ilevel #2 not defined in this style}}% \else \def\next@{\expandafter \gdef\csname\exstring@#1@J#2\endcsname}% \fi \next@} ```
Now we have to reduce \InitS@ to \InitH@. Let's suppose the argument of \InitS@ is \chapter, which has been created by

\NameHL1\chapter

so that \chapter@R has the value {HL}{1}. We introduce the combining construction
``` \def\InitC@#i#2{\odef\nextii@{\expandafter\noexpand \csname\csname\#1\endcsname\#2}} ```
(again compare pages 126 and 161 for the \expandafter\noexpand), so that
``` \InitC@{HL}{1} makes \nextii@ mean \HL1; the point of this is that we can then use \expandafter\InitH@\nextii@

#### 23.15. Unitialize

Actually, things are not that direct. To get (**A**) we need

\expandafter\InitC@\chapter@R

except that '\chapter@R' will actually have to be specified as

\csname\existing@1@R\endcsname

which cannot be used directly in this \expandafter. As on page 218, we will actually use the combination

\def\next@\let\next@=\expandafter\next@\csname\exstring@#1@R\endcsname

\expandafter\InitC@\next@

The first two lines make the "nameable" control sequence \next@ have the save value as \chapter@R, and then the third line makes \nextii@ mean \HL1.

Putting this all together, our final definition is

\def\InitS@#1#2{expandafter

\ifx\csname\existing@#1@R\endcsname\relax

\Err@{\noexpand#inot defined in this style}%

\let\next@=\relax

\else

\def\next@\let\next@=\%

\expandafter\next@\csname\exstring@#1@R\endcsname

\expandafter\InitC@\next@

\def\next@\expandafter\InitH@\nextii\next@\next@\

### Chapter 24. Accessing and controlling counters, styles, etc.

We are finally ready to examine the various constructions that allow us to access and manipulate the values that \ref and its relatives give us.

First we will consider the constructions that allow us to access the values: \value, \Evaluate, \pre, \post, \style, \nunstyle, and \fonstyle.

The definition of \value illustrates the basic strategy required: \value\tag should make sense, and if we \NameHL1\chapter, then \value\chapter should make sense; on the other hand, \value\list and \rule\HL should make sense only when followed by an appropriate number. These two different cases are easily distinguished, because \tagGC and \chapter@C are defined, but \list@C and \HL@C are not defined, while things like '\list@C1' and '\HL@C1' are defined.

The definition of \value\first uses the test

\ifx\csname\exstring@#1@C\endcsname\relax

to see whether #1 is a construction like \tag with a single counter. If this \ifx test is false, so that the counter in question does exist, it simply prints

\number\csname\exstring@#1@C\endcsname

If the \ifx test gives a positive result, we want to use the test

\ifx\csname\exstring@#1@C1\endcsname\relax

to see if #1 is a construction like \list with several counters. If this test also gives a positive result, we want to give an error message,

\noexpandvalue can't be used with \string#1

(see section 3.4 for the use of \noexpand) but if this second test is false, we want to call \value@#1, where \value@#1#2 tests whether

\csname\exstring@#1@C#2\endcsname


but we won't bother printing the code for \Evaluate, because it is strictly analogous, except that it globally sets the value of the counter \Value, instead of printing a number.

The definition of \pre#1 is quite similar, except that instead of typesetting

\number\csname\exstring@#1@C\endcsname

we typeset

\csname\exstring@#1@P\endcsname}

(we enclose this material inside braces, in case a font change instruction is involved).

Only the first part of the definition will be given:

\def\pre#1{\expandafter \ifx\csname\exstring@#1@P\endcsname\relax \expandafter\ifx\csname\exstring@#1@P1\endcsname\relax \def\next@{\Err@\noexpand\pre can't be used with \string#1}}% \else \def\next@{\pre@#1}% \fi \else \def\next@{\csname\exstring@#1@P\endcsname\}% \fi \next@}

Notice that we now use \foo@P and '\foo@P1' rather than \foo@C and '\foo@C1' to determine whether \pre can be used with \foo. So it is possible for \Reset\foo to be allowed but not \pre\foo and vice versa. This generality will extend to all our constructions, and will even be of some importance in Chapter 25.

The definition of \post is strictly analogous to that for \pre, but with 'Q' replacing 'P' in the tests.

The definition of \style is also analogous, except that we don't have the extra set of braces, i.e., we have the clause

\def\next@{\csname\exstring@#1@S\endcsname} Nevertheless, this definition functions quite differently, because the \next@ that we call will actually be a control sequence that will process its argument (the following input).

And exactly the same remarks hold for \numstyle.

On the other hand, \fontstyle has to be handled differently, because we want something like

\fontstyle\claim{...} to expand to

\claim@F...} so \fontstyle#1 must itself be a control sequence with an argument:

\def\fontstyle#1{\expandafter \ifx\csname}\exstring@#1@F\endcsname}relax \expandafter\ifx\csname}\exstring@#1@F\endcsname}relax \def\next@{\Err@{\noexpand}fontstyle can't be used with \string#1}\% \else \def\next@{\fontstyle@#1}\% \fi \else \def\next@##1{\csname}\exstring@#1@F\endcsname#1}\% \fi \next@}

}def{fontstyle@#1#2{expandafter {ifx}csname}exstring@#1@F#2{endcsname}relax {def{\Err@{\String}fontstyle}string#1can'tbe  followed by {string#2}}% {else {def{\next@#1{{\csname}exstring@#1@F#2}endcsname##1}}% {fi {next@} ```
Next we come to the constructions that allow us to manipulate the values, namely \Reset, \Offset, and the \new.... constructions.

\Reset is similar to \fontstyle, in that \Reset\tag, for example, must be a control sequence with an argument, namely the number following \Reset\tag.

There is also one new wrinkle. If we \Reset\tag5, for example, then we want to set the \tag counter, \tagCC, to 4 (since the next use of \tag increases this counter by 1 before printing the \tag). But if we \Reset\page5, then we simply want to set \pagenc=5;1 this special case is handled by the boxed code:
``` \def\Reset#1{expandafter {ifx}csname}exstring@#1@C\endcsname}relax {expandafter\ifx}csname}exstring@#1@C\endcsname}relax {def\next@{\Err@{\nonexpand\Reset can't be used  with \string#1}}% {else {def\next@{\Reset@#1}% \fi \else \def\next@##1{\count@=##1\relax \ifx#1\pagec\else}advance\count@ by -1 \fi \global\csname\exstring@#1@C\endcsname=\count@}% \fi \next@} ```
\def\Reset@#1#2{expandafter \ifx\csname\existing@#1@C#2{endcsname}relax \def\next@{\Err@{string}Reset\string#1can'tbe  followed by \string#2}}% \else \def\next@##1{\count@###1{relax}avance\count@by-1 \global\csname\existing@#1@C#2{endcsname=\count@}% \if \next@} ```

We won't repeat the code for \Offset, which is analogous to that for \Reset, except that we don't need any special compensation for \page. However, there is an important point to be made about both \Reset and \Offset. Suppose that we have used

\NameHL1\chapter

(see Chapter 28). Then \Reset\chapter sets the value of the counter \chapter@C, while \Reset\HL1 sets the value of the counter \HL@C1'. But when we look at the definition of

\NameHL1\chapter

we see (page 219) that it basically involves

\let\chapter@C=^\HL@C1'

and this means that \chapter@C and '\HL@C1' are simply two different names for the _same counter_ (e.g., \count47). Consequently, \Reset\chapter and \Reset\HL1 have exactly the same significance, and the same is true of \Offset.

This fortunate circumstance will not extend to \newpre, which introduces numerous new problems. First of all, \newpre is used in a construction like

\newpre\tag{(newpre material)}

So \newpre\tag should essentially define \next@ to be

\def\tag@P

and then call \next@, so that we will obtain

\def\tag@P{(new pre material)}

allowing the \def to do the work of scanning the {\(new pre material)}.

As a first attempt we might use

\def\newpre#1{\expandafter \ifx\csname\existing@1@P\endcsname\relax \expandafter\ifx\csname\existing@1@P1\endcsname\relax \def\next@{\Err@{\noexpand\newpre can't be used  with \string#1}}% \else \def\next@{\newpre@#1}% \if \else \def\next@{\expandafter \def\csname\existing@#1@P\endcsname}% \if \next@}

However, there are two features that need to be added to this definition:

1. As mentioned on page 192, we really want an \def rather than a \def.
2. If we have used \NameH1\chapter, then, unlike the situation with \offset and \Reset discussed above, \chapter@P and \H1\H2P1' are two independent control sequences, and special efforts are required to insure that \newpre\chapter and \newpre\H1 will each change \chapter@P and \H1\H2P1'.

For (1) it would appear that we simply have to replace the

\expandafter\def\csname\existing@#1@P\endcsnamewith

\expandafter\edef\csname\exstring@#1@P\endcsname

Unfortunately, things are not quite that simple, because, although \newpre should involve an \edef, we still want this \edef to be carried out while \noexpands@ is in force!

This would seem to require something like

\begingroup\noexpands@

\expandafter\edef\csname\exstring@#1@P\endcsname

But that means

1. We need to supply an \endgroup after the \edef is completed.
2. This \edef must therefore be an \xdef in order to survive the grouping.

We can attack these two problems at once by saying

\def\next@{%}

\def\next@{}endgroup

\expandafter\let\csname\exstring@#1@P\endcsname

\=\Next@}

\begingroup\noexpands@\afterassignment\next@

\xdef\Next@}

\next@

Thus, \next@

1. first supplies \begingroup\noexpands@,
2. and then it \xdef's Next@ to be the following text;
3. after that assignment is completed, it supplies an \endgroup, and
4. then it (locally) lets \...@P be this (globally defined) \Next@.

We use \Next for this globally assigned scratch token (page 22).

For (2) we have to worry about the fact that a single control sequence to which \newpre applies, like \chapter, might have an associated pair \HL1 to which \newpre should apply, and conversely, a pair like \HL1 might have an associated control sequence \chapter.

In section 23.14, we already noted that if \chapter is created by

\NameHL1\chapter

then 'HL@R1' will be defined, with \chapter as its value, and \chapter@R will be defined and have as value the pair {HL}{1}.

On page 218 of that section, one of the problems associated with this \...@R... mechanism was handled with the code

\def\nertiv@{\let\nextiii@=} \expandafter\nextiiv@\csnameHL@R1\endcsname

which makes the "nameable" control sequence \nextiii@ have the same value as 'HL@R1'.

More generally, we will define

\def\getR@#1#2{\def\nextiiv@{\let\nextiii@=}% \expandafter\nextiiv@\csname\existing@#1@R#2\endcsname}

which can be used in two ways.

1. First of all

\getR@\chapter[]

will make \nextiii@ be \chapter@R. We will also define

\def\letR@#1#2#3{\expandafter \let\csname#1@#3#2\endcsname=\Next@}

Then the effect of

\getR@\chapter[\expandafter\letR@\nextiii@ P

is
\letR@\(\expansion of \chapter@R)P i.e., \letR@{HL}{1}Phence \let^\HL@P1^=\Next@
2. On the other hand, \getR@\HL1 will make \nextiii@ be ^\HL@R1'. We will also define \def\letR@@\#1#2{expandafter \let\csname\exstring@@1@@\endcsname=\Next@} Then the effect of \getR@\HL1 \expandafter\letR@@\nextiii@ P is \letR@@\(\text{expansion of}^\}\HL@R1')P i.e., \letR@\chapter P hence \let\chapter@P=\Next@

Putting this all together, we can define \newpre as follows:

\def\newpre#1{expandafter \ifx\csname\exstring@#1@P\endcsname\relax \expandafter\ifx\csname\exstring@#1@P1\endcsname\relax \def\next@\Err@{\noexpand\newpre can't be used with \string#1}}% \else \def\next@{\newpre@#1}% \fi


but this can be handled in much the same way as \newpre. For example, we want \newstyle\tag to define \next@ to be

\def\tag\gs

and then call \next@, so that we will obtain.

\def\tag\gs(parameter text)\((replacement text)\)

In this case, we want a \def, rather than an \def, and we don't need to enter a group with \noexpands@. Aside from these differences, however, we simply copy the code for \newpre:

\def\newstyle\ef1\expandafter \ifx\csname\existing@#1@S\endcsname\relax \expandafter\ifx\csname\existing@#1@S\endcsname\relax \def\next@\Err@\noexpand\newstyle can't be used with \string\item\}\% \else \def\next@\newstyle\#1\% \fi \else \def\next@\% \def\nextii@\% \expandafter\let\csname\existing@#1@S\endcsname =\Next@ \expandafter\ifx\csname\existing@#1@R\endcsname\relax \else \getR@#1\expandafter\letR@\nextii@ S\fi\% \afterassignment\nextii@\gdef\Next@\% \fi \next@\}

\def\newstyle\ef1\#2\expandafter \ifx\csname\existing@#1@S\#2\endcsname\relax \def\next@\{\Err@\{\}string\newstyle\string\#1 can't be followed by \string\item\}\%


else \def\next@##1{% \gdef\Next@{##1}%  \expandafter\let\csname\exstring@#1@N\endcsname =\Next@  \expandafter\ifx\csname\exstring@#1@R\endcsname\relax \else \getR@#1{\expandafter\letR@\nextiii@N\fi}%  \ri \next@}

\def\newnumstyle@#1#2{\expandafter \ifx\csname\exstring@#1@N\#2\endcsname\relax \def\next@{\Err@{\string\newnumstyle\string#1 can't be  followed by \string#2}}% \else \def\next@##1{%  \gdef\Next@{\#1}%  \expandafter\let\csname\exstring@#1@N\#2\endcsname =\Next@  \expandafter\ifx\csname\exstring@#1@R\#2\endcsname\relax \else \getR@#1{\#2}\expandafter\letR@@\nextiii@N\fi}%  \fi \next@}

\newfontstyle is exactly analogous to \newnumstyle, so we won't bother repeating the code.

The definition of \word is strictly analogous to that of \pre, etc., with W substituted for P everywhere, and word substituted for pre everywhere.

The definition of \newword follows that for \newstyle, where we want a \def, rather than an \edef, and don't need to enter a group with \noexpands@.

}def\newword#i{\expandafter \ifx\csname\exstring@#10W\endcsname\relax \expandafter\ifx\csname\exstring@#10W1\endcsname\relax \def\next@{\Err@{\nexpand}\newword\can'tbeused with \string#1}}% \else \def\next@{\newword@#1}% \fi \else \def\next@{\def\next@{\nexplainC} \def\next@{\nexplainC}\expandafter\let\csname\exstring@#10W\endcsname =\Next@ \expandafter\ifx\csname\exstring@#10R\endcsname\relax \else \getR@#1{\expandafter\letR@\nextiii@ W\fi}% \afterassignment\nextii@\gdef\Next@}% \fi \next@} \def\newword@#1#2{\expandafter \ifx\csname\exstring@#10W#2\endcsname\relax \def\next@{\Err@{\string\newword\nexpand#ican't befollowedby\string#2}}% \else \def\next@{\% \def\nextii@C} \expandafter\let\csname\exstring@#10W#2\endcsname =\Next@ \expandafter\ifx\csname\exstring@#10R#2\endcsname\relaxelse {getR@#1{#2}expandafter\letR@@\nextiii@ W\fi }% {afterassignment\nextii@\gdef\Next@}% \fi \next@} ```


hand, we don't want to have a separate counter 'foottext@C', since the numbers in the marker and in the footnote certainly have to be the same. (Since \foottext@N is undefined, we also can't have different numbering styles. If, for some weird reason, a style wanted something like a footnote mark of 3 referring to a footnote beginning with iii, the necessary modifications should be pretty obvious.)

25.2. \rfootnote@. In plain tex, the \footnote macro is defined in terms of \rfootnote (footnote in vertical mode), which does the main work of producing an insert. \(\L_{\Updelta}\)-TEX uses \rfootnote@ for this purpose, to avoid any possible conflict (\rfootnote@ will also work rather differently from \rfootnote).

In \(\L_{\Updelta}\)-TEX,

\rfootnote@#1{_ _ }

will be called when #1 represents something like the footnote marker, which has already been determined by other \(\L_{\Updelta}\)-TEX constructions, while'_ _  is the text that we want to appear at the bottom of the page.

A straightforward definition of \rfootnote@ would be

\def\rfootnote@#1#2{insert\footins {\floatingpenalty=20000 \interlinepenalty=\interfootnotetelinepenalty \leftskip=Opt rightskip=Opt \spaceskip=Opt \text{\}rm \{splittopskip=\}ht\strutbox \{splitmaxdepth=\{dp\}strutbox \{locallabel@Uniondent@@{\{footmark@F#1} \} \{strut#2\}strut}\}} \end{\} \right\}\) (using \(\ln\)onident@0, see Chapter 8).

The \locallabel@ defines \thelabel@,..., in terms of \helabel@,..., which have been set by the constructions that will call \rfootnote@ (either \footnote or \foottext); this is for the use of any \label in #2. And #1 will be something like \foottext@S{\hellabel@0}, which we set at the beginning of an unintended paragraph (in the font \footmark@F, if that's relevant). Then the rest of the footnote is typeset in \rm.

The large value of \floatingpenalty, which is the penalty added to a page when there is a split \insert on it, discourages footnotes from breaking across a page. \interlinepenalty is the penalty for page breaks between two arbitrary lines of a paragraph. It is normally 0, but is here temporarily set equal to \interfootnoteleinepenalty, which plain TEX gives the value 200; so if a footnote must split across a page, it will be more likely to split between paragraphs. Other styles might set other values for \interfootnoteleinepenalty.

\leftskip and \rightskip must be set to Opt within the \insert in case it occurs within text where other values are in force (paragraphs indented on the left or right), and similarly for \spaceskip and \xspaceskip (paragraphs set \raggedright, for example).

If a style had a construction that did something else strange, like changing the value of \parfillskip, then this would normally also have to be changed back within the \rfootnote@.

The \strut#2\strut adds a strut to the first and last line of the footnote (compare the footnote on page 57). \strut is defined by plain TEX in terms of \strutbox, which contains a vertical rule of zero width and the desired height and depth of a \strut; in the default style a \strut has height 8.5pt and depth 3.5pt. And \splittopskip is made the height of \strutbox so that the space before the first line of a split footnote will be just the same as if there were a \strut on this line also; similarly, the value of \splitmaxdepth allows footnotes to go below the bottom of the page only by the depth of \strutbox. Normally any point-size command, like \tenpoint, \minepoint, etc., will redefine \strutbox; in the paper and book styles, \rm is replaced by \eightpoint, so that the \strutbox then has a smaller height appropriate for 8 point type; the \rm in this definition has been placed before the assignments of \splittopskip and \splitmaxdepth, to emphasize that in general, font size commands must precede them.

Actually, plain TEX uses

\footstrut#2\strut

where \footstrut is defined as \vbox to\splittopskip{}, which thus has height \strut\strutbox, but no depth. This will be important for a two-line footnote, whenever \lineskiplimit happens to have been chosen to be greater than Opt: If a full \strut appeared on both lines, so that the first line has depth 3.5pt while the second line has height 8.5pt, then these two lines could not be placed together with Opt glue between them because they would then be closer together than \lineskiplimit; consequently, additional \llineskip would intrude.



### 25.2. \rfootnote@

We've now essentially established the required definition, except that there's always the horrid possibility of a footnote only one token long, which has been typed without braces, so we actually need a \futurelet\next to worry about this:

\def\rfootnote@1{insert\footins \bgroup \floatingpenalty=20000 \interlinepenalty=\interfootnotelinepenalty \leftskip=Opt \rightskip=Opt \spaceskip=Opt \rm \rm \splittopskip=\ht\strutbox \splitmaxdepth=\dp\strutbox \locallabel@\noindent@@@{foottext@ff\#1}\modifyfootnote@footstrut\futurelet\next\fo@tt} Here \fof@t calls \f@tt when a group follows, but \f@tt otherwise:

\def\fof\fof\f{\ifcat\bgroup\noexpand\next\expandafter\f@tt\else \expandafter\f@tt\f\} (this is a slight redefinition from plain, using the K-method). Since \f@tt is called when we have a single token following instead of a group, we just insert that token, followed by \@foot, to be defined presently.

\def\fof\#1{\#1}@foot\}

\f@tt is also slightly changed from plain TEX:

\def\f@tt{\bgroup\aftergroup\@foot \afterassignment\FNSSP@\let\next@=\} Here the \afterassignment\FNSSP@ adds \FNSSP@ right after the \{ that the \let\next@= swallows, thereby discarding any space that might come after the \(\{\), and also taking care of the possibility that an invisible construction follows the \(\{\).1




### 25.4. \footmark

Roughly speaking, the \xdef makes \Next@ mean

\ifcase \for(number)1\or(number)2\or(number)3...\else -10000 \if

which immediately picks out either \(number)\({}_{k}\) or -10000. In reality, however, things are trickier, and this code works only by a fluke: As TeX expands \number\footmark@C, it will have to expand out \fnpages@ (since this might stand for another digit of the final number that it is looking for); consequently, all the \'s in \fnpages@ will be revealed, so that TeX will know how many \or's the \ifcase actually has. If we had been "careful" and used

\ifcase\number\footmark@C\relax\fnpages@\else -10000 \f1 then we would always get the case -10000 (being sloppy pays off), so a more intricate scheme would be needed. This observation will also be important when we read in data from a.dat file for tables (Volume 2).

### 25.4. \footmark.

In section 1, we introduced the flag \iffn@, which is true when we are processing a \footnote.

When \footmark is not called indirectly by \footnote, but is called directly (so that the flag \iffn@ will be false), we will have to store

\[\{V_{1}\}\{V_{2}\}\{V_{3}\}\{V_{4}\}\]

where V1,..., V4 have their usual significance (Chapter 11 et seq.), because this information will have to be used by some subsequent \foottext (a \label might appear in the \foottext part, and V2 will be the marker that will appear at the beginning of the \foottext).

This information will be stored in \justfootmarklist@, initially defined to be empty,

\let\justfootmarklist@=\empty

In this case it will be more convenient for \justfootmarklist@ to be a list of the type introduced in _The TeXbook_, page 378, so we will be using \rightappend@ (c.f. section 3.7) to append to it.



252

_Chapter 25. Footnote_

\noexpands@ \let\style=\foottext@S  \Qlabel@{#1}  } \iffn@\else  {\noexpands@ \xdef\Next@{{\label@}-{\label@}  {\label@@}-{\label@@000}  }  } \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi  \#i  \@sf\relax} The definition of \footmark@, the routine when \footmark is not followed by a quoted number "...", will be quite a bit more complicated.

First, we want to advance \footmark@C by 1,

\global\advance\footmark@C by 1

Next we want to define \adjustedfootmark@, which will simply be the value of \footmark@C for non-fancy footnotes, but which will be the properly adjusted value when \fancyfootnotes is in force. For the latter case, we use the strategy explained in section 3. Note that if the test (A) on page 248 makes \Next@ have the value -10000, then we presumably have some new footnotes, not recorded on the last run; in this case we just use \footmark@C for determining the value of \adjustedfootmark@ (another run will be necessary to get everything right):

\ifplainfn@  \xdef\adjustedfootmark@{\number\footmark@C}  \else  {\let\\\\=\vor  \xdef\Next@{\ifcase\number\footmark@C\fnpages@}else-10000 \ifnum\Next@-10000  \xdef\adjustedfootmark@{\number\footmark@C}



### 25.4. \footmark

\iffn@\else {\noexpands@ \xdef\Next@{{{\Thelabel@}{\Thelabel@}% {\Thelabel@@@}{\Thelabel@@@}}% }% \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi \@sf\relax}% \futurelet\next@}

\def\footmark@\% \iffirstchoice@ \global\advance\footmark@C by 1 \ifplainfin@ \xdef\adjustedfootmark@{\number\footmark@C}% \else {\let\\\\=\or \xdef\Next@{\ifcase\number\footmark@C}\fnpages@@ \else-10000 \if\ifnum\Next@=-10000 \xdef\adjustedfootmark@{\number\footmark@C}% \else \ifnum\Next@=\lastfinpage@@ \global\advance\fancyfootmarkcount by 1 \else \global\fancyfootmarkcount@=1 \global\lastfinpage@@=\Next@ \fi \xdef\adjustedfootmark@{\number\fancyfootmarkcount@}% \fi \fi \f\n@expands@@ \xdef\Thelabel@@@\adjustedfootmark@@}% \xdef\head@\footmark@@


#### 25.5. \foottext

Assuming this hasn't happened, we will use the process just described to make \next@ be the first thing on \justfootmarklist@, and to redefine \justfootmarklist@ to be the remainder.

And then we will use

\expandafter\foottext@\next@

so that \foottext@ can use the four values of \next@:

\def\foottext{\prevanish@ \ifx\justfootmarklist@\empty \Err@{There is no \noexpand\footmark for this \string\foottext}\fi \def\next@\######2\next@{\def\next@{\aff1}\% \gdef\justfootmarklist@{\#2}\% \expandafter\next@\justfootmarklist@\next@ \expandafter\foottext@\next@}

Once again, for the \noexpand in the error message, see section 3.4. \foottext@ simply uses the next four values for defining \Thelabel@,..., \Thelabel@@ee@, and then calls \vfootnote@ with the value of \thelabel@@ (the \locallabel@ part of \vfootnote@ sets this to the current value of \Thelabel@, namely the second value of \next@):

\def\foottext@##1\2\3\4[\{\noexpands@ \xdef\Thelabel@{\#1}\xdef\Thelabel@@{\#2}\% \xdef\Thelabel@@@0{\#3}\xdef\Thelabel@000{\#4}\% \vfootnote@{\thelabel@00}\}

The \vfootnote@ will put in a \postvanish@ at the end, to match the \prevanish@ at the beginning, since \iffn@ will not be true when \foottext is processed. The only thing left to do now, is to

\rightadd@\foottext\to\vanishlist@


_Part IV Miscellaneous_

_Constructions_* [15]



#### 26.1. In-line literal mode

I made this choice so that the first line could at least indicate that more than one space was involved, but it looked too weird to have spaces at the beginning of the next line. If that more literal sort of literal mode is preferred, it is only necessary to define the active space to mean

\allowbreak\hbox to.5em{}\hskip0emminus.15em

In practice, one would presumably be printing \'s if the number of spaces needs to be emphasized.

The \allowbreak at the beginning of the definition of a space in literal mode does introduce one slight complication: we should

\def\lit*{\leavevmode\begingroup..}

--otherwise a '\lit*' at the beginning of a paragraph will contribute an \allowbreak in _vertical_ mode, possibly overruling a \nubreak that occurs before it.

Moreover, the definition of \lit@ should be changed to

\def\lit@#1*{\endgroup\null}

so that a \lit*...* construction ending with a space won't have this space deleted by any succeeding \unnskip.

Making spaces active means that we don't have to say \frenchspacing, since now there aren't any spaces after punctuation. However, as _The TeXbook_ points out (page 381), there's another slight problem, because the \tt font has the ligatures?' and!', which print as \_l and \_i_ respectively (sign). So we must

\catchcode'\'=\active\gdef'{\relax\lq}

and then use

\catchcode'\'=\active\obeyspaces\defspace\at the end of the definition of \litcodes@.


#### 26.2. Displayed literal mode

where \CtrlM@ will be defined in a moment, so that \letMe will make ~~M have the meaning of \CtrlM@ once \bobeylines has appeared.

We can begin defining \Lit* by:

\def\Lit*{\bigskip\begingroup \litcodes@\bobeylines\letMe\tt\Lit@}

We don't need to disable hyphenation, since we are going to be setting each line as a separate \hbox (and therefore the shrink in the definition of the active space will also be irrelevant). For reasons to be discussed in section 3, \litdefs@ hasn't been included yet.

\Lit@ will begin setting an \hbox, so we first declare

\newbox\litbox@

and then

\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@}

Thus, the \Lit@ will start setting \box\litbox@ to be whatever is on the current line, with the literal codes in effect, as well as the temporary definitions from \litdefs@. When we get to the end of the line, we will encounter a ~~M, which will have the meaning of \CtrlM@, which we can define by

\def\CtrlM@{\bogroup \box\litbox@

\Lit@}

so that the ~~M will simply cause the \hbox containing the line to be added to the vertical list, and then start setting another \box\litbox@.

In order to have the closing * end the literal display, the simplest method is to make the * _active_ during the display and have it defined by

\def*{\egroup\endgroup\bigskip}

The \egroup ends the \box\litbox@ that started being set at the beginning of the line containing the *, but instead of adding this (presumably empty)


_And this is extremely important:_ After any particular box\litbox@ has been placed on the main vertical list, TeX may decide to exercise the \output routine, possibly long before the \endgroup supplied by the final *. If we had put \litdefs@ right into the definition of \Lit*, then \litdefs@ would be in effect when the \output routine is invoked, which could lead to havoc. For example, suppose that in the book style we have typed

\chapter The \LamSTeX\ Co\"op\endchapter

so that even-numbered pages will use

The \LamSTeX\ Co\"op

in the running heads. Then if this running head happened to be typeset while the literal mode definitions are in force, we would end up with

The \Lit\$-TeX\Co"op

since the \' symbol is \char32 in the Computer Modern fonts, while \char34 is ". Similarly, the user should be able to define \0 and \1, and have them used in running heads, without worrying about them changing definitions if the output routine is invoked in the middle of literal mode.

_26.4. Prohibiting page breaks._ Normally, we want to prohibit breaks between lines of displayed literal material, so we also want to add a penalty after \box\litbox@. We will declare a new counter

\newcount\interlitpenalty@

\interlitpenalty@=10000

and we will have \CtrlM@ (page 265) add \penalty\interlitpenalty@ before the current \box\litbox@ except for the very first box (other constructions, see section 8, can insert other penalties, or give different values to \interlitpenalty@). The following definition takes care of this, together with the fact that we also don't want the empty box from the first line (page 266):

\def\CtrlM@{\egroup \ifcase\littlines@ \advance\littlines@ by 1 \or \box\litbox@ \advance\littlines@ by 1 \else \penalty\interlitemalty@\box\litbox@ \fi \Lit@

Notice that with this arrangement, \penalty\litemalty@ends up being added after each \box\litbox@, _except_ the last box, so that a page break can occur at the \biggskip supplied by the closing * (page 265); an explicit \penalty could be added before the \biggskip if we wanted to discourage or encourage a page break at that point.

#### Indentation

We usually want displayed literal constructions to be indented by a certain amount. So we declare a new dimension

\newdimen\litindent

with the default value

\litindent=2Opt

and we add \hskip\litindent at the beginning of each box:

\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@\hskip\litindent}

#### TAB's

Proper interpretation of the TAB character (~~I) is another feature that we want to add. We will use

\catcode'\~~I=\active\gdef\letTAB@{\let~~I=\TAB@}}

so that \letTAB@ will make an active~~I mean \TAB@, which we will define in a moment, and then we will add

\catcode'\~~I=\active\letTAB@to the definition of Lit*, before the \obeylines.

For \TAB@, we want, first of all, to allow for variances in the spacing for TAB's. So we will create a new counter, with the default value 8,

\newcount\littab@ \littab@=8 as well as the construction \littab, to change the value,

\def\littab#1\littab@=#1\relax\

Every time that we encounter a ~~I while we \setbox\littbox@, we want to supply an \egroup, so that \box\littbox@ will be complete, add extra space at the end of \box\littbox@ so that it has the requisite width (namely the next multiple of \littab@ times the width of \lbox\ltt0), and then include all this at the beginning of another

\setbox\littbox@=\lthox\bgroup\littdefs@ _The TEXbook_, page 391, gives a simple way to find the required extra space: If \dimen@ is the width of our box, and \dimen@ii is \littab@ times the width of \hbox\ltt0}, then to see how many times \dimen@ fits within \dimen@ii, we can simply

\divide\dimen@ii by \dimen@ \multiply\dimen@ii by \dimen@ Here \dimen@ will be converted to its equivalent in scaled points (i.e., 1pt will become 65536). At the end, \dimen@ii will be the largest multiple of \dimen@ that is \dimen@ii, so we will just have to increase \dimen@ by \littab@ times the width of \hbox\ltt0} to move to the next tab.1 We have to remember, however, that all our boxes begin with an extra \litindent amount of space:

\def\TAB@{\egroup\dimen@=\wd\littbox@ \lattab@ \advance\dimen@ by -\litindent


before a literal display. One could even add a clause

\predisplaypenalty=...

changing \predisplaypenalty from its default value of 10000, to allow, or encourage, page breaks before a literal display (if this done, then a \penalty of that amount should be added before the \biggiskip in the \else clause above). However, the last line on page 85 is just wrong: changing \displaywidowpenalty within the formula won't affect anything.

As with displayed formulas (compare section 16.1), special care is required in the definition of * made by \defstar@ (page 265), in case an invisible construction follows. Basically we need to augment the definition to

\egroup\endgroup\biggskip

\vskip-\parskip

\noindent@@@@\\futurelet\next\pretendspace@

to start a \noindent'ed paragraph, and take care of the fact that an invisible construction may follow (compare page 146). But now we have an extra complication: we must skip over the space following the * before adding the \noindent@@@@, so that our \noindent'ed paragraph doesn't begin with an extra space. So we really need

\egroup\endgroup\biggskip

\vskip-\parskip

\def\next@{\noindent@@@@\\futurelet\next\pretendspace@}

\FNSS@\next@

\endgroup\biggiskip

\def\next@{\noindent@@@\\futurelet\next\pretendspace@}

\FNSS@\next@

\endgroup\biggiskip

\begin{array}{@{}{}}\end{array}

As in the case of a displayed formula (page 101), users must be warned against adding "invisible" constructions at the end of a literal display that ends a paragraph.

\endgroup\biggiskip

\begin{array}{@{}{}}\end{array}\]

The treatment of the end of display literal mode has been changed from version 1 of \(\ref{L44}\)-\(\ref{L44}\), where a displayed formula was added at the end also (with undesirable side effects).


26.8. Page breaks

Then

(a line of the literal display)

"allowdisplaybreak

(the next line of the literal display)

will produce

(a line of the literal display)

penalty 0

appropriate \baselineskip glue for next box

(the next line of the literal display)

Finally, we will define

\def\allowdisplaybreaks{\egroup\allowbreak

\interlitpenalty=0 \litlines@=0 \lit@}

In this case,

(a line of the literal display)

"allowdisplaybreaks

(the next line of the literal display)

produces

(a line of the literal display)

\penalty 0

appropriate \baselineskip glue for next box

(the next line of the literal display)

\penalty 0

with a \penalty0 after all succeeding lines of the literal display, except the very last (see page 268).



)

\leftmargin\litindent \litindent=20pt \newbox\litbox@ \newcount\interlitpenalty@ \interlitpenalty@=10000 \newcount\litlines@

{\obeyspaces\gdef\defspace@{\% \def {\allowbreak\hskip.5emminus.15em\relax}}}

{\obeylines\gdef\letM@{\let^^M=\CtrlMe}}

{\catcode^\'=\active\gdef'{\relax\lq}}

\def\CtrlMe\{\ggroup \ifcase\litlines@ \advance\litlines@ by 1 \or \box\litbox@ \advance\litlines@ by 1 \else \penalty\interlitpenalty@ \box\litbox@ \liit@}

\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@ \hskip\litndent}

\newcount\littab@ \littab@=8 \def\littab#1{\littab@=#1\relax}

{\catcode^\~~I=\active\gdef\letTAB@{\let^\~~I=\TAB@}}

def\TAB@{\getop \dimen@=|wd\litbox@ \advance\dimen@ by -\litindent \setbox0=\hbox{\ttot}% \dimen@ii=\litttab@|wd0 \divide\dimen@ by \dimen@ii \multiply\dimen@ by \dimen@ii \advance\dimen@ by \littab@|wd0 \advance\dimen@ by \litindent \setbox\litbox@=\hbox{\hbox{\ttbgroup}litdefs@ \hbox{\hbox{\tt\cup}}\hbox{\tt\cup}}\)

We want to allow the possibility that no literal backslash has been chosen. For this purpose, we will first

\let\litbs@=\relax

and then have \litdelimiter#1 redefine \litbs@, so that we can insert \litbs@ within our definitions whether or not a literal backslash has been chosen.

\litdelimiter#1 must define \litbs@ so that it first sets the category code of #1 to 0 For this we can use

\edef\litbs@{\catcode^\string#1=0...

In this \edef, the only thing that gets expanded is the \string#1. Since this gives us a character C of type 12,

\catcode^C=0

without the usual \ after the'is quite legitimate; that's fortunate, since

\catcode^\#1=0

would be totally misinterpreted as

\catcode 351=0 (35 is the category code of #)When we say \littdelimiter" we also want \litbs@ to save away the definition

\def\"{char'{}string"}

in \litbs@0, and similarly for any other argument that may be used with \littdelimiter. Here we will need our old \expandafter\noexpand trick (pages 126 and 161):

\let\litbs@=\relax

\def\litbackslash#1{% \edef\litbs@% \catcode'\string#1=0 \def\noexpand\litbs@@{\def\expandafter\noexpand \csname\string#1\endcsname\char'{}string#1}}% \littodes can now be defined by

\def\litcodes@{\catcode'\=12 \catcode'\{=12 \catcode'\=12 \catcode'\$=12 \catcode'\$=12 \catcode'\#=12 \catcode'\^=12 \catcode'\=12 \catcode'\=12 \catcode'\^=12 \catcode'\^=12 \catcode'\^=12 \catcode'\^=12 \catcode'\:=12 \catcode'\:=12 \catcode'\=12 \catcode'\W=12 \litbs@\catcode'\'=\active\obeyspaces\defspace@} Notice that we need the \catcode'\"=12 since " is normally active in \L\\$-TEX. The \litbs@ is placed after all the other \catcode's, since it may effect a further category code change (e.g., the category code of " may then be changed to 0).

The extra \cactode's for ; and : and! and? are inserted just in case any of these have been made active for French styles (compare 3.10).

Now comes a tricky part. \litedlimiter#1 will define \List#1, and part of this definition will be to make #1 active and then properly define it. So we want a construction, \activate@#1, which will define #1 properly when it is active. But putting

 \def#1{...} in our definition won't work, since the #1 will be read in before #1 actually is actively So we will resort to the \lowercase trick. We first use

 \lccode'\"='#1 to make the \lccode of the _active_ character ~ be #1 (only an ordinary character is allowed for the literal delimiter, so the '#1 is fine). This means that when ~ appears within a \lowercase it will be turned into an _active_ #1.

So then we can do something like

 \lowercase{% \gdef\defdelimiter@{\def^{\_..}} } so that \defdelimiter@ will define our delimiter #1 properly once it is active. We will need a similar, but different, definition for the redefinition of #1 for \Litbox, so we will let \activate@ have two arguments--the first, which will always be either 0 or 1, determining which value the global scratch token \Next@ (see page 22) will be given:

 \def\activate@#1#2{{\lccode'\"='#2% \lovercase{% \if0#1% \gdef\Next@{\def^{\_ef^{\_egroup}endgroup \bigskip}\vskip-\parskip \def\next@{\_{\_{\_}}}\niondent@@@{\}futurelet\next\pretendspace@}% \FNSS@\next@)}%)

}else \gdef\Next@{def^{\agroup\egroup}}% \fi }% }% }} ```
Another thing \littledimiter#1 will do is to set \littledim@ to be the character code for #1:

\edef\littledim@{\char'#1} since this will be used by \littlefs@:

\def\littlefs@{\let\0=\empty\def\littledim@}% \def\{\char32 }\little8@@}
```

Remember that \little8@ is either \relax or the proper definition of \" if \littledimiter" has been used, etc.

Finally, \littledimiter#1 then defines \lit#1, \Lit#1 and the construction \Litbox#1=#1. The definitions are just those in the previous sections, except that \Lit#1 will use

\catcode'#1=\active \activate@0#1\Next@ to get the literal delimiter #1 active, and give it the proper definition, while \Litbox#1=#1 will use

\catcode'#1=\active \activate@1#1\Next@ to get the proper definition for that case:

\def\littledimiter#1{\% \edef\littledim@{\char'#1}% \def\little#1{\leavevmode\beggroup}littleodes@\littlefs@ \tt\thyphenchar\tent=-1 \lit@}% \def\little######1{\#\#1{endgroup\null}%



Making * active does necessitate some small changes in other parts of \(\lak\$\$\$-TEX. First of all, I changed the plain definition of \ast to

\def\ast\string*}

so that \ast just gives the category 12 *, and can thus be used both in text and in math mode (giving the symbol * in text, but * in math).

Then I had to examine all the places where * already appears in lamster.tex.

1. Its appearance in the definition of \fnsymbol requires no change, since the * appearing there is a type 12 *.
2. However, the definition of \starparts@ needs to be restated, after * has been made active, because it uses a * as part of the syntax for the subsidiary control sequence next@.
3. Similarly, the definition of \starparts@@ uses * as part of its syntax, so it needs to be restated.
4. And the same was true of \iabbrev. Moreover, in this case, the * in the replacement text needs to be replaced with \noexpand*.

There are also a few definitions for mathematics where * appears.

1. The first is in the definition of \keybin@ (section 3.10). Since \ast would now be used instead of * in a math formula, in the definition of \keybin@ the

\ifx\next* clause needs to be replaced with

\ifx\next\ast
2. It also appears in \boldkey. Although \boldkey is meant to be used with symbols on the keyboard, rather than control sequences, it would probably be reasonable to change the clause

\ifx\first\mathcharii@203 \else

\ifx\first\ast\mathcharii@203 \else

and agree that \boldkey can also be used with \ast.



The boxed additions to the definition of \star00 are needed because of a strange TEX "feature".

Suppose we type

\hangafter-2 \hangindent=20pt

Here are several...

lines of text.

\vskipin

Here are several...

lines of text.

Here are several...

lines of text.

Then the first paragraph, implicitly ended by the \vskipin, will have hanging indentation of 20 points for the first two lines (like these small print notes), while the next two paragraphs will be treated normally. But now suppose we type

\hangafter-2 \hangindent=20pt

Here are several...

lines of text.

\vskipin}

Here are several...

lines of text.

Then the second paragraph will also having hanging indentation for the first two lines!

Reason: The \vskipin, implicitly ending the first paragraph, causes TEX to restore \hangafter and \hangindent to their default values, as with any other locally defined TEX parameters.1 So, after the \ that follows the \vskipin, the values of \hangafter and \hangindent_are still_ -2 and 20pt, respectively!!


**Chapter 27. Literal mode in heading levels**

As mentioned in Chapter 25, our definitions allow literal mode to work within \footnote's. It might seem that it should be just as easy to allow literal mode constructions within heading levels, but here the situation is much more complex.

Remember that something like

\hli{Extra \lit*}* errors}

must not only typeset 'Extra } errors', it must also send

Extra \lit*}* errors

off to the.toc file, and it's not very clear how we are going to get these tokens, with unbalanced braces, stored inside a control sequence1 Moreover, a \footnote, no matter how formatted, usually involves an \insert\footnote{...}, so a style file designer who wants to change the appearance of a \footnote probably won't to have to worry about the trickery involved in allowing category changes. But it seems much less reasonable to commit heading levels to something like

\global\setbox1=\vbox{...}

since heading levels for other style files might have to be handled quite differently.

Of course, in the great majority of cases, even when literal mode is used, it won't be needed in header levels. And even when literal mode material does occur in header levels, usually only small snatches are needed, which can behandled quite easily with special definitions. For example, for this manual, where control sequences appear quite often in heading levels, I defined

\def\CS#1{{\tt\char'134 #1}}

so that the next section could be typed as

\section{Literal mode in \CS{HL} and \CS{hl}}

With a few definitions for the backslash \ and the curly braces { and }, virtually any literal mode material can be included in heading levels.

For this reason, lamstex.tex does not directly address the problem of literal mode in heading levels. However, there is a subsidiary file, lithl.tex, which adds new definitions that allow literal mode to be incorporated, albeit somewhat indirectly, within heading levels.

#### Literal mode in \HL and \hl.

If the file lithl.tex is \input, before a \litdelimiter and \litbackslash are declared, then \lit*...* will generally act as before, but two special extensions will be introduced:

1. On the one hand, we can type \lit_n*...* for \(n=0,\ldots,9\). This will not typeset... in literal mode, but simply store the corresponding literal mode tokens in a special storage space, one for each of 0,..., 9.
2. On the other hand, the combination \lit_n_ (where the next symbol is _not_ a *) will simply give a copy of whatever is stored in storage space \(n\).

So, for example, the current section could be typed as

\lit0*\HL* \lit1* \section{Literal mode in \lit0 and \liti}

)

lithl.tex creates new boxes

\expandafter\newbox\csnamelit@0\endcsname

\expandafter\newbox\csnamelit@1\endcsname

for the storage locations, and makes \lit a control sequence with an argument,

\lit#1

If * is going to be the literal delimiter, then when the argument #1 is * we use \lit@@0, which is essentially the old \lit*, but if #1 is not * (and thus presumably one of 0,..., 9), we set

\count@=#1

and then use

\futurelet\next\lit@0

The \futurelet is needed to see whether the next character is a * or not. If it isn't (so that we have something like '\lit0 and'), then we simply use

\nthcopy\csnamelit@\number\count@\endcsname\null

(the \null is added for the same reason that is was added to the original definition of \lit@ [page 263]). But if we now have a *, so that we are in the case

\litn*...*

we use the routine \lit@000.

We might define \lit@000*\def\lit@00@*\prevanish@\begingroup

\litcodes@\litdefs@\lit@000@}

27.1. Literal mode in \HL and \hl

\def\lit@@@@@@#1*{\toks@@={#1} \global\expandafter\setbox \csnamelit@\number\count@\endcsname =\hbox{ttt\the\toks@@} \endgroup\postvanish@@} with \prevanish@@ and \postvanish@@ added to make constructions like \lit_n*...* invisible, just in case they get used in a paragraph.

With such definitions,

\lit0*\HL* \lit1*\hl*1 \section{Literal mode in \lit0 and \lit1} will indeed produce the current section title. On the other hand, if we are making a.toc file, then this section will simply appear as

\section{27.1} \[Literal mode in \lit0 and \lit1} so we will also want to have

\lit0*\HL* \lit1*\hl*

written to the.toc file first.

This might seem fairly straightforward (after all the trickery to which we've become accustomed),

\def\lit@@@@@@#1*{\toks@@={#1} \iftoc@@ \edef\next@@{write}toc@{\noexpand\noexpand\noexpand\lit\number\count@*\the\toks@@*\next@@ \fi..... but, alas, it can fail in a subtle way.

Suppose that we wanted a heading like

1. Comparing \u and \space

and therefore typed

\lit0*\" * \lit1*\space* \HL1 Comparing \lit0 and \lit1\endHL

Then the first line would cause the.toc file to contain

\lit0 *\\"

Reason: When we have dutifully established \litcodes@ and \litdefs@ before exercising \lit0000, the token list \toks@ contains two tokens: the first token is a type 12 \, and the second token is 'control-space', i.e., the control sequence whose name is "'when " is the escape character, and \'when \ is the escape character, etc. When TeX goes to print that control sequence in the.toc file, it will simply print it as '. To put it another way, the tokens '\'that get written really consist of a type 12 \ followed by a type 0 \ followed by a space, but once the tokens are written, the category codes become irrelevant.

To get around this problem, we use the following byzantine strategy. After using \litcodes@ to change the category codes, we add

\catcode'\"=12

so that " is just an ordinary character. Then \toks@ will be just the ones that we want to write to the.toc file. The problem, of course, is that they are no longer the tokens that we want to put in the \hbox: we really have to read in the *\.** material once again, this time _without_ making the special change for ". Although we cannot get TeX to back up and read the argument again, nevertheless we can reread the argument, by first _writing_ the token list \toks@ to a temporary file, and then reading it in again with the proper codes!

\newwrite\tempwrite@ \newread\tempread@27.1. Literal mode in \HL and \h1

Unfortunately, that doesn't quite work either, because there is no way that \next@ can reflect the exact number of spaces that occurred at the end of the *...* sequence that we wrote to \tempwrite, since spaces at the end of a line are always stripped off by TEX as it reads. So yet another fillip has to be added: We will always add a * at the end of the sequence (this * can't occur within the sequence, although "1 can appear to indicate this character), and then we will strip off the * and everything following (presumably just the space inserted by the ~~M at the end of the line) from \next@:

\def\lit@@@@@@@1*{\toks@={#1}% \iftoc \def\next@{\write}toc@{\noexpand\noexpand\noexpand\noexpand\lit\number\count@*\the\toks@*\next@\fi\immediate\openout\tempwrite@=\jobname.tmp \immediate\write\tempwrite@{\the\toks@\%}% \immediate\closeout\tempwrite@ \catcode'\"=0\litdefs@ \immediate\openin\tempread@=\jobname.tmp \read\tempreadto\next@ \immediate\closein\tempread@ \def\next\in\#\#1*\#2\next@{\def\next@{\#1}}% \expandafter\next\inti@\next@\next@\%global\expandafter \setbox\scanmelit@number\count@\endcsname =\hbox\{tt\next@} \endgroup \postvanish@\}

#### The general definitions

The previous section indicated definitions to be used when * is the literal delimiter, and " is the literal backslash. Now we will give the code in general.

The file lithl.tex begins, like lamstex.tex itself, with

\catcode'\@=11

As illustrated here, we will always use double horizontal lines for code that is in subsidiary files, rather than in lamstex.tex itself.

Since we are going to use \new... constructions we then declare (compare page 38)

\let\alloc@=\alloc@

First we declare new boxes,

\expandafter\newbox\csnamelit@0\endcsname \expandafter\newbox\csnamelit@9\endcsname

and the input and output streams for the.tmp file,



#### The general definitions

\def\allowdisplaybreak{\(\backslash\)egroup\allowbreak \(\backslash\)litlines@=0 \(\backslash\)lit@}% \(\backslash\)def\allowdisplaybreaks{\(\backslash\)negroup\allowbreak \(\backslash\)interlitpenalty@=0 \(\backslash\)litlines@=0 \(\backslash\)lit@}% \(\backslash\)litcodes@\(\backslash\)tt\(\backslash\)catcode'\(\backslash\)~~I=\(\backslash\)active\letTAB@ \(\backslash\)obeylines\letMe@\(\backslash\)Lit@}% \(\backslash\)def\(\backslash\)Lit@>#1=#1{\(\backslash\)begingroup \(\backslash\)ifodd#1\relax\(\backslash\)aftergroup\(\backslash\)global\(\backslash\)fi \(\backslash\)aftergroup\(\backslash\)setbox \(\backslash\)aftergroup\(\backslash\)litrox@ \(\backslash\)def\allowdisplaybreak{\(\backslash\)lit@}% \(\backslash\)def\allowdisplaybreaks{\(\backslash\)negroup\allowbreak \(\backslash\)interprettipenalty@=0 \(\backslash\)litlines@=0 \(\backslash\)Lit@}% \(\backslash\)catcode'#1=\(\backslash\)active\(\backslash\)litcodes@\(\backslash\)tt\(\backslash\)catcode'\(\backslash\)~~I=\(\backslash\)active\letTAB@ \(\backslash\)obeylines\letMe@\(\backslash\)global\(\backslash\)setbox\(\backslash\)ttbox@=\(\backslash\)vbox% \(\backslash\)bgroup\(\backslash\)litindent=Opt \(\backslash\)litlines@=0 \(\backslash\)Lit@}% \(\backslash\)

Finally, we reassign \(\backslash\)alloc@ its original definition from plain TeX, and make @ active again:

\(\backslash\)def\(\backslash\)alloc@11#2#3#4#5{\(\backslash\)global\(\backslash\)advance\(\backslash\)count1#1by\(\backslash\)ne \(\backslash\)ch@ck#11#4#2\(\backslash\)allocationnumber=\(\backslash\)count1#1 \(\backslash\)global#3#5=\(\backslash\)allocationnumber \(\backslash\)wlog{\(\backslash\)string#5=\(\backslash\)string#2\(\backslash\)the\(\backslash\)allocationnumber}} \(\backslash\)catcode'\(\backslash\)@=\(\backslash\)active

If the alternate syntax of section 26.11 is used, something different would be needed. For example, we might create \(\backslash\)SL and \(\backslash\)UL (store literal mode material and use literal mode material), so that \(\backslash\)SL_n_*...* stores the material in location \(n\), while \(\backslash\)UL_n_ uses it. With a little work, we could even arrange for *_n_...* to work like \(\backslash\)SL_n_*...*, so that only \(\backslash\)UL would be needed. (For the case of literal mode material that happened to begin with a digit, like 0..., we would then have to use *"00...* to print it.)




### Chapter 29. The bibliography

L_M_S-TEX's bibliography constructions, an extension of those originally used in amsypt.sty, are really quite adequate for most bibliography requirements. They show that various "fields" of information, allowed to appear in any order, can be put together properly by TEX itself, without resorting to an external program like BibTeX. Moreover, as explained on page 98 of the L_M_S-TEX Manual, the bibliographic entries can be labelled, and thus cited within the text using \ref, so that the proper number for a bibliographic entry is printed automatically (after enough passes).

Of course, BibTeX also allows bibliographic entries to be selected from a data base and sorted in any of numerous desired ways. Moreover, the BibTeX approach has the advantage that the final result (the.bbl file) consists of standard (well, almost standard) TEX code, and is thus easily edited and modified. By contrast, it may be quite difficult to coerce L_M_S-TEX's bibliography macros into performing as desired, and many special sorts of TEX trickery had to be built into the macros for this purpose. (With either approach, careful proofreading of the bibliography--rarely attempted by the authors, alas--is advisable, to check that special situations have been handled correctly.

Since many people have already made extensive data bases for BibTeX, which they presumably don't want to go to waste, L_M_S-TEX now provides an interface with BibTeX, as explained in the next chapter. (Of course, it would be nice if there were a LibTeX program, working like BibTeX, but producing a.bbl file with L_M_S-TEX code instead of L_T_EX code.)

Others may prefer using L_M_S-TEX's bibliography macros, however, especially since they provide features missing from BibTeX. I have added all features that the AMS has added to amsypt.sty (though often with modified syntax), not to mention a few more of my own. All in all, this was a rather harrowing experience--I now understand the perils of creeping featureism. I ended up deferring the bibliography macros to the very end, rightly dreading all the details that would be involved. On the other hand, when I finally came to writing this chapter, it turned out that the description of the macros, and the strategy behind them, went rather smoothly.

Most important of all, from the point of view of the user or style file designer, once L_M_S-TEX's hidden macros have taken care of all the messy details, the final process of printing the information from all the fields, in the proper


29.2. Features of LWAS-TEX's bibliography macros
303

29.2. Features of LWAS-TEX's bibliography macros. The original amsppt.sty command \Refs is called

\makebib in LWAS-TEX, and this \makebib now requires a matching

\endmakebib at the end of the entries. With the

\makebib \endmakebib region, the general amsppt.sty syntax

\ref... \endref has been changed to

\bib... \endbib since \ref already has another use in LWAS-TEX.

Within \bib... \endbib we can use the fields

\no \key \by \bysame \paper \your \vol \issue \yr \toappear \pg \pp \book \publ \publaddr \paperinfo \bookinfo \finalinfo which correspond to those from the original amsppt.sty, with \pg and \pp replacing \page and \pages, since \page has another use in LWAS-TEX.

Some changes have been made in conformity with changes by the AMS:

\key now automatically adds brackets, and sets its field in \bf. Thus, \key C1 gives \[\[\mathrm{C1}\]

\* \inbook normally prints only the book title, not preceded by 'in'[which many people don't like very much], although, as discussed below, this can be changed.
* \issue now prints 'no.'before its field, though I think that's very bad (\issue was originally designed for something like 'Special commemorative issue').
* The AMS has also changed \finalinfo, so that it is preceded by a comma, rather than a period after all the previous information. I think that's even worse, and have kept the old arrangement (see page 312 for further discussion of this particular point.)

As in the AMS's new amspt.sty, there is no longer a \manyby to indicate the start of a sequence of \bsysame's. The first reference is simply typed as \by, with \bsysame used for the subsequent ones. In addition, \bsysame now prints a horizontal rule of fixed width, rather than one that varies with the width of the first instance. (This makes the macros considerably easier to write, but it's what journals always use anyway, so there's no point apologizing for the shortcut.)

\moreref has been changed to \morebib. As before, something like

\bib \no 2 \by L. Auslander

\paper On the Euler characteristic of

compact locally affine spaces

\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27

\morebib

\paper \rm II

\jour Bull. Amer. Math. Soc. \vol67 \yr1961 \pp 405--406

\endbib

will produce

2. L. Auslander, _On the Euler characteristic of compact locally affine spaces_, Comment. Math. Helv. **35** (1961), 25-27; II, Bull. Amer. Math. Soc. **67** (1961), 405-406.

If part II of this paper had appeared in the same journal, but in a different volume,

\bib \no 2 \by L. Auslander

\paper On the Euler characteristic of

compact locally affine spaces

\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27

\morebib

\paper \rm II

\vol36 \yr1961 \pp 13--15

\endbib

the output would look like

2. L. Auslander, _On the Euler characteristic of compact locally affine spaces_, Comment. Math. Helv. **35** (1961), 25-27; II **36** (1961), 13-15.

\morebib remembers that there was a \jour before, so it prints the \vol, \yr, and \pp fields for the second title even though no \jour is given for that title.

By the way, this example illustrates one of those innumerable circumstances where a completely automated system won't give the optimal results: journal volume numbers in the default style happen to be printed without commas following the preceding field, which looks just fine for the **35** following 'Comment. Math. Helv.', but not so fine after the shortened title 'II'; in this case we would probably want to change the input to

\paper \rm II,

(see also page 311).

This "remembering" feature of \morebib is generally quite convenient, but it doesn't give the desired results in certain other situations. For example,

\bib \no 3 \by Stefan Banach \paper Sur la d\'ecomposition des ensembles de points en parties respectivement congruents \jour Fund. Math. \vol 6 \yr 1925 \pp 244--277 \morebib \book \OE uvres \publ \'Editions Scientifiques de Pologne \publaddr Warzaw \yr 1967 \endbib will produce
3. Stefan Banach, _Sur la decomposition des ensembles de points en parties respectivement congruents_, Fund. Math. **6** (1925), 244-277; (1967), _OEuvres_, Editions Scientifiques de Pologne, Warzaw. \

Here the 1967 got printed first, as if it were the \yr for a \jour, because \morebib remembered that a \jour appeared before.

So there is now \anotherbib, which clears out such information. If we use \anotherbib instead of \morebib we will get the desired result:

3. Stefan Banach, _Sur la decomposition des ensembles de points en parties respectivement congruents_, Fund. Math. **6** (1925), 244-277; _OEuvres_, Editions Scientifiques de Pologne, Warzaw, 1967. \

By the way, the AMS does not seem to have retained this "remembering" feature for \morebib. At any rate, the \(\mathcal{M}\mathcal{S}\)-TeX Version 2.0 User's Guidegives an example like

\bib \no 7

\by P. D. Lax and C. D. Levermore

\paper The small dispersion limit for the KdV equation. ~\rm I

\jour Comm. Pure Appl. Math. \vol 36 \yr1983

\pp 253--290

\morebib\paper \rm II

\jour Comm. Pure Appl. Math.

\vol 36 \yr 1983 \pp 571--594

\morebib\paper \rm III

\jour Comm. Pure Appl. Math.

\vol 36 \yr 1983 \pp 809--829

\endbib

to produce

\(\sqcap\)

7. P. D. Lax and C. D. Levermore, _The small dispersion limit for the KdV equation._ I, Comm. Pure Appl. Math. **36** (1983), 259-290; II, Comm. Pure Appl. Math. **36** (1983), 809-829.

which is an obvious example of overkill. The listing

\(\sqcap\)

7. P. D. Lax and C. D. Levermore, _The small dispersion limit for the KdV equation._ I, Comm. Pure Appl. Math. **36** (1983), 253-290; II, 571-594; III, 809-829.

would have been preferable by far.

There are now four new fields, as added by the AMS:

* \ed and \eds are for one editor, or several editors, respectively, of a book; the first adds "ed." after the editor's name, while the second adds "eds"; all the information is enclosed in parentheses.
* \lang, for the original language of a translation, prints its information, enclosed in parentheses, at the very end, after the final punctuation for the \bib entry. I have followed the AMS macros in this regard--

\lang basically becomes \finalinfo--although I don't think that's the optimal solution.

* \transl is for translation information, preceding the \jour or \book to which it pertains; thus, an entry with \transl may well have more than one \jour or \book--in essence, \transl functions something like \anotherbib.

As examples,

\bib\no9 \by S. Kripke \paper Semantical analysis of intuitionistic logic \rm I \inbook Formal Systems and Recursive Functions \eds J. Corssely and M. A. E. Dummett \publ North-Holland \yr1965 \pp92--130 \endbib

produces
* S. Kripke, _Semantical analysis of intuitionistic logic_ I, Formal Systems and Recursive Functions (J. Corssely and M. A. E. Dummett, eds.), North-Holland, 1965, pp. 92-130.

and

\bib\no6 \by O. A. Ladyzhenskaya \book Mathematical problems in the dynamics of a viscous incompressible fluid \bookinfo 2nd rev. aug. ed. \publ ''Nauka'' \publaddr Moscow \yr 1970 \lang Russian \transl English transl. of 1st ed. \book The mathematical theory of viscous incompressible flow \publ Gordon and Breach \publaddr New York \yr 1963; rev. 1969 \endbib* [6] O. A. Ladyzhenskaya, _Mathematical problems in the dynamics of a viscous incompressible fluid_, 2nd rev. aug. ed., "Nauka", Moscow, 1970 (Russian); English transl. of 1st ed., _The mathematical theory of viscous incompressible flow_, Gordon and Breach, New York, 1968; rev. 1969.

As you can see from these examples, the default style, in conformity with the AMS's changes, now prints both paper titles and book titles in italics, except for book titles produced by \inbook. However, there are new AMS constructions

\booxinquotes

\paperinquotes

which have also been added in IAMS-TEX. Typing

\booxinquotes

after \makebib will cause all the book entries to be placed in quotes (and in roman type), and similarly for \paperinquotes.

\paperinquotes and \booxinquotes can be used together, but I personally feel that one, and only one, of these commands should always be used, to distinguish between papers and books. The necessity for this is well illustrated by one of the AMS's examples in the User's Guide:

\[\Gamma^{\top}\]

4. V. I. Arnol\({}^{\prime}\)d, A. N. Varchenko, and S. M. Gusein-Zade, _Singularities of differentiable maps. I_, "Nauka", Moscow, 1982. (Russian)

\[\sqcup\]

Until I looked at the input,

\bib\no4\by V. I. Arnol\({}^{\prime}\)$d, A. N. Varchenko,

and S. M. Guse\u\i n-Zade

\bookSingularities of differentiable maps.^\rm I

\publ\''Nauka''\publaddr Moscow Vyr 1982

\lang Russian

\endbib

I didn't know this was a book! (Normally a book would have something like

'Volume 1' in its title.)The Kripke example on page 308 appears on page 263 of the second edition of _The Joy of TeX_, but with

\inbook in Formal Systems and Recursive Functions

to explicitly add 'in'before the book title. Unfortunately, that won't work very well if \bookinguotes has been specified! Instead, I have added

\ininbook

to add 'in'before all book titles specified by \inbook; if \bookinguotes has also been specified, the quotes will go only around the book title itself.

The AMS has extended the use of (the old) \nofrills within the bibliography: \nofrills after a field suppresses the punctuation that would normally occur. The above mentioned example was actually given as

\bib \no9 \by S. Kripke \paper\nofrills Semantical analysis of \nintuitionistic logic \rm I; \inbook in Formal Systems and Recursive Functions \eds J. Corssely and M. A. E. Dummett \publ North-Holland \yr1965 \pp92--130 \endbib

to produce

\nofr
9. S. Kripke, _Semantical analysis of intuitionistic logic_ I; in Formal Systems and Recursive Functions (J. Corssely and M. A. E. Dummett, eds.), North-Holland, 1965, pp. 92-130.

\nofrills has been replaced by \nopunct and \nospace in \_I_W_S-TeX (and its positioning has been changed), and this usage now extends to bibliography items also: In \_I_W_S-TeX the above example could be typed as

\ininbook


)

\morebib\paper \rm III \pp 809--829 \endbib thereby suppressing the punctuation on the field immediately preceding the \finalinfo (we might not be sure just which field this is).

As another example, note that in LWS-TEX the input

\bib \key C \by H. Cartan \paper Operations dans les construction acycliques \inbook Seminaire H. Cartan 1954--55 \bookinfo Expos\'e 6 \publ ENS \publaddr Paris \finalinfo Reprinted by W. A. Benjamin, New York (1967) \endbib produces

**[C]** H. Cartan, _Operations dans les construction acycliques_, Seminaire H. Cartan 1954-55, Expose 6, ENS, Paris. Reprinted by W. A. Benjamin, New York (1967).

with the information from the \finalinfo field following a period after all the other fields (see page 304). To print this in the AMS's manner,

**[C]** H. Cartan, _Operations dans les construction acycliques_, Seminaire H. Cartan 1954-55, Expose 6, ENS, Paris, reprinted by W. A. Benjamin, New York (1967).

we can type

\publ ENS \publaddr Paris \noprespace\noprespunct\finalinfo, reprinted by W. A. Benjamin, New York (1967). \endbib

Notice also that, once again in conformity with the AMS's changes, punctuation is supplied automatically after \finalinfo, unless it is preceded by \nopunct.

Finally, it turned out that one more such modifier was needed. When book or paper titles are printed in quotes, we sometimes want to suppress the quotation marks. For example,
2. L. Auslander, "On the Euler characteristic of compact locally affine spaces," Comment. Math. Helv. **35** (1961), 25-27; "II," Bull. Amer. Math. Soc. **67** (1961), 405-406.

l

looks much better if we suppress the quotations around the II,
2. L. Auslander, "On the Euler characteristic of compact locally affine spaces," Comment. Math. Helv. **35** (1961), 25-27; II, Bull. Amer. Math. Soc. **67** (1961), 405-406.

l

To obtain this, we would type

\morebib

\noquotes\paper\rm II

_29.3. Storing the fields._ One of the basic problems in the bibliography macros is that we want to be able to type things like

\by... \paper... \jour...

instead of

\by {...} \paper {...} \jour {...}

but we also don't want to force the various elements to be typed in a particular order, or force all of them to appear.

The solution to this problem is to have boxes, say \bybox@, \paperbox@, \jourbox@,..., in which to store the information from these various fields, and to make definitions like

\def\by{\unskip\egroup \setbox\bybox@=\hbox\bgroup}

\def\paper{\unskip\egroup \setbox\paperbox@=\hbox\bgroup}

The idea is that the \egroup matches the \bgroup from the previous field, and then we start storing the current field. (The \unskip before the \egroup simply removes any extraneous space at the end of the previous field; it is convenient to get rid of this space at the very outset, instead of worrying about it later.) The definition of \bib will have to start with an extra \bgroup, which will be closed by the \egroup of the first field that follows, while \endbib will supply a final \egroup, and then take the material in all these boxes, and suitably arrange them.

This whole idea works because \hbox can be ended by \egroup, rather than an explicit . However, several details intrude:

(1) If the user adds one of the line breaking commands, \nolinebreak, \allowlinebreak, \linebreak, or \newline at the end of a field, we want the corresponding \penalty to be inserted _after_ the punctuation that will follow the field when it is printed, not before.

Recall (section 3.5) that the \LWS-TEX definitions of \nolinebreak, \allowlinebreak, and \linebreak have an extra element \lkerns@ at the end, while \newlines has \nkerns@. Originally these are both \relax, but now we will change them, so that they involve very small kerns like

\kern-1sp \kernisp

The presence of such \kernis, presumably not ever explicitly inserted by the user, will allow us to recognize that such commands were typed, and to deal with them suitably (details are presented in section 10).

(2) Some people like to prepare a "template" with all possible fields,

\bib
\no
\key

\paper

and then fill in only the necessary fields. So we have to deal with the possibility that certain fields are empty.

(3) Finally, there is the phenomenon reported by Michael Downes in TUGBOAT, Volume 11, No. 4. Normally when \TEX is setting text it inserts a discretionary break after hyphens, en- and em-dashes, and explicitly typed


The space factor code of the period is changed to 1000 because almost all periods in a bibliography will come from abbreviations (except for the periods at the ends of each entry, and those occur at the ends of paragraphs). We add \everypar={}, just in case \everypar was non-empty before, since each entry begins as a nonindented paragraph, and we might as well set \parindent to Opt, though that shouldn't matter.

Once \makebib has appeared, we might be using not only \nopunct and \nospace, but also \noprepunct and \noprespace and \nopatores before various elements of a \bib...\endbib entry. Since all of these can precede almost any construction, we want to save ourselves all the agony of section 20.1, and simply have each of these set a flag. \nopunct and \nospace, which already have definitions, will thus have to be changed by \makebib, and, to be on the safe side, we will reset the flags to be false,

\def\makebib{bigbreak \centarrelline{}\msc Bibliography} \nopreak\nopreak



#### 29.5 \bibinfo@

The routine \setbibinfo@#1, used when #1 is \paperbox@,..., suitably expands \bibinfo@ if necessary, based on the current values of the flags \ifnopunct@,..., \ifnoquotes@:

\def\setbibinfo@#1{\def\next@{\ifnopunct@1\else0\fi \ifnospace@1\else0\fi\ifnopropunct@1\else0\fi \ifnoprespace@1\else0\fi\ifnquotes@1\else0\fi\% \def\nextti@\nextti@\else \xdef\bibinfo@{\bibinfo@\the#1,\next@}% \fi}

Here we first set \next@ to the proper \x1...x5. Then, if this sequence is 00000 (because none of \nopunct,..., \noquotes appeared) we do nothing; otherwise, we add

\the#1,x1x2x3x4x5

to \bibinfo@. An \xdef was needed to define \bibinfo@ globally because we will be using \setbibino@ within a group, to pass information on beyond that group (section 12).

There is a corresponding \getbibinfo@#1, which will \let\next@=x1,..., \let\nextv@=x5 when '\the#1,' appears in \bibinfo@, or simply \let them =0 otherwise:

\def\getbibinfo@#1{\% \ifx\bibinfo@\empty \let\next@=0\let\nextti@=0\let\nexttii@=0% \let\nextti@=0\let\nextti@=0%


which we will set true after printing each \paper or \book title that has begun with ''. The next field will then supply the closing '' at the right time, and reset the flag to false, using the routine

\def\closequotes@{\ifopenquotes@''\openquotes@false\fi}

In addition, we need special flags to deal with the possibilities of \morebib, \anotherbib, and \transl. The definitions of these constructions aren't given until section 14, but some discussion is necessary now. These three constructions act almost like an \endbib \bib pair, first printing the information already collected (but without ending the paragraph), and then collecting new information. For efficiency, these constructions and \endbib all call upon a common construction, \endbib@, which does all the work of printing the accumulated information, except that certain flags will have to be set differently for the various constructions.

First we have the flags

\newif\ifbeginbib@

\newif\ifendbib@

The flag \ifbeginbib@ will, for example, determine whether or not we should print \no and \key information; it will be true when we are setting the first part of a \bib.\endbib entry, but false if we are printing a \morebib part. The flag \ifendbib@ will, for example, determine whether we should print the final period at the end of the entry; it will be false if we are printing the first part of an entry that has a \morebib part to follow, though it will be true when we then set the \morebib part.

We also need the flags

\newif\ifprevjour@

\newif\ifprevbook@

to pass information to \morebib and \anotherbib about a \jour or \book in the main part.

29.7. \bib. For defining \bib we first introduce a new dimension

\newdimen\bibindent@with the default value

\bibindent@=20pt in terms of which the hanging indentation for \bib items will be specified. This makes it easier to add commands to change this indentation. (The default style doesn't have any such commands, but other styles do.) Then we define

\def\bib{\global\let\bibinfo@=\empty \global\let\translinfo@=\relax \beginbib@true \begingroup \noindent@\hangindent\bibindent@\hangafter1 \bib@} The \global\let\bibinfo@=\empty clears out \bibinfo@ from the previous \bib.\end{verb.} \translinfo@, which will play a role later, also has to be cleared out. Then we set \ifbeginbib@ to be true, begin a group, start a \noindent@\ed paragraph with hanging indentation \bibindent@ after the first line, and call \bib@. \bib@ has to start by setting \nobox@, \keybox@,..., to void boxes. We introduce the abbreviation

\def\v@id#1{\setbox#1=\box\voidb@x} and then

\def\bib@{\v@id\nobox@ \v@id\keybox@ \v@id\bybox@ \v@id\paperbox@ \v@id\paperinfobox@ \v@id\v@id\issuebox@ \v@id\yrbox@ \v@id\gbox@ \v@id\ppbox@ \v@id\gbox@ \v@id\gbox@ \v@id\gbox@ \v@id\book@ \v@id\book@ \v@id\book@ \v@id\book@ \v@id\publaddrbox@ \v@id\edsbox@ \v@id\langbox@ \v@id\translbox@ \v@id\finalinfobox@ \bgroup} As explained in section 3, the \bgroup will immediately be closed by an \egroup at the beginning of the \no or \key or \... that occurs next.


But if we have an empty field (page 314), in which case our \vbox will have width Opt,1 we want to reset our box to \box\voidb@x. We can do this with

\unskip\setbibinfo@#1\egroup

\def\aftergroup@{\ifdim\wd#1=Opt \setbox\voidb@x\if}

\setbox#1=\vbox\bgroup \aftergroup\aftergroup@]

Here the '\aftergroup@' is performed immediately after the \egroup from the next field (or from \endbib) that eventually matches the \bgroup.

In addition, in a few cases we will need to add something extra right after the first \egroup (namely, settings for the flags \ifprevjour and \ifprevbook). So for this general case we define

\def\Setnonemptybox@#1#2{\unskip}setbibinfo@#1\egroup#2% \def\aftergroup@{\ifdim\wd#1=Opt \setbox\i=\box\voidb@x\if\% \setbox#1=\vbox\bgroup \aftergroup\aftergroup@ \hsize=\maxdimen \leftskip=Opt \rightskip=Opt \rightskip=Opt \rightskip=10000 \hfluzz=\maxdimen \noindent}

and then for the more common case we define

\def\setnonemptybox@#1{\Setnonemptybox@#1\relax}

Notice that we used \noindent@ in the definition of \bib, but \noindent in the definition of \Setnonemptybox@. That is because there is a difference between the situation

\bib \agelabel{...}\no.\.\.\endbib

where the invisible \pagelabel occurs before any field, and something like

\bib \paper \pagelabel{...}.\.\endbib

#### 29.9. \no, \key,...

where the \pagelabel occurs within a field.

In case (**A**), the \bib contributes a \bgroup (via the \bib@), and the \no supplies the ending \egroup. Within this group, the \pagelabel{...} has already deleted the final space, but even if it didn't, the \unskip before the \egroup contributed by \no would get rid of it. Consequently, nothing except a \write is contributed by this group. But if we tried to be too careful, and replaced the \bgroup in \bib@ with

\bgroup\futurelet\next\pretendspace@

then, since the invisible \pagelabel follows, the results would be wrong:

1. First \pretendspace would contribute \hskip-ipt\hskipipt.
2. Then the \prevanish@ in \pagelabel would set \saveskip@ to \ipt and remove the \hskipipt.
3. Then the \postvanishe in \pagelabel would add back the \ipt and then delete the next space, if any.
4. Consequently, the \unskip\egroup in \no would remove the final \ipt, leaving an extra \hskip-ipt at the beginning.

In case (**B**), however, the \noindent (which eventually calls the combination \futurelet\next\pretendspace@) makes everything work out correctly if an invisible element occurs first (followed by something else). Of course, this won't work if a \pagelabel appears within an _empty_ field, but that doesn't seem worth worrying about

#### 29.9. \no, \key,...

Now we are ready to give definitions of \no, \key,..., many of which are quite similar. First we have

\def\no{\setnonemptybox@\nobox@}

\def\key{\setnonemptybox@\keybox@\bf}

\def\by{\setnonemptybox@\bybox@}

Notice that \key specifies \bf for the font.

For \bysame we simply specify the desired rule, rather than waiting for user input:

\def\bysame{\setnonemptybox@\bybox@}

\leaders\hrule\hskip3em\null}

The \null is essential, to prevent the \unskip from the next field from deleting this \leaders glue (compare the \(\LMS\)-TEXT Manual, page 225).

The definition of \paper is a little more complicated, because we have to begin with'' when \ifpaperinquotes@ is true, except not when \noquotes precedes \paper. To find out this latter information, we use

\getbibinfo@\paperbox@

which will \let\nextv@=1 if \noquotes preceded \paper, but will \let\nextv@=0 otherwise:

\def\paper{\setnonemptybox@\paperbox@ \ifpaperinquotes@ \getbibinfo@\paperbox@ \if\nextv@1\else''\fi \else \it \fi}

Notice that we've specified \it when \ifpaperinquotes@ is false (even if \noquotes preceded \paper).

The next definition reverts to the simple case,

\def\paperinfo{\setnonemptybox@\paperinfobox@}

but the definition of \jour uses \Setnonemptybox@, since we need to set \ifprevjour@ true (for possible use by \morebib later on):

\def\jour{\Setnonemptybox@\jourbox@\prevjour@true}

The next definitions are simple (\vol merely adds \bf for the font),

\def\vol{\setnonemptybox@\volbox@\bf}

\def\issue{\setnonemptybox@\issuebox@}

\def\yr{\setnonemptybox@\yrbox@}

But \toappear is handled quite specially:
#### 29.9. \no, \key,...

\def\toappear{\noprepunct}finalinfo(to appear)}

Then come another two simple definitions:

\def\pg{\setnonemptybox@\pgbox@} \def\pp{\setnonemptybox@\ppbox@}

The definition of \book has both the complexities of \paper (involving quotation marks) and \jour (setting a flag),

\def\book{\setnonemptybox@\bookbox@\prevbook@true \ifbookinquotes@\getbibinfo@\bookor@ \if\nextv@1\else^'\fi \else \it \fi}

and the definition of \inbook has yet another clause, because of the flag \ifinbook@:

\def\inbook\set{\setnonemptybox@\inbookbox@\prevbook@true \ifininbook@ in \ifbookinquotes@\getbibinfo@\inbookor@ \if\nextv@1\else^'\fi \fi}

(In this case we don't change fonts even if there are no quotation marks.)

Then comes another bunch of simple definitions,

\def\bookinfo{\setnonemptybox@\bookinfobox@} \def\publ1{\setnonemptybox@\publbox@} \def\publaddr{\setnonemptybox@\publaddrbox@} \def\ed\setnonemptybox@\edbox@} \def\reds{\setnonemptybox@\edbsbox@} \def\lang{\setnonemptybox@\langbox@} \def\finalinfo{\setnonemptybox@\finalinfobox@}

This leaves only \transl, \morebib, and \anotherbib, all of which are treated somewhat similarly--it will be easiest to understand their definitions later (section 14) after examining how \endbib puts all the information together.

#### Manipulating the \vbox'es

At the end of a \bib...\endbib entry, we will have stored all our information in various \vbox'es, and we now have to get information out of each such box, #1, with a construction \getbox@#1. Most of the time we could simply use

\def\getbox@#1{\setbox0=\vbox{\unvbox#1 \setbox0=\lastbox \global\setbox1=\hbox{\unhbox0\unskip\unrespanalty} \unhbox1 } Here the inner \box00 (\lastbox) is the final line of this one line paragraph (having \hsize=\maxdimen), at the end of which we have (see _The TeXbook_, page 100),

\penalty 10000 \parfillskip glue) \rightskip glue)

which we delete with the \unskip\unskip\unpenalty.

But since line breaking commands may have occurred (either in the middle of the field, or at the end), our \vbox may have several \hbox'es, separated by glue and possibly penalties (\clubpenalty, etc.), and we may have to use a \loop to discover all these boxes. We add \vskip-10000 pt at the beginning as a marker, the assumption that such a \vskip won't be inserted otherwise.

\def\getbox@#1{\setbox0=\vbox{\vskip-10000ptpt \unvbox#1% \setbox0=\lastbox \global\setbox1=\hbox{\unhbox0\unskip\unrespanalty} \ifdim\lastskip=-10000pt \else \loop \ifdim\lastskip=-10000 pt

#### Line breaking commands

\else \unskip\unpenalty\setbox0=\lastbox \global\setbox1=\hbox{\unhbox0 \unhbox1}% \repeat \fij% \unhbbox1 \

Notice that we use the test \ifdim\lastskip=-10000pt before entering the \loop, even though it is also used within the \loop; this allows us to bypass the \loop completely if it is unnecessary.

\def\setboxzl@{\setbox\ze\lastbox}

and then we use \setboxzl@ throughout. However, for the sake of readability, we will always simply print \setbox0=\lastbox'.

#### Line breaking commands

Next we have to deal with the problem of a line breaking command appearing at the end of one our fields, since the appropriate penalties must be inserted _after_ the punctuation that is normally added after the field. These line breaking commands produce

\null\kern-\nsp\kernnsp\kernnsp\kernnsp\kern

at the end of the horizontal list produced by \getbox@. More specifically,

(1) \nolinebreak produces

\penalty10000 \(\langle\)possible glue\null\kern-\nsp\kernnisp The (possible glue) comes about because \nolinebreak remembers the glue before it, and inserts it after the \penalty10000, so that this glue does _not_ disappear. Of course, it is unlikely that any one would want to have such a non-disappearing space at the end of a field, but we might as well allow for the possibility.


the punctuation, because the previous field began with ''':

\def\adjustpunct@@1{\count@=\lastkern \ifnum\count@=0 #1\closequotes@\else \ifnum\count@>2 #1\closequotes@\else \ifnum\count@<-2 #1\closequotes@\else

In the remaining, more interesting case, we use

\unkern\unkern\setbox0=\lastbox to get rid of the

\null\kern-\nsp\kern\nsp Then we save the previous glue in \skip@ and remove it:

\skip@=\lastskip \unskip Now we've reached the point where the original \penalty is revealed; we store it in \count@@ and remove it:

\count@=\lastpenalty \unpenalty

Moreover, in the case of \newline (\count@ is 2), we also get rid of the \null\hfil:

\ifnum\count@=2 \unskip \setbox0=\lastbox \fi Now we can add the punctuation #1, followed by \closequotes@; if \skip@ is non-zero, because of the \(\langle\)possible glue\(\rangle\) in the case of \nolinebreak or \allowlinebreak, we add this first:

\ifdim\skip@=Opt \else \hskip\skip@ \fi
#1\closequotes@

In the case of |newline we then add back a |null\hfill, and in all cases we add back the original |penalty, now stored in |count@@:

\def|adjustpunct@#1{count@=|lastkern |ifnum\count@=0 #1\closequotes@|else |ifnum\count@>2 #1\closequotes@|else |ifnum\count@<-2 #1\closequotes@|else |unkern\unkern\setbox0=|lastbox |skip@=|lastskip |\count@=|lastpenalty\unpenalty |ifnum\count@=2 |unskip\setbox0=|lastbox\fi |ifdim\skip@=Opt |else |hskip\skip@ |fi |\closequotes@ |ifnum\count@=2 |null\hfill\fi |penalty\count@0 |ifi\fi|\fi|\

#### 29.12. Adding punctuation before a field

Now our definition of \prepunct@ begins

 \def\prepunct@#1#2{\getbibinfo@#2% % first part  \infopunct@  \else  \if\nertiii@0\adjustpunct@#1\fi  \fi  \closequotes@  \ifinospace@  \else  \if\nertiw@0\space\else\fi  \ficsecond part  \nopunct@false \nospace@false  \if\nerxt@1\nopunct@true\fi  \if\nertii@1\nospace@true\fic

Before examining the first part of this code, consider the second part: this sets \ifnopunct@ to be true if \nopunct@ preceded the field and \ifnospace@ to be true if \nospace@ preceded the field.

The first part of the code should now make more sense, when we remember that those same assignments will have been made by the field which precedes this field: The test \ifnopunct@ is true if the previous field is not supposed to have punctuation at the end, and \nextiii@ will be 1 (rather than 0) if the current field was followed by \noprepunct. In either of these cases, we don't supply any punctuation; otherwise, we use \adjustpunct@#1 to supply the punctuation #1. Even when no punctuation is supplied, we need \closequotes@, in case the previous field set \ifopenquotes@ true (if \adjustpunct@ _was_ used, the \closequotes within it has already set \ifopenquotes@ to be false [page 321], so we won't be adding closing quotes twice). Space following the punctuation is handled similarly, using the flags \ifnospace@ and the value of \nextiw@.

\def\prepunct@#1#2{\getbibinfo@#2% \ifnopunct@}else  {if\nextiii@0\adjustpunct@#1\fi }fi \closequotes@ \infospace@ \else  {if\nextiv@0\space\else\fi \fi \nopunct@false\nospace@false \if\next@1\nopunct@true\fi \if\nextii@1\nospace@true\fi }prepunct@#1#2 is usually followed immediately by \getbox@#2, so we introduce an abbreviation for that combination:

\def\punbox@#1{\prepunct@{#1}#2\getbox@#2}

###### Abstract

The _subjective_

#### 29.13. \endbib@

Thus, when \ifbeginbib@ is true (which will usually be the case, unless we are printing remaining information from \morebib, \anotherbib, or \transl), if \box\nobox@ isn't void we start our \noindent@'ed paragraph with

\hbox to\bibindent@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{ \hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{ \hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{ \hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@ {\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@ {\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@ {\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss}@{\hss} }\]

a box of width \bibindent@, which is also the amount of hanging indentation we will be using, containing the information in \box\nobox@. This information (from \getbox@\nobox@) is followed by a period and a space, and preceded by \hss}@hss (rather than \hfil, just in case the number is too long). Because the \ifvoid test always tells us whether or not a particular field has been set, we don't need any flags for this. Note also that \getbox@#1 uses \unvbox@1 (page 328), so that once we print the information for a field, the box containing that information has become void again.

If \box\nobox@ is void, we instead use the information in \box\keybox@, if that isn't void. In this case we surround the information with brackets, and have it start at the left margin, with the additional space at the right.

In the other case, where \ifbeginbib@ is false, we use

\else

\nopunct@true

\ifvoid\bybox@\else\getbox@\bybox@\fi

\fi

We first set \ifinopunct@ to be true because we don't want the first field of our \morebib or \anotherbib or \transl portion to add any punctuation to the end of the previous field, which will already have been supplied with a closing ; (see page 338ff.). Normally \box\bybox@ will be void for this subsequent portion, but \by could conceivably be used after \anotherbib, so we add that in.

After this preamble, we start to add the other various elements in the required order. Although \transl isn't defined until section 14, it does end up storing its information in \box\translbox@, just like other fields; if this box is nonvoid, then we must be setting this second portion of the entry, and this information should come first, so we now add

\ifvoid\translbox@\else\punbox@,\translbox@\fito print the information.

Next comes

\ifvoid\paperbox@ \else \ppunbox@,\paperbox@ \ifpaperinquotes@ \if\nextv@1\else\openquotes@true\fi \fi

Thus, if \box\paperbox@ isn't void we add the information in it, with appropriate punctuation and spacing before it. The \ppunbox@ routine has already used \getbibinfo@\paperbox@ to get information from \bibinfo@. When the flag \ifpaperinquotes@ is true (so that we are enclosing paper titles in quotation marks), then the paper title normally has begun with '' and we want to set \ifopenquotes@ to be true, so that the next routine will know the add the ''; however, we don't do this when the \bibinfo@ has caused \nextv@ to be 1, since this indicates that a \noquotes preceded the \paper, in which case the opening '' will not have been included in the paper title.

After the paper title, we add any \paperinfo:

\ifvoid\paperinfobox@\else\ppunbox@,\paperinfobox@\fi

Then comes the information in \jourbox@, \volbox@, \issuebox@,... Information from \volbox@,..., should be added only if there was

(a) information in \jourbox@;

(b) or in the case of \morebib, information in a previous \jourbox.

In the latter case, \ifprevjour@ will have been set true, so we use

\test@false \ifvoid\jourbox@\else\test@true\ppunbox@,\jourbox@\fi \ifprevjour@\test@true\fi \iftest@ \(\langle\)material for \vol, \issue, \yr, \pp, \pg\} \fi


)

\pgbox@, since the latter three can be with \paper as well as with \book. There's nothing here that we haven't already considered:

\ifvoid\edbox@\else\prepunct@\relax\edbox@ (\getbox@\edbox@, ed.)\fi \ifvoid\edbox@\else\prepunct@\relax\edbox@ (\getbox@\edsbox@, eds.)\fi \ifvoid\bookingfobox@\else\punbox@,\bookinfobox@\fi \ifvoid\punblock@\else\punbox@,\punblock@\fi \ifvoid\punblock@\else\punbox@,\punblock@\fi \ifvoid\pprox@\else\punbox@,\pwrbox@\fi \ifvoid\pprox@\else\pprepunct@,\pprox@ \pp.~\getbox@\pprox@\fi \ifvoid\pgox@\else\pprepunct@,\pgbox@ \p.~\getbox@\pgbox@\fi

Then come the finishing touches. At this point the flag \ifendbib@ will be important. It will have been set true if we are finishing off the whole \bib...\endbib entry, but it will be false if we are simply printing the first portion of an entry, with a further portion from \morebib or \anotherbib or \transl to follow. The possibility of a \finalinfo field will also play a role. We begin with the case where there was no \finalinfo field:

\ifvoid\finalinfobox@ \ifendbib@ \ifnopunct@\else.\closequotes@\fi \else \ifvoid\langbox@\else\space(\getbox@\langbox@)\fi \/\semicolon@\closequotes@

In other words, if we are truly at the end, we print a period, unless a \nopunct preceded the previous field, which will be indicated by \ifinopunct@ being true; the \closequotes@ is added just in case the previous field happened to be a \jour or \book in quotes.

Otherwise (\morebib or \anotherbib or \transl information follows), we add any \lang field information in parentheses, and then a semicolon (with



)

29.14.\endbib,\morebib,\anotherbib,and\transl. The construction \endbib begins with

\unskip\group

just like all other fields, and then it calls \endbib@ with the flag \ifendbib@ set true (\ifbeginbib@ has already been set true by \bib), finishing up with a \par and then an \endgroup to match the \begingroup supplied by the original \bib:

\def\endbib{\unskip\group\endbib{\unskip\group\endbib{\par\endgroup}

\

\morebib uses an \endbib@ to set the material so far, just like \endbib, except that we set \ifendbib@ to be false:

\def\morebib{\unskipegroup \endbib@false\endbib@

And then we want to call \bib@ again, to deal with the following material, except that we also need to reset \bibinfo@ to be empty and \ifbeginbib@ to be false:

\def\morebib{\unskipegroup \endbib@false\endbib@

\global\let\bibinfo@=\empty \beginbib@false \bib@}

And \anotherbib is almost the same, except that we also set \ifprevjour@ and \ifprevbook@ to be false before the \bib@, so that no previous material will be "remembered":

\def\anotherbib{\unskipegroup \endbib@false\endbib@

\global\let\bibinfo@=\empty \beginbib@false\prevjour@false\prevbook@false\bib@}

Finally, \transl is something like a cross between \morebib and a more standard field. We want to begin with something like

\unskip\egroup \endbib@false\endbib@

in order to print the previous information.

Then we want to call \bib@ again, after first setting \ifbeginbib@ to be false, as with \morebib. Now we start with

\beginbib@false \bib@

\egroup \def\aftergroup@{...} \egroup\setobox\translbox@=\vbox\bgroup \aftergroup@ \hsize=\maxdimen \noindent@}

so that we will be putting the following field into \box\translbox@ in essentially the same way that \paper, \jour, etc., put their fields into boxes, using \setnonemptybox@. The one thing we are missing from \setnonemptybox@ is the procedure for storing information about any \nopunct,..., \nopotest that precedes the \transl. This information should be stored in \bibinfo@, except that any other information in \bibinfo@ should be emptied out, ready to be refilled, if necessary, with current information for the fields following \transl.

To do this, we first store the information in \translinfo@, before the \egroup,

\def\transl\unskip \xdef\translinfo@{\the\translbox@,\ifinopunct@1\else0\fi \ifinospace@1\else0\fi\ifinopropunct@1\else0\fi \ifinopresppace@1\else0\fi}

(we simply use 0 as the last value, without bothering about the value of \ifinoquotes@, since the value is never used in setting the translation information anyway), and then we set \bibinfo@ to be \translinfo@ before calling \bib@:

\def\transl\unskip \xdef\translinfo@{\the\translbox@,\ifinopunct@1\else0\fi \ifinospace@1\else0\fi\ifinopropunct@1\else0\fi \ifinoprespace@1\else0\fi0}

)

\egroup \endbib@false \endbib@ \global\let\bibinfo@=\translinfo@ \beginbib@false \bib@ \egroup \def\aftergroup@{\ifdim\wd\translbox@=0 \setbox\translbox@=\box\voidb@x\fi}% \setbox\translbox@=\vbox\bgroup \aftergroup@ \hsize=\maxdimen\lleftskip=Opt \hbadness=10000 \hfuzzy=\maxdimen \noindent@}

And that jolly well finishes off the bibliography macros!

**Chapter 30. Interfacing with BiBTeX**

It turns out that we can easily prepare an.aux file on which BiBTeX can operate, so that a LaTeX file can use the resulting.bbl file. The control sequence

UseBibTeX

will set things up for this. When UseBibTex is specified (preferably close to the beginning of the document), a

\bibliographystyle{...}

line should also appear somewhere.

Furthermore, when UseBibTeX is specified, \cite will essentially function just as in LaTeX, rather than as in the previous chapter, except that we will continue to use (...) for an optional argument rather than [...]. As in LaTeX, a citation of the form

\cite{\key}1,\key\2,...}

had better not have spaces after the commas, because this multiple argument is going to be passed directly to the.aux file, on which BiBTeX operates, and BiBTeX will insist that no space appears. (Of course, spaces will be made to appear after the commas in the output.)

Finally, when \UseBibTeX is specified, instead of a

\makebib

\endmakebib

region, a line

\bibliography{\source list}1,\source list}2,...}

should appear, at the appropriate place. In this case, no specific references should be given, either in LaTeX or in LaTeX format. The references will be supplied by the.bbl file that will eventually be made, and which the \bibliography command will read in, and any additions or changes would be made directly in that file.

_30.1_. USeBibTeX. We first declare new streams for writing the.aux file, and reading the.bbl file:

\newwrite\auxwrite@ \newread\bbl@

Now \UseBibTeX must first open up an.aux file,

\immediate\openout\auxwrite@=\jobname.aux

and then redefine \cite. We will simply

\let\cite=\BTcite@ \ where \BTcite@ is defined separately afterwards. That allows a style file to redefine aspects of \BTcite@ that deal with the material actually printed.

\UseBibTeX will also define \nocite,

\def\nocite#1{\immediate\write\auxwrite@{\string\citation\#1}}

and \bibliographystyle,

\def\bibliographystyle#1{\immediate\write\auxwrite@ \{\string\bibstyle{\#1}}}

Finally, it must define \bibliography, and this is somewhat more complex. To begin with, we want to

\def\bibliography@W\{Bibliography}

#### 30.1. \UseBibTeX

so that \newword\bibliography can be used. Then we start with

\def\bibliography#1{\immediate\write\auxwrite@ {\string\bibdata{#1}}} Then we have to see whether a.bbl file exists. If it doesn't, we simply give a message to that effect, but if the.bbl file does exists, we read in a special macro file bibtex.tex before we \input the.bbl file, since the bibtex.tex macros will make this a file that we can process,

\def\bibliography#1{\immediate\write\auxwrite@ {\string\bibdata{#1}}% \immediate\openin\bbl@=\jobname.bbl \ifeof\bbl@ \W@(No.bbl file)% \else \immediate\closein\bbl@ \begingroup \inputbibtex \input\jobname.bbl \endgroup \fi}

Putting this all together, we have

\def\UseBibTeX{\immediate\openout\auxwrite@=\jobname.aux \let\cite=\BTcite@ \def\nocite##1{\immediate\write\auxwrite@ {\nocexpand\citation{#1}}}% \def\bibliographystyle#1{\immediate\write\auxwrite@ {\string\bibstyle{#1}}}% \def\bibliography@\W{Bibliography}% \def\bibliography#1{\% \immediate\write\auxwrite@{\string\bibdata{#1}}}% \immediate\openin\bbl@=\jobname.bbl \ifeof\bbl@ \We{No.bbl file}%



(\rm has been explicitly specified for the brackets and comma definitions), but a change to the style file should be used if all citations are supposed to be in \bf. It is even possible to type something like

By {\bf\cite(\it page^123){(key)}} we have...

to print something like

By [8, _page 123_] we have...

(there are no restrictions on the material occurring in the optional argument). In the definition of \BTcite@ we typed {\##1\/} in the definition of \nextii@ to allow for the fact that font change instructions might occur in this argument.

If we have a multi-key \cite,

\cite{(key)1,(key)2,...}

then \(\key)1 will give a warning message like

Warning: No \label found for (key)1.

1.36... \cite{(key)1}

while \(\key)2 will give a warning message like

Warning: No \label found for (key)2.

1.35... \cite{(key)2}

Although it would be nicer if we got a single message involving

1.35... \cite{(key)1,(key)2,...}

this doesn't really seem worth worrying about.

The.bbl file will have \bibitem's, but the definition of \bibitem is found only in the file \bibtex.tex. However, we will state

\let\newblock=\relax

even though \newblock occurs only in the.bbl file that is read in after the \bibtex.tex file; the reason for this is that different styles might want to change the definition of "newblock". (Many LaTeX style files define "newblock" to be "hskip.11em plus.33em minus.07em", but the default "LMS-TEX style leaves no extra space between various parts of a bibliographical entry.) Similarly, we define a default routine

\def\beginthebibliography@#1{\rm \setbox0\hbar{#1}\bibindent@=\wd0 \bigbreak \centerline{\smc\bibliography@W}% \nobreak\medskip \sfcode^\.=1000\everpar{\}\parindent=Opt} which will be used by the

\begin{tabular}{}

 that occurs in the.bbl file; style files can redefine this, to produce different sorts of formatting for the information in the.bbl file.

_30.2. The \bibtex.tex file. The file \bibtex.tex is read in right before the.bbl file; its purpose is to make sense out of the various LaTeX macros that are going to appear._

The file begins with

\%\input cd.tox \%\input islands.tox \%\input bib.tox \%\input alignat.tox \%\input lists.tox \%\input cardord.tox \%\input anynum.tox \%\input dblack.tox \%\input literal.tox (As in section 27.2, we are using double horizontal lines for code that is in the subsidiary file \bibtex.tex, rather than in \itemaster.tex itself). Althoughthese lines are commented out, it might be wise to uncomment them, if it turns out that adding the extra material from bibtex.tex unduly strains the implementation of TEX that is being used.

This is followed by

\catcode^\@=11 \let\alloc@=\alloc@

since we will be using a \newcount and \newdimen (compare page 38).

Next we have to deal with the fact that the.bbl file usually begins with things like

\newcommand{\noopsort}[1]{\newcommand{\printffirst}[2]{\#1} and perhaps there will be \newcommand's for control sequences without arguments also. So we have to interpret \newcommand correctly.

For a situation like

\newcommand{\foo}{bar} where a control sequence \foo without arguments is being defined, we can simply let \newcommand#1 mean \define#1. But the general case is more complicated.

First we define \args@so that \args@1 makes \toks@ be the token list ##1, and \args@2 makes \toks@ be the token list ##1#2, etc. (we want the double ##'s because \toks@ will then be used within an \edof). The definition looks pretty strange,

\def\args@#1{count@=1 \toks@={}% \loop \edof\next@{\toks@={\the\toks@#########\number\count@}}% \next@ \ifnum\count@<#1 \advance\count@ by 1 \repeat} because we have the _ocublet_ #########, even though we want to end up with only a pair ##. The reason we need this octuplet is that the \loop...\repeat



30.2. The bibtex.tex file

A \bibitem, which is written by BibTEX, might have an "optional argument" [...], so we will need maneuvers similar to that for \newcommand. The case

\bibitem[...]{(key)}

will call

\bibitem@{...}{(key)}

while the case

\bibitem{(key)}

without the optional argument will call

\bibitem@{\number\bibitemcount@}{(key)}

where \bibitem@@#1#2 takes care of making the \(key) #2 act like a \label with the value #1, and then printing #1 at the beginning of the bibliographical data that follows:

\def\bibitem{% \def\nextii@[#1#1]##2{\bibitem@{##1}{\#2}}% \def\nextii@##1{\global\advance\bibitemcount@ by 1 \bibitem@{\number\bibitemcount@}{\#1}}% \def\nexti@{\if\next[\expandafter\nextii@\else \expandafter\nextii@\if\% \futurelet\nexti@\next\nexti@\% \futurelet\nexti@\%

In order for \bibitem@#1#2 to make #2 act like a \label with the value #1, we simply have to

{\def\thelabel@{#1} \let\thelabel@@=\empty \let\thelabel@@@@=\empty \label@@@@@=\empty \label{#2}}


30.2. The bibtex.tex file

At the very end of the file we will encounter

\end{thebibliography} Again, hopefully this is the only \end that will occur in the.bbl file, and we define

\def\end#1{% \def\next@{#1}\def\nextii@{thebibliography}% \ifx\next@\nextii@ \else \Err@{I can deal with \string}end{#1}% \fi} (The fact that we are redefining \end isn't important, since the definitions of bibtex.tex, together with the.bbl file are all read in within a \begingroup...\endgroup region (page 348.)

Finally, we reassign \alloc@ its original definition from plain TeX, and make @ active:

\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}} \cactcode^\@=\active* [15]We _don't_ bother with counters like '\list@C1', or any thing else created with a new... construction, because it would create confusion if we had to restore them in the.tex files--each \newcount construction will use up another possibility for a counter, even if we happen to be using the same name as before. \newif works differently, so flags are set equal to \relax, and we also

\let\list@C=\relax

...

Intermingled with these redefinitions we also have

\let\keelisting=\undefined

\let\list=\undefined

\let\runinitem=\undefined

...

And at the very end we make @ active again,

\catcode'\@=\active

On the other hand, the file lists.tex essentially consists of all the definitions for \lists, except for things like

\expandafter\newcount\csnamelist@C1\endcsname

that aren't removed by lists.tox.

There's nothing mysterious about \purge and \unpurge--they simply read in a.tox or.tex file:

\def\unpurge#1{\input #1\relax} \def\purge#1{\input #1.tox\relax}

Each.toc file clears up the memory space used for certain control sequence definitions, by redefining these control sequences. Control sequences meant for the user (those without @ in their names) are set equal to \undefined, which \\\\\\\\text{L}\!\!\text{A}\!\!\text{S}\!\!\text{T}\!\!\text{E}\!\!\text{X}\) always keeps undefined, so that their use will give an error message. On the other hand, control sequences used internally by \(\text{L}\!\!\text{A}\!\!\text{S}\!\!\text{T}\!\!\text{E}\!\!\text{X}\) (those with @ in their names) are simply set equal to \relax. For example, the file

lists.tox

which eliminates everything for making lists, starts (again, as in section 27.2, we use double horizontal lines for code in subsidiary files)

\catcode'\@=11 \let\listformatbi@=\relax \let\listformatmi@=\relax \let\listformatti@=\relax \let\listformatte@=\relax \let\listformatte@=\relax \let\listformatte@=\relax \thereby removing from memory the initial definitions of section 18.1.

Then, for the definitions in section 18.2, we

\expandafter\let\csname list@P1\endcsname=\relax \expandafter\let\csname list@Q1\endcsname=\relax \358Part V

Islands

and the

Output Routine


### Chapter 32. Packaging figures, tables,..., with captions

The previous Parts have covered almost all the standard _HMS_-TEX constructions that involve |label's (as well as miscellaneous constructions that don't). But |caption's, in a1 |Figure, |Table, or the more general |island construction, have been postponed to this Part, because they interact so intimately with the |output routine.

#### Preliminaries

First we want to disable certain commands from plain TeX, since they would conflict with _HMS_-TEX's approach to these insertions:

|let|topinsert=|undefined |let|midinsert=|undefined |let|pageinsert=|undefined

Next, we deal with the rather simple matter of producing crop marks around an |hybw or |Hbyw. We first need a flag for telling whether |Figureproofing or |noFigureproofing is in force:

|newif|fifipproofing@

|def|Figureproofing{|fifproofing@true}

|def|noFigureproofing{|fifproofing@false}

The special |Hbyw construction is reduced to |hybw, but also sets a flag, to indicate that this |hybw will need further processing later on:

|newif|fifby@

|def|Hbyw#1{global|Hby@true\hyw}vsize{#1}

The |global is needed because the later processing will occur after the current group is completed.




#### 32.2. Starting an \island

(or when we use something created by \newisland with this \c{...}), and empty if we omit the \c{...}.

Similarly, a construction created with \newisland, say \map, will define \islandtype@ to be \map, analogous to \claimtype@, while an ordinary \island will define \islandtype@ to be \island.

Analogous to \claim@@@P, etc., we define

\def\island@@@P{\csname}exxx@\islandtype@ @P\endcsname}

\def\island@@@@Q{\csname}exxx@\islandtype@ @Q\endcsname}

\def\island@@@@S{\csname}exxx@\islandtype@ @S\endcsname}

\def\island@@@@N{\csname}exxx@\islandtype@ @N\endcsname}

\def\island@@@F{\csname}exxx@\islandtype@ GF\endcsname}

while for \island@@@C we

\def\island@@@C{\csname}island@C\islandclass@\endcsname}

We want to give an error message if an \island is not used within some sort of \...place, so we declare a flag

\newif\ifplace@

which such constructions can set true, and which each \island will eventually set false. Moreover, we want a flag

\newif\ifisland@

which each \island will set true, so that constructions like \Aplace{...} can give an error message if'...' is not some sort of \island.

If \island is used when \ifplace@ is false, we will give an error message. Otherwise, we will initialize \islandclass@ to be empty and \islandtype@ to be \island, and then use a \futurelet to see if a \c comes next:) def{island{% \ifplace@ \def{next@{let{islandclass@=}empty \def{islandtype@{island}% \futurelet{next@}}% \else \long\def{next@##!endisland{\Err@{\noexpand}islandmust be used after some type of \string}...place}}% \fi \next@} ```
Notice that when we give the error message, we also swallow the whole \island...\endisland construction, to eliminate confusion. The \long is required because the \caption before the \endisland is allowed to contain a blank line. For the \noexpand, see section 3.4.

If \island is followed by \c we will use \island@c. Otherwise we will need yet another \futurelet, to see if the next token is a \, since we want to give an error message if a suitable group {...} for the "caption prefix" doesn't come next:

\def{island@{\ifx\next\c\letnext@=\island@c\else \def{\futurelet{next@}island@@}\if\next@}

Here \island@emptyset will call \island@emptyset if a group {...} does follow, but give an error message otherwise:

\def{island@emptyset{% \ifcat\group\noexpand\next \let{next@=\island@emptyset \else \def{\next@{\Err@{\noexpand}islandmustbefollowedby a \{prefix}for \string}caption's}}% \fi \next@}
```

(See section 3.4 for the use of \noexpand in the error message.)
Finally, if we've made it this far without an error message, i.e., if we've been scanning

\island {...}

then we will save '...' in \captionprefix@, and start to store everything in a box:

\global\setupbox\islandbox@=\vbox\bgroup

Although the \global really isn't necessary here, some of our routines will require \global, so we will use it in all cases.

We therefore first want to declare a new box \islandbox@. Moreover, we also want a new counter \captioncount@, which is quite different from \island@C: it records the number of \caption's that occur within the current island (remember that an \island can have more than one \caption):

\newbox\islandbox@

\newcount\captioncount@

\def\island@@@@!{def\captionprefix@{#1}%

\captioncount@=0

\global\setupbox\islandbox@=\vbox\bgroup}

The \bgroup matching this \bgroup might be supplied by the \endisland; in most cases, however, it will be supplied by a \caption, which will then go on to store the \caption argument, and then combine this properly with \box\islandbox@.

Leaving these details aside for the moment, let us now consider \island@c, which we obtain when we have

\island \c{...}

As we might expect from our experience with \newclaim, a construction created by \newisland is going to lead us directly to \island\c{...}. Since such constructions must also be used only within a suitable \...place construction, this means that we _must repeat our_\ifplace@_test_.


is followed by yet another group {...} to specify a caption prefix; in fact, we will need \FNSS@, to skip over any space after the \c{...}:

\def\island@c\c#1{% \ifplace@ \def\next@{\def\islandclass@{#1}% \expandafter\if\csnameisland@C#1\endcsname\relax \expandafter\newcount@\csnameisland@C#1\endcsname \global\csnameisland@C#1\endcsname=0 \fi \FNSS@\island@c@\% \else \def\next@{\def\noexpand\next@##########1\expandafter \noexpand\csnameand\expandafter\exxx@ \islandtype@\endcsname \noexpand\Err@{\noexpand\noexpand\expandafter\noexpand \islandtype@ must be used in some type of \noexpand\string\noexpand\...place\}}}% \next@\next@\% \fi \next@} ```

Then \island@c@ works analogously to the way \island@@ worked before:

\def\island@c@{% \ifcat\bgroup\noexpand\next \let\next@=\island@c@@ \else \def\next@{\Err@{\noexpand\island\string\c \{\expandafter\string\islandclass@} must \be followed by a {prefix} for \string\caption's}}% \fi \next@} \def\island@c@@#1{\def\captionprefix@{\#1}% \captioncount@=0 \global\setbox\islandbox@=\vbox\bgroup}

32.3. Starting a \caption. As we are setting \box\islandbox@ we will probably encounter a \caption, which we have to consider next, before worrying about the \endisland.

First of all, we

\rightadd@\caption\to\nofrillslist@

since the default style adds a period at the end of the \caption automatically, and we want to allow \nopunct to override this.

This is a change from version 1: Even though captions are often whole sentences, where it might seem normal for the user to add the punctuation, it is preferable to require that this punctuation not appear in the input file, because it could create problems in the.tic file, where the caption might be followed by something like dot leaders.

Then we will need a box,

\newbox\captionbox@

to store \caption's, and since we allow more than one \caption in an \island, we will need another box,

\newbox\Captionbox@

to store the accumulated \caption's.

A \caption will first be encountered within an \island, where we have already begun

\global\setup\islandbox@=\vbox\bgroup

and it will normally first supply the matching \egroup that will finish \box\islandbox@, before scanning its argument. But we don't want to add an \egroup if our \caption is simply a subsequent \caption within the 

#### Starting a \caption

same \island. So we want something like

 \def\caption{%  \ifnum\captioncount@=0  \let\next@=\egroup  \else  \let\next@=\relax  \fi  \next@  \advance\captioncount@ by 1

But there is an extra detail to worry about: If the \caption was preceded by Unopunct, then we have Unopunct@true after the \caption, but this will then be hidden by the \egroup. So we actually use

 \def\caption{%  \ifnum\captioncount@=0  \ifnopunct@  \def\next@{\egroup\nopunct@true}%  \else  \let\next@=\relax  \fi  \next@  \advance\captioncount@ by 1  \futurelet\next\caption@} Note that the \captioncount@ is always set or advanced outside of the various boxes that we build, so we don't need to use \global with it. Note also that we didn't worry about \nospace. That's because this control sequence, although allowed before \caption, won't have any effect (in the default style, where nothing follows the final punctuation of a caption; if for some reason a style did have a space after this punctuation, a slightly more complicated routine would be needed).


#### Formatting a \caption

Analogous to \claimformat@, we want to have \captionformat@, to describe, in the very simplest terms, how a caption should be formatted

\long\def\captionformat@#1#2#3{\#1{\island@@@@F#2}#3\punct@.} Here #1 will be the "caption prefix", #2 will be the properly formatted caption number, and #3 will be the argument of \caption. We use \long because we allow #3 to contain a blank line (the default style doesn't treat new paragraphs in a \caption in any particularly interesting way, but other styles might.) The '\punct@.' allows a \nopunct before the \caption to eliminate the period (for a caption that ends with a! for example); a \null is not added here (compare pages 166 and 208) since nothing follows the period. A \nospace before a \caption will have no effect, in the default style, but is allowed.

Unfortunately, the actual formatting of a caption may be quite a complex affair. In the default style, for example, if the caption can be set on a single line whose width is less than the width of \box\islandbox@, we center that line under \box\islandbox@; otherwise, we set the caption as a paragraph whose width is the same as that of \box\islandbox@. In addition, when a single \island has multiple \caption's, we have the usual problem of stacking these paragraphs on top of each other, so we will want to insert struts.

Many, many, other arrangements might be used; captions might be printed on the side of the figure, etc. It is impossible to anticipate all the things that different style files might do, but necessary modifications for other styles should be clear from a careful study of the proceedings used throughout this chapter.

We begin by adding struts to the definition of \captionformat@:

\long\def\captionformat@#1#2#3{\rm\strut
#1{\island@@@@F#2}#3\punct@.}

In other styles, \rm might be replaced by something like \tenpoint, so that the caption will be in 10 point type no matter what the current font may be; the \strut should follow, so that it will be the right size. Of course, some styles might even need different \captionformat@'s, for different sorts of \island's.

Then we want to have

\widerthanisland@#1#2#3 to test whether \captionformat@#1#2#3 produces an \hbox that is wider than \box\islandbox@, setting \iftest@ to be true if it is wider, and setting it to be false otherwise. Basically, we want to

\setbox0=\hbox{\captionformat@{#1}{#2}{#3}} and measure the width of \box0.

This fails, however, if the caption contains a displayed formula, like

\#$\alpha=....$$

Indeed, in restricted horizontal mode $$ simply stands for an empty formula (_The TeXbook_, page 287), so the \alpha is outside of math mode, and will give a (mysterious) error message. (It also fails if the caption contains a \linebreak, although presumably this will only be put to avoid an Overfull \hbox when the caption is longer than the island.)

So instead (compare page 315) we first

\setbox0=\vbox{\hsize=\maxdimen  \noindent@@\captionformat@{#1}{#2}{#3}%  \par  \setbox0=\lastbox} where the inner \setbox0=\lastbox simply removes1 the last box in (the main) \box0. (See Chapter 8 for the \noindent@@.) If our caption argument #3 consists of simple text, everything will have been set on one line, which will be \lastbox, so our final \box0 will be empty, and therefore have width \(\tt{Opt}\) (compare the footnote on page 324). In this case, we will simply set the same material in \box\captionbox0, and set \iftest@ to be true if the width of this box is greater than the width of \box\islandbox@ and false otherwise.

#### 32.4. Formatting a \caption

But if #3 contains a displayed formula, or more than one paragraph of text, or anything else that creates more than one line of text (including perhaps, so much text that it won't even fit on a line of length \maxdimen), then there is still a line left after we eliminate \lastbox, so the final \box does not have width Opt. In this case, we also want \iftest@ to be true, since we again want to reformat #3 within a \vbox having the width of \box\islandbox@.

After we have set a box for testing purposes, we must be careful to \unlabel@ (section 16.5), to ignore any \label's for future setting of #3, for otherwise we will be using a \label more than once when we do the final setting. We will also use \nooset (section 16.4), just in case \Reset or \Offset appear.

We define our test by:

\long\def\widerthanisland@#1#2#3{\test@true \setboxO=\vbox{\hsize=\maxdimen \noindent@@@\captionformat@{#1}{#2}{#3}\% \par\setboxO=\lastbox}% \ifdim\wd=Opt \setbox\captionbox@=\vbox{\nooset@\unlabel@ \captionformat@{#1}{#2}{#3}\% \ifdim\wd\captionbox@ > \wd\islandbox@\else\test@false\}if \if}

Now we can define \captionformat@, which does the actual formatting by:

\long\def\captionformat@@@#1#2#3{\widerthanisland@{#1}{#2}{#3}\% \iftest@ \global\setbox\captionbox@=\vbox{\vbox{\hsize=\wd\islandbox@ \vskip-\parskip \noindent@@@\noiset@\unlabel@ \captionformat@{#1}{#2}{#3}\par}\%}else  {global\setbox\captionbox@= \hboxto\islandbox@{\hfil\box\captionbox@\hfil\% \fij} ```

The \vskip-\parskip is used to eliminate any extra \parskip glue before our \noindent@@@'ed paragraph.

Finally, \finishcaption@#1, where #1 will be the argument of \caption, first stores #1 in \entry@,

\def\entry@{\#1}

for writing to the.tic file later (section 5), and then takes care of details like ignoring initial and final spaces,

{\localabel@ \captionformat@@@{\expandafter\ignorespaces\captionprefix@\unskip}%  {\ifx\thelabel@@@\empty\unskip\else\thelabel@@\fij}%  {\ignorespaces@1\unskip}}

If there is only one \caption so far, our final \box\Captionbox@ will just be a \vbox containing \box\captionbox@:

\global\setbox\Captionbox@=\vbox\box\captionbox@}%

(We do this so that \box\Captionbox@ is always a \vbox; that way, we can always \unvbox\Captionbox@ when necessary.)

Otherwise, we want to create a new \box\Captionbox@ by combining the old \box\Captionbox@ with \box\captionbox@ with a \smallskip between them:

\global\setbox\Captionbox@=\vbox\(\{\unvbox\}Captionbox@ \{\small\smallskip\backslash box\}Captionbox@)%

In addition to the \smallskip, \strut's will give the proper line spacing.

#### 32.4 Formatting a \caption

Note that the \unvboxed \Captionbox@ and \box\captionbox@ will not have any additional space added between them.1

Footnote 1: _The TeXbook_, page 282: “The vertical list inside that box is appended to the current vertical list, without changing it in any way.” _The TeXbook_ goes on to say that “The value of \preverbth is not affected.” That is, the value of \preverbth after the \unvbox is the value it had before the \unvbox, _not_ the depth of the last box produced by the \unvbox. This will be important later (page 445).

At this point we also want to add appropriate \write\tic@'s for writing to the.tic file (page 187). Although it would seem reasonable to include these \write's within \box\Captionbox@,1 we will instead attach them to \box\islandbox@, which will always appear on the same page as the corresponding captions. (At some preliminary stage of the macros, \box\Captionbox@ was subjected to further processing, which would have been complicated by the presence of \write's. That is no longer the case, so that the \write's could be included in \box\Captionbox@, but there's nothing wrong with the other approach, and I didn't want to rewrite this part of the routines, with the attendant risk of introducing some new bugs.)

Footnote 1: Note that, unlike \insert’s, which have an effect only if they “migrate” out to the main vertical list, \write’s will take place when enclosed in boxes, no matter to what depth.

We will define \ticwrite@, the appropriate collection of \write\tic@'s, in section 5, and we will use

\ifnum\captioncount@=1

\global\setupbox\islandbox@=\vbox\{\icture\vbox\islandbox@}\%

\global\setupbox\Captionbox@=\vbox\{box\captionbox@}

\else

\global\setupbox\islandbox@=\vbox\{\unvbox\islandbox@}

\setupbox=\lastbox\citewrite@\boxo }

\global\setupbox\Captionbox@=\vbox\{\unvbox\Captionbox@}

\smallskip\box\captionbox@}

\%fi

Note that when \captioncount@ is 1, our new \box\islandbox@ is a \vbox containing \ticwrite@ at top, and then the old \box\islandbox@ enclosed in another layer of \vboxing. The reason for this is that \box\islandbox@ might contain more than one thing (in particular, it might contain the \write for a \pagelabel), and we don't want to uncover any of these layers when 





so that this new box, together with the caption box and #1 space between them, will take up the entire page. In addition, if \ifFigureproofing is true, then we need to put crop marks around this new \box\islandbox@.

So we start out by setting

\dimen@=\vsize

If there was a caption we

\advance\dimen@ by -\ht\Captionbox@ \advance\dimen@ by -#1

Now we basically want to

\setbox\islandbox@=\vbox

\(\{\hbyw\dimen@{\wd\islandbox@}\}\)

In order to allow crop marks around this box, however, we need to have \ifHby@ be false (page 365). But we'll need to know the value of \ifHby@ later on (page 390 ff.). So we will set \global\Hby@false before we do this, and restore \global\Hby@true afterwards (remember that this whole routine is being done only when \ifHby@ is true; we use \global assignments here since they were necessary previously).

Before we actually

\global\setbox\islandbox@=\vbox

\(\{\hbyw\dimen@{\wd\islandbox@}\}\}\)

we must first extract any \tickwrite's that may have appeared in the old \box\islandbox@, and make sure that they appear in the new one. To do this, we can first store \wd\islandbox@,

\dimen@ii=\wd\islandbox@

and then

\global\setbox\islandbox@=\vbox

\(\{\unvbox\islandbox@}\)

\(\{\setbox\0=\)\lastbox

\(\}\hbyw\dimen@\dimen@ii\}\)

#### 32.6\Htrim@

Recall (page 380) that the

\unvbox\islandbox@\setbox0=\lastbox

leaves the \write's at the top of \box\islandbox@, while deleting the other part. Unfortunately, that's not quite adequate, because we will then loose any \pagelabel information that may have been in \box\islandbox@. So instead we use

\global\setbox\islandbox@=\vbox

\unvbox\islandbox@

\setbox0=\lastbox

\vbox toOpt{\vss\box0}\nointerlineskip

\hbyw\dimen@\dimen@ii}

Although no extra space is inserted before the \vbox toOpt (see the footnote on page 379), we need \nointerlineskip to prevent extra space between that box and the next \hbyw.

The complete code is:

\def\Htrim@#1{% \ifHby@ \dimen@=\vsize \ifnum\captioncount@=0 \else \advance\dimen@ by -\ht\Captionbox@ \advance\dimen@ by -#1% \fi \global\Hby@false \dimen@ii=\wd\islandbox@ \global\setbox\islandbox@=\vbox \{\unvbox\islandbox@ \setbox0=\lastbox \vbox \vbox toOpt{\vss\box0}\nointerlineskip \hbyw\dimen@\dimen@ii}% \global\Hby@true \fij

#### Other accoutrements for \endisland.

The \islandpairdata and \islandtripledata constructions (section 10) essentially operate by temporarily creating \islands and storing \box\islandbox@ in other places. During such processes we want to abort most of the additional operations of \endisland, so we need a flag

\newif\ifdata@

to tell us when we are performing such temporary maneuvers.

We also need a way of testing for the class of an \island, since this will determine how the caption is attached to the \island; in the default style, for example, an \island with class T (i.e., a \Table), has the caption above, instead of below. The definition of \iclassstest@ is analogous to \classtest@ for \claim (section 22.11):

\def\iclassstest@#!{\def\next@{\#!}\ifx\next@\islandclass@ \test@true\else\test@false\if}

We don't bother with a corresponding \itypetest@, because the class of an \island should be sufficient information: Unlike the situation for \claim, where, for example, \claim\c{T}{Theorem} and \claim\c{T}{Lemma} might be used so that Theorem's and Lemma's are numbered together, it's unlikely that any one would want Tables and Figures, or Maps and Plates to share a common numbering. Of course, a style file that did want to allow such things could introduce a suitable \itypetest@.

#### 32.8 \endisland.

Finally, we are ready for \endisland. If there was no \caption, then it must provide the \egroup that matches the \bgroup in \island,

\ifnum\captioncount@=0 \expandafter\egroup\fi

Next come the instructions for putting the island and caption together, which will _not_ be done when we are simply collecting data for constructions
32.8 \endisland

like \islandpairdata, etc.,

\ifdata@

\else

\fi

In the case of a table, the default style leaves a \bigskip between the caption and the island, so we want to start with something like

\iclasstest@{T}

\iftest@

\Htrim@\bigskipamount

Remember that \Htrim@ operates only when we have an \Hbyw. In this case, it makes \box\islandbox@ just high enough so that its height plus the height of \box\Captionbox@ plus \bigskipamount is \vsize.

Actually, instead of \bigskip, we really want less space, because the last line of the caption above the table will have a depth of 3.5pt (the depth of a strut). So we really want something like

\skip@ = -3.5pt \advance\skip@ by \bigskipamount

\Htrim@\skip@

That way, we know exactly how much space we are getting: enough to make the baseline of the first line of the caption 12pt plus \bigskipamount below the \island.

We will actually use something like

\rm\global\skip1 = -\dp\strutbox\global\advance\skip1 by \bigskipamount

\Htrim@{\skip1}

to remind other style files to insert something like \tenpoint for the \rm, so that \skip1 will have the proper value. We need \skip1 because of the }global assignment. Since it turns out that \skip1 will be used quite frequently, we will

\skipdef\skipi@=1

so that we can use \skipi@ to abbreviate \skip1.

Then we want

\global\setbox\islandbox@=\vbox {\ifnum\captioncount@=0 \else \box\Captionbox@ \nointerlineskip \vskip\skipi@ \fi \box\islandbox@}

In addition to the \vskip\skipi@ that we provide, there would normally also be \lineskip glue between the caption and \box\islandbox@; we use \nointerlineskip to suppress this, so that there is just one glue between the two boxes.

The new \box\islandbox@ will eventually be taken apart by the \output routine (knowing that there is just one glue between the two boxes makes this easier), and the pieces will be put back on the page in the proper way. In the default style, \box\Captionbox@ and (the original) \box\islandbox@ will each be centered; at that time, the \vskip\skip\skipi@ glue between them will be able to stretch or shrink with the other glue on the page.

In the default style, all \island's other than \Table's have their captions below, with a \medskip between them. In this case we actually want to _increase_ the \medskip by 3.5pt, since the first line of the caption has a strut of height 8.5pt:

\else {\rm\global\skipi@ = \dp\strutbox} \global\advance\skipi@ by \medskipamount \Htrim@\skipi@




store the \island's and \caption's from their arguments in appropriate boxes, which we first declare:

\newbox\islandboxi \newbox\islandboxiii \newbox\captionboxi \newbox\captionboxii \newbox\captionboxiii \newbox\captionboxiii \newbox\captionboxiii \newbox\captionboxiii \((These boxes, as well as \islandpairdata, etc., have no \(\emptyset\)'s in them, so that they will be accessible to the user.)

\islandpairdata{...}{...} is meant to be used when each... is some sort of \island like

\Figure _ _ \endFigure

Basically, we just want to execute the first

\Figure _ _ \endFigure

without any \...place, and store \box\islandbox\in \box\islandboxi and \box\Captionbox\in \box\captionboxi, and similarly for the second

\Figure _ _ \endFigure

Since \island's normally work only when \ifplace\(\emptyset\) is true, we will simply temporarily declare this within a group. We will also set \ifdata\(\emptyset\) to be true to disable most of the \endisland routine.

\long\def\islandpairdata\#1#2{\%  {\place@true \data@true  #1%  \global\setupbox\islandboxi=\box\islandbox\emptyset  \global\setupbox\captionboxi=\box\captionbox\#2%  \global\setupbox\islandboxi=\box\islandbox\emptyset  \global\setupbox\captionboxii=\box\cup\)\(\{\)\(\}\}\)


Thus, Figurepair produces the same effect as if we had made an island where the (appropriate space) is the combination of the (appropriate space)'s for the two islands, and where the caption is the combination of the captions for the two islands.

In version 1 the definition was somewhat different: Figurepair treated the entire combination as a single new island without a caption. The advantage of the new approach is that when our box\islandbox@ is taken apart by the output routine (page 388), there will be \vskip\skipi@ glue between the combined (appropriate space)'s and the combined captions, which will again be able to stretch or shrink with the other glue on the page. In particular, if a Figure and a Figurepair appear on the same page, the space before the caption will have stretched or shrunk by the same amount for each.

The definitions of \islandparbox, to put the captions above the combined spaces, and \Tablepair, which uses this, won't be given, since they are quite analogous. Similarly, \islandtripledata, etc., follow quite similarly.

### Chapter 33. An overview

Placing the packaged figures, tables,...

We come now to what is perhaps the most interesting part of LaMS-TEX's general document processing features--its handling of inserted Figures and other island's.

Chapter 8 of the LaMS-TEX Manual describes the default style's fairly rigorous set of rules for figure placement. Of course, innumerable different rules might be specified by a style designer, so we certainly cannot claim to have anticipated all problems.

In fact, as the Manual concedes (pages 68 and 70), although the current solution will probably be quite adequate in practice, it isn't ideal. The aim of LaMS-TEX's automatic placement mechanism is not to provide perfection, but to get as much mileage as possible out of TEX's own insert mechanism. Although the details of the LaMS-TEX constructions take up the next few chapters, they are fairly simple in concept; a TEXpert intending to change the \output routine should not rush in, but at least this is not a region where TEX angels fear to tread (a thorough understanding of pages 122-125 of _The TEXbook_ is in order, however).

#### 33.1.

place. Before we get to the interesting part, we will consider the "low level" construction \place, used in a construction like

\place{\island... \endisland}

to simply insert \box{\islandbox@ at the current point in the file.

The \place construction begins by declaring \place@true, so that the \island construction won't give an error message, and \island@false, so \ifisland@ will be true only if the argument of \place@ actually involves an \island of some sort:

\def\place#1{\place@true \island@false

\#1..

The argument #1, presumably \island...\endisland, will simply create \box{\islandbox@ and set \island@true. So if \ifisland@ is still false, wewill give an error message:

\Error@{Whoa... there's no \string\Figure, \string\Table, etc., here}

Otherwise, we will just use

\box\islandbox@

to typeset the box at that point.

Then we will reset \ifplace@ to be false:

\def\place#i{\place@true\island@false

\ifisland@

\box\islandbox@

\else \Err@{Whoa... there's no \string\Figure, \string\Table, etc., here}%

\fi \place@false}

#### Automatic placement

Having gotten that out of the way, we are ready, willing, and able to tackle the automatic placement routines.

Here is the general principal. Whenever something is \...place'd it will simply be added to a certain insertion class; for this purpose we might as well preempt plain TeX's \topins insertion class, since we have already disallowed its use for its original purposes.

Remember that for every insertion class, like \topins, there is

* An associated box, \box\topins, which is where the material from that insertion class appears when a page has been completed and the \output routine is called. At that time, the height of \box255 may well be different than \vsize, since the \output routine is going to combine \box255 with the material in \box\topins (and possibly other material), to make the box that TeX will \shipout.

#### Automatic placement

In plain TEX, material from the \footins and \topins insertion classes are handled rather simply: the \pagecontents macro simply \unvbox'es each of these boxes, keeping everything in \box\topins at the top of the page, and everything in \box\footins at the bottom. But there is no need for such a restricted approach: it's quite possible for the \output routine to extract various pieces from \box\topins, putting some pieces at the top and other pieces at the bottom. Thus, some figures in the \topins insertion class can just as well be placed at the bottom of the page (hopefully, before the footnotes) as at the top of the page.
* An associated counter \count\topins, which tells TEX what proportion of the height plus depth of \box\topins to subtract from \resize in computing the proper height for \box255. In plain TEX, \count\topins=1000, indicating that \box255 should leave room for the full height plus depth of \box\topins; this will remain the same in \(\box\)S-TEX.
* An associated dimension register, \dimen\topins, which indicates the maximum size of \box\topins that will be allowed per page.
* An associated glue register, \skip\topins, which indicates extra space to leave blank in \box255 if there happens to be anything in \box\topins.

As we will soon see, \dimen\topins and \skip\topins are the keys to making \topins work for us.

Notice that TEX's insertion mechanism already does most of the work we want: boxes are added and withdrawn from any insertion class in a "first in first out" manner; and TEX does all the calculations to make sure that \box255 is made sufficiently short to accommodate anything in the insertion class.

Of course, we usually don't want TEX to allow more than two things in \topins to appear per page. But this can be controlled by \dimen\topins (which can be set to any desired value at any time); if \dimen\topins is the sum of the height plus depths of the first two boxes in \topins, then TEX will allow only these two boxes to be added to \box\topins.

There is also the question of the glue to be left below a figure at the top of a page, which we will call \beltopfigskip, or above a figure at the bottom of the page, which we will call \abovebottfigskip. For the moment, let's pretend that these two values are the same. Then before


#### 33.4. How \Aplace works

##### Setting things up

First we declare the glues below figures at the top of the page and above figures at the bottom of the page, and give them their default values; at the same time, we introduce a (dimen) register for the minimum amount of text to be allowed on a page that is otherwise filled with figures:

\newskip\belowtopfigskip=15pt plus 5pt plus 5pt minus 5ptpt

\newskip\abovebotfigskip=18pt plus 5pt minus 5ptpt

\newdimen\minpagesize \minpagesize=5pc

To get \skip\topins to be the (dimen) part of \belowtopfigskip - \abovebotfigskip, we use the following code (compare page 136):

\dimen@=\belowtopfigskip \advance\dimen@ by -\abovebotfigskip \skip\topins=\dimen@ (If a style file changes \beltowtopfigskip and \abovebotfigskip, these lines should be repeated, to reset \skip\topins correctly.) Initially, \dimen\topins will be Opt; it will be increased only as we \Aplace things.

\dimen\topins=Opt

In order to set \dimen\topins correctly, we are going to have to keep track of various things. In particular, we will use a counter

\newcount\topinscount@

to keep track of how many boxes still remain in the \topins insert.

##### 33.4. How \Aplace works

An extra layer of complications envelops \A_N_S_-TEX's automatic placing mechanism because of the existence of so many different varieties of \...place's. In order to get a better idea of the main features, in this section we will consider a simpler style in which there is onlyAplace, and we will also assume that \Aplace is being used only in vertical mode. Code surrounded by dashed lines rather than solid lines will be changed when we get to the final definitions later on.

(1) Each

\Aplace{\island... \endisland}

will essentially

\insert\topins\box\islandbox@

where \box\islandbox@ is the completed box--containing both the \island and its caption(s), which the \island...\endisland creates--except that we will first increase the height of \box\islandbox@ by the (dimen) part of \abovebottggskip, so that TEX will be trying to leaving room for this box plus this amount of space. TEX doesn't allow us to say

\advance\ht\islandbox@ by \abovebottggskip

so we have to take a roundabout route and say

\dimen@=\ht\islandbox@

(A) \advance\dimen@ by \abovebottggskip

\ht\islandbox@=\dimen@

(2) Then we will

\advance\dimen@ by \dp\islandbox@

so that \dimen@ is the height plus depth of \box\islandbox@, plus the \(\dimen\) part of \abovebottggskip. The value of \dimen@ is information that we are going to store, whether or not we plan to allow the \Aplace'd \island to appear in \box\topins. Instead of keeping a list of these dimensions, it is simpler to store empty \hbox's of the corresponding width inside a \vbox, which we call \topinsdims@; the routine for doing this will be called \storedim@:

\newbox\topinsdims@33.4. How \Aplace works
401

Notice that we put the new information on the _top_ of the \vbox. That is because it is easiest to get information by taking things off of the _bottom_ of the \vbox, with \lastbox (see the footnote on page 376). Note also that no glue will be added between the \hbox's (see the footnote on page 379).

(3) Each time we encounter an \Aplace, we must decide whether or not the corresponding

\box\islandbox@,

which we have placed in the \topins insertion class, should be allowed to appear in \box\topins at the next \output routine.

The default style uses the rule that there should be at most two \island's per page. Recall that \topinscount@ is supposed to be the number of insertions currently in the \topins insertion class. So if \topinscount@ is greater than or equal to 2, there are already at least two insertions waiting to go on the current page. In this case, we don't want to allow the current insertion to appear in \box\topins. But if \topinscount@ is less than 2, so that there is at most one insertion waiting to go on the current page, then we do want to allow the current insertion to appear in \box\topins (of course, it will then be up to \TeX to decide whether there is actually room on the page for this insertion).

We initially have

\dimen\topins=Opt

This means that initially no inserts will be placed in \box\topins during the \output routine. If we decide to allow the current insertion to appear in \box\topins, we need to communicate that decision to \TeX, as indicated on page 397, by increasing \dimen\topins by \dimen@,

\ifnum\topinscount@ > 1 \else (increase \dimen\topins appropriately) \fiAgain, we will need a roundabout route for increasing \dimen\topins, \advance\dimen@ by\dimen\topins \global\dimen\topins=\dimen@ We define a routine for doing this, \advancedimtopins, which contains one more element, \def\advancedimtopins@\% \ifnum\pageno=1 \else \advance\dimen@ by \dimen\topins \global\dimen\topins=\dimen@ \fi\

In other words, aside from any other considerations influencing our decision as to whether or not an \Aplace'd \island should be allowed to appear in \box\topins, it will never be allowed on page 1.

Simple modifications of \advancedimtopins@ allow numerous other style decisions. For example, in the book style, each \chapter starts a new page and then sets \iffirstchapterpage@ to be true; then in the definition of \advancedimtopins@, the clause

\ifnumpageno=1 \else

is replaced by

\iffirstchapterpage@ \else

This prevents anything from appearing in \box\topins when the first page of any \chapter is presented to the \output routine.

(4) Once we have properly increased \dimen\topins, we can \insert our \box\islandbox into \topins (it is important to do the \insert _after_ taking care of \dimen\topins, because TeX decides whether or not to move an \insert onto the current page at the time the \insert is made).

(5) Finally, the counter \topinscount@ is supposed to be the number of boxes currently in the \topins insertion class, so each time an \Aplace occurs we need to

\global\advance\topinscount@ by 1

(it will be the duty of the \output routine to suitably _decrease_\topinscount@ by the number of \island's that finally get placed on that page).

For the actual definition, \Aplace, like \place, will begin by setting \place@true and \island@false, and end by resetting \place@false. After calling the argument #1 to set a box, and set \ifisland@ to be true, we give an error message if \ifisland@ is still false,

\def\Aplace@1\place@true \island@false

\ifisland@

\else

\Error@{Whoa... there's no \string\Figure, \string\Table, etc., here}

\fi

\place@false}

(1) Assuming we don't give an error message, the first thing will be

\dimen@=\ht\islandbox@

\advance\dimen@ by \abovebottigskip

\ht\islandbox@=\dimen@

(2) This will be followed by

\advance\dimen@ by \dp\islandbox@

\storedim@

(3) Next comes

\ifnum\topinscount@ > 1 \else \advancedimtopins@ \fi(4) Then we are ready to

\insert\topins{\penalty0 \splittopskip=Opt \floatingpenalty=0 \box\islandbox@}

The \penalty0 allows this insertion to be treated as a split insertion, and thus float to the next page if it does not fit on this page (_The TeXbook_, pages 123-124). Other penalties, like plain TeX's \penalty200, might be used by style designers to encourage TeX to keep the insertion on the same page. The \splittopskip=Opt insures that only Opt glue precedes this split insertion; this is probably unnecessary, since the inserted box is quite unlikely to be smaller than \topskip, but there's no point taking chances, especially since at one point (page 407) it will be crucial to know that this glue is indeed Opt. The \floatingpenalty=0 means that there will be no extra page breaking penalties if later inserts are allowed to split also (i.e., to appear on later pages); this is also not really necessary, since \floatingpenalty has the default value 0.

(5) Finally, we

\globaladvance\topinscount@ by 1

So our definition is

\def\aplace#1{\place@true \island@false
#1% \ifisland@

\dimen@=\ht\islandbox@

\advance\dimen@ by \abovebtoffigskip

\ht\islandbox@=\dimen@

\advance\dimen@ by \dp\islandbox@

\storedim@

\ifnum\topinscount@ > 1 \else \advanceddimtopins@ \fi

\insert\topins{\penalty0 \splittopskip=Opt

\floatingpenalty=0

\box\islandbox@}% \global\advance\topinscount@ by 1}

#### How the \output routine works

\getbox@{% \unvbox\topins \globally\setboxi=\lastbox} which makes \box1 be the bottom box. In the case where \box\topins contains at most two boxes, this isn't really all that burdensome, but in the general situation, where something like \AAplace may have been used, the reverse order becomes a true impediment. So we will define a routine

\fliptopins@

that recreates \box\topins with the sub-boxes in reverse order. At the same time, the number of boxes will be stored in a counter, \flipcount@, whose value will be used later on.

(1) To begin, we set \flipcount@ to 0. Then we \unvbox\topins within another box, into which \vskip1pt is inserted at the beginning, as a marker (compare page 328). And within this box, in which \box\topins has already been destroyed, we initialize the new \box\topins:

 \def\fliptopins@{\global\flipcount@=0  \setbox0=\vbox{\%  \vskip1pt  \unvbox\topins  \global\setbox\topins=\vbox{} }

 If \box0 looks like

 \vskip1pt  \penalty0  (box1)  \penalty0  (box2)  \penalty0  (box3)

then, as we start to take off boxes and penalties from the bottom of this list, \lastskip will be 1pt when we have reached the top; at any other point \lastskip will be Opt, since there is no other glue on the list. So the procedure

 \loop  \ifdim\lastskip=Opt  \global\advance\flipcount@ by 1  \setbox0=\lastbox  \global\setbox\topins=\vbox{\unvbox\topins\box{\}box{\}box{\}\label{\unpenalty  \repeat} should set \flipcount@ to the number of boxes, and also reconstruct \box\topins, in the reverse order.

 But \box0 can have a different structure also: when a member of \topinshas been deferred to a later page (i.e., split), \box\topins looks like

\vskipOpt

\box\1\penalty0

\box\2\penalty0

\box\3\penalty0

\box\3\penalty0

where the \vskipOpt is the \splittopskip glue, which we have made certain will be Opt (page 404). So we have to use the more complicated

\loop

\test@false

\ifdim\lastskip=Opt

\unskip

\ifdim\lastskip=Opt

\test@true

\fi

\iftest@

\setup\setbox0=\lastbox

\global\setbox\topins=\vbox\(\unvbox\topins\box\)\(\unpenalty

\repeat\)

We want to avoid all this rigamorole if \box\topins is void to begin with, so our final definition is

\newcount\flipcount@

\def\fliptopins@{\global\flipcount@=0

\ifvoid\topins}else

\setbox0=\vbox\%

\vskip1pt

\unvbox\topins

\global\setbox\topins=\vbox\%



have their correct heights, so the

\centerline{\box3} \nointerlineskip \vskip\skip\skip\centerline{\box1} \

causes a net decrease of \abovebottigskip in height, to which we have then added a net increase of \belowtopfigskip. As explained on pages 398 and 400, TeX has already left exactly enough space to allow this change from \abovebottigskip to \belowtopfigskip, so it looks like everything should work out just right. Actually, however, we will change the

\vskip\belowtopfigskip to

\ifdim\ht255 < \unimpagsize \else \vskip\belowtopfigskip \fi for reasons discussed in section 7.

If our \island had no caption, then \box1 would actually be the \hbyw, or other material, \skip\gould be Opt, and \box3 would be void. This makes no difference in the current situation, where all the sub-boxes are treated the same, but other styles might have to make explicit checks to see whether \box0 contained a caption or not.

It is even conceivable that the style would need to know what class of \island was contained in \box20. This information would probably best be recorded in a list like the list \AAllist@ discussed in sections 34.3, 34.4, and 34.8.

Once we've taken care of figures at the top of the page we use

\ifdim\ht255 < \unimpagsize \vfill\else \unvbox255 \fi to print the text in \box255, unless there is too little to go on the page; then we finish the definition off with a routine \bottomfigs@, which adds the figure at the bottom if \box\topins still has a box left in it, after which we add the footnotes, just as in plain TeX:

--------------------------------------------------------------- \def\pagecontents{% \ifnum\flipcount@ > 0 \setbox\topins=\vbox{\unvbox\topins \global\setbox1=\lastbox}% \setbox=\vbox{\unvbox1 \global\setbox1=\lastbox \global\setbox1=\lastskip \slash\label\subskip1=\lastskip \slash\label\subskip1=\lastbox \global\setbox3=\lastbox3% \centerline\{box3\}\nointerlineskip \textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{ \}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{ \}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{ \}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{\}\textbackslash{ \}

)

\centerline{box3}\nointerlineskip \vskip}skipi@ \centerline{box1}% \ifi}

Note that the \nointerlineskip at the very beginning of the definition of \bottomfigs@ is quite essential: without it, extra glue would be added before the \centerline{box3}. Even extra \lineskip glue might not fit at this stage, but, in fact, the glue might be bigger, because \box3 could be empty (for example, an empty caption above a table), in which case \baselineskip glue would be used!

Since we went to the trouble of taking apart \box\islandbox0, in order to allow the glue between the island and the caption to stretch or shrink on the page, we might also want to take apart \box\Captionbox0, so that the glue between multiple captions could also participate.

When we have an \island at top, followed by material from \box255,

\centerline{box1} \vskipbelowtopfigskip \unvbox255

the first line of \box255 will have glue above it determined by the value of \topskip; for example, in the default style there will usually be enough glue to make the height of the first line be 10pt. So the space between the bottom of \box1 and the baseline of this first line will be \belowtopfigskip + 10pt. If we were being fussy, we might increase \belowtopfigskip by 2pt to compensate for this. However, even that wouldn't work precisely if \box1 has some depth.

Probably none of this matters much when \belowtopfigskip is a fairly large value, but a more precise routine could be made: for \island's like \Figure, with their caption below, in the \endisland routine (page 389) we could add

\kern-\verbverbatim

after the \box\Captionbox0 in the final \vbox33.5. How the \output routine works

(3) After the \shipout, we will use

\advancepageno

to advance the page number.

(4) Now that \pagecontents has properly arranged the boxes in \topins on the page, the \output routine must set things up properly for the next page. First of all

\global\advance\topinscount@ by -\flipcount@

insures that \topinscount@ will still represent the number of elements in the \topins insertion class. Taking care of \dimen\topins requires more work.

At the time that the \output routine was called, \dimen\topins was the height plus depth, plus extra \abovebtofigskip space, for the first two boxes in the \topins insertion class. After the \output routine is done, we have to reset \dimen\topins to the same quantity for the first two boxes that remain in this class.

Remember that \box\topinsdim@ is a \vbox of empty \hbox's whose widths are the appropriate dimensions for the various boxes in the \topins insertion class. Since these boxes were added at the _top_ (page 401), the bottom box has the dimension for the first box in \topins, and so forth. In order to keep our information current, we will remove boxes from the bottom, the number of boxes we remove being \flipcount@, and reset \dimen\topins to the sum of the widths of the next two bottom boxes: this will ensure that on the next page, at most two of the next boxes in \topins will actually be allowed to appear in \box\topins.

To do this, we first

\global\setbox\topinsdim@=

\vbox\%

\unvbox\topinsdim@

\count@=0

\loop

\ifnum\count@ < \flipcount@

\setbox2=\lastbox

\advance\count@ by 1

\repeatIn other words, the new \box\topinsdims@ will start out with all the boxes originally in this box (from the \unvbox\topinsdims@); and then we will use \setupox0=\lastbox the appropriate number of times to get rid of \flipcount@ boxes at the bottom.

Before finishing off this box, we need to set \dimen\topins to the sum of the widths of the next two bottom boxes. The only way we can get at these widths is by using \lastbox; since we don't want to throw away these next two boxes, however, we will store them in \box1, and then \unvbox1 before completing the box. For purposes of generalization later on, we will write this as a \loop also:

\dimen@=Opt \count@=0 \setbox2=\vboxx{} \loop \ifnum\count@ < 2 \setupox0=\lastbox \advance\dimen@ by \wd0 \setbox2=\vboxx{\boxx0 \unvbox2} \advance\count@ by 1 \repeat \unvbox2 \global\dimen\topins@=\dimen@

The whole routine will be called \resetdimtopins@:

\def\resetdimtopins@{% \global\advance\topinscount@ by -\flipcount@ \global\setbox\topinsdims@= \vbox\% \unvbox\topinsdims@ \count@=0 \loop \ifnum\count@ < \flipcount@ \setbox0=\lastbox \advance\count@ by 1 \repeat33.5. How the output routine works

\dimen@=Opt \count@=0 \setbox2=\vbox{}% \loop \ifnum\count@ < 2 \setbox0=\lastbox \advance\dimen@ by \wd0 \setbox2=\vbox{\box{\nwbox2}% \advance\count@ by 1 \repeat \unvbox2 \global\dimen\topins=\dimen@} -----------------------------------------------

We aren't going to formally define an \output routine for our specialized style, saving for Chapter 36 numerous additional details (some discussed in the next section of this chapter). But here is a summary of the main points:

1. The \output routine first uses \fliptopins@ to get \box\topins into the right order, computing \flipcount@ in the process.
2. Then it ships out a \vbox whose main part is \pagecontents, which we have already considered in detail.
3. At this point, when any delayed \write's have been done, we can use \advancepageno

to advance the page number.
4. Then we use \resetdimtopins@

to properly adjust \topinscount@ and \dimen\topins for the next page.
5. Unlike the plain routine, where \box255 is always used up, our routine will not use \box255 if its height is less than \minpagesize. So at this point we use

\ifvoid 255 \else \unvbox255 \penalty\outputpenaltyThis puts the material in \box255 back on the top of the list, together with whatever \penalty precedes it, since this was recorded in \outputpenalty (_The TEXbook_, pages 125 and 254).
6. Then we end, as in plain TEX, with \ifnum\outputpenalty > -20000 \else \dosupereject \fi

#### When insertions float

Although the theory behind our definition of \Aplace may seem fine, it has one annoying flaw that becomes particularly significant when we are dealing with straight text, unrelieved by displayed formulas, or other material that introduces shrink or stretch on the page.

To take a particular example, let us suppose that we have set

 \parskip=Opt  \topskip=1Opt  \baselineskip=12pt  \vsize=478pt (= 39 x 12pt+10pt) so that exactly 40 lines of text will fit on a page, without any stretch or shrink allowed between paragraphs. (Styles with such specifications usually arrange for the heights of any Chapter headings, etc., to be an integer multiple of \baselineskip. When illustrations are to be included, \belowtopfigskip and \abovebotfigskip should probably have stretch and shrink at least half of \baselineskip, unless care is taken to insure that the heights of all \island's, when added to these \vskip's, are also an integer number times \baselineskip. However, for purposes of illustration, we will simply continue to use our default values of \belowtopfigskip and \abovebotfigskip.)

Now suppose that near the bottom of page 2 we \Aplace something that will not fit on that page, so that the \insert will split. If'\showbox\topins' is added to the \output routine, then before page [1] is shipped out, the.log file will contain the following information about \box\topins (which happens to be \box253):

 > \box253=void

#### 33.6 When insertions float

But before page [2] is shipped out, we will have

> \box253= \vbox(0.0+0.0)x0.0 this \vbox being the part that is split off from the

\insert\topins{\penalty0... } This might seem like an insignificant difference, but it's not: Since TeX has added something (albeit something trivial) to \box\topins, it has also allowed for \skip\topins=-3pt glue. If \showbox255' is added to the \output routine, then the log file will have

> \box255= \vbox(481.0+...)x....\glue(\topskip)

In other words, \box255 is now 3pt_too high_. In our particular example, it will probably be an Underfull box. TeX doesn't report Underfull boxes when \box255 is packaged for use by the \output routine (_The TeXbook_, page 400), and when we \unvbox255, everything will probably still turn out all right.

But if \skip\topins were as large as 12pt, then we would definitely have an extra line on our page. Consequently, the \output routine will have to take care to trim \box255 down to the proper height, and anything left over will have to be put back on the main vertical list at the end of the \output routine. (Such a final step in the \output routine will be needed for other reasons also; for example, when there are figures at both the top and bottom of the page, and the space between is less than \unimagesize, so that no text is allowed to appear on the page, everything in \box255 has to be put back).

Notice that if \belowtopfigskip were _greater_ than \abovebotfigskip, then our problem would be much more severe: In this case, \box255 would be _too short_, and there would be no way to rectify the situation. This is discussed further in section 36.5.

#### What happens to an

When we have an island involving an nhyw, the height of box0 will have been increased so that it is 18pt larger than vsize. TeX has chosen box255 so that

\vsize = height of box255 + height of box0 + \vskip\topins = height of box255 + \vsize + 18pt - 3pt = height of box255 + \vsize + 15pt

So box255 will be an empty box of height -15pt (see below for further elucidation), which would make things come out just right when it is added back in with the other material. But we won't be adding the material from \box255 in this situation, since its height is less than \uninpagesize;1 consequently, if we were to add \vskip\beltowtopfigskip in this case, we would get an Overfull box that is 15pt too high. That is why we had to use

\ifdim\ht255 < \uninpagesize \else \vskip\beltowtopfigskip \fi

In our final definition, page 457, we will actually use more refined emendations.

This apparently anomalous situation, where \box255 has negative height, more or less follows from the rules on page 128 of _The TeXbook_. The first time that an \Hbyw insertion is considered, it will be split, according to Step 4, at the \penalty0, leaving a box of height \vsize + 15pt. When the next page is made, this box will definitely be added, at Step 1, which will decrease the \pagegoal \(g\) by this height, so that it is now -15pt.

Note that, as a consequence, an \Hbyw will always appear at least one page after it is \aplace'ed, even if there is nothing else on the page at the time.

**Chapter 34.** \Aplace, \Aplace and \Bplace

We are now ready to consider the real definition of \Aplace, together with \Aaplace and \Bplace.

Unlike \Cplace, \Wplace and \MXplace, which can only be used between paragraphs, or in a special \Par...\endPar region, \Aplace, \Aaplace, and \Bplace can be used directly within paragraphs. Nevertheless, it is conceivable that the latter will also be used in a \Par...\endPar region (probably because some \Cplace, \Wplace, or \MXplace is also being used in that region). So we first have to take care of some preliminaries related to \Par...\endPar regions.

The \_\A_S_-\TEX Manual states, on page 67, that blank lines within a \Par...\endPar region will give an error message, and this was indeed true in version 1 of \_\A_S_-\TEX. But there is really no need for this, and the implementation was quite imperfect, so that feature has been dropped in version 2.

_34.1. Figures, etc., within \Par...\endPar_ First we need a flag to tell whether we are in such a paragraph, a counter to tell how many times a \...place occurred within this paragraph, and a box in which to store the text of such a paragraph:

\newif\ifPar@

\newcount\Parcount@

\newbox\Parbox@

The \island's that are \...place'ed within such regions will be stored in other boxes,

\expandafter\newbox\csname\Parfigbox1\endcsname

\expandafter\newbox\csname\Parfigbox2\endcsname

\expandafter\newbox\csname\Parfigbox3\endcsname

\expandafter\newbox\csname\Parfigbox4\endcsname

\expandafter\newbox\csname\Parfigbox5\endcsname

Creating these boxes with \csname...\endcsname is easier and more convenient than trying to make a '\Parfigbox' macro with an argument.

It turns out that we are also going to need (dimen) registers to store the depths of various paragraphs:

\expandafter\newdimen\csnameParprev1\endcsname

\expandafter\newdimen\csnameParprev2\endcsname

\expandafter\newdimen\csnameParprev3\endcsname

\expandafter\newdimen\csnameParprev4\endcsname

\expandafter\newdimen\csnameParprev5\endcsname

\expandafter\newdimen\csnameParprev6\endcsname

We need six (dimen) registers because \Parprev1' will store the depth of the paragraph before the \Par...\endPar region, \Parprev2' will store the depth of the text before the first \island, etc. As before (compare pages 14, 29, 75, and 128), we use quotes around \Parprev1 to indicate that it is a single control word.

In addition to all this, within each \Par...\endPar region we will be keeping a list,

\Parlist@

which will simply be a list of letters.

The definition of \Par begins by ending the previous paragraph, storing the depth of the last line of that paragraph in \Parprev1', setting \ifPar@ to be true, and initializing \Parcount@ to be 1 and \Parlist@ to be empty:

\par

\csnameParprev1\endcsname=\prevdepth

\par@true

\global\Parcount@=1

\global\let\Parlist@=\empty

Then we begin to set \box\Parbox@,

\setbox\Parbox@=\vbox\bgroup

We want this \vbox to begin with a \break for latter purposes (section 35.4).

Our whole definition is:
The definition of \endPar will not be given until section 35.4.

2. \place@. The constructions \Aplace, \AAplace, and \Bplace have much in common, and they are going to be defined in terms of a control sequence \place@#1#2 with a rather strange combinations of arguments:

\Aplace will be defined in terms of \place@ a\Aplace@ \Aplace will be defined in terms of \place@ A\Aplace@ \Bplace will be defined in terms of \place@ b\Bplace@

Here the first argument is simply a convenient single character marker, whose role will eventually become clear; the second argument, \Aplace@, \Aplace@, or \Bplace@, will then do the main work.

As an example of how this is going to work out, let's consider the definition of \Aplace, which will actually come later:

\def\Aplace@1\prevanish@ \place@true \island@false
#1% \place@ a\Aplace@ \postvanish@} where we begin with \prevanish@ and end with \postvanish@ to make the \Aplace invisible.

The definition of \place@ will be of the form

\def\place@#1#2\% \ifisland@)

\else \Err@{Whoa... there's no \string\Figure, \string\Table, etc., here} \fi \place@false} to produce an error message if the argument of \Aplace didn't involves some sort of \island. If we are in vertical mode, we will just call argument #2, but in horizontal mode we call \vadjust{#2}. For example, we will call \Aplace@ when we are using \Aplace in vertical mode and

\vadjust{\Aplace@} in horizontal mode. So far we haven't even mentioned argument #1. And, quite concomitantly, we haven't mentioned what happens if we happen to be in a \Par...\endPar In this case, we want to globally set the box 'Parfigbox1' to be \box\islandbox@ if this is the first \...place@, or globally set the box '\Parfigbox2' to \box\islandbox@ if it is the second, etc. We will keep track of which \...place@ we are at with the counter \Paramout@, which was set to 1 by the \Par, and which will be increased with each \...place. So the box we want to be setting is

\csname\range\number\Parcount@\endsname and to globally set this box to \box\islandbox@ we need to say

\expandafter\expandafter\expandafter\global\csname\Parfigbox\recovery\Parcount@\endsname=\box\islandbox\islandbox\ followed by

\global\advance\Parcount@ by 1to keep the \Parcount@ counter accurate.

And, finally, here is where argument #1 comes in. When it comes time to properly tear apart \box\Parbox@, we will need to know what sort of \...place's produced the various \Parfigbox's. We keep this information in the list \Parlist@, which, for example, will be 'abaAb' when our \Par... \endPar region contains the sequence

\Aplace

\Bplace

\Aplace

\Aplace

\Bplace

\Aplace

Each time we \place@, we will simply add the marker, argument #1, at the right of \Parlist@,

\xdef\Parlist@{\Parlist@#1}

The only other detail is that an error message should be produced if more than five \...place's appear in the \Par...\endPar region. Here is the complete code:

\def\place@#1#2\%

\ifisland@

\ifhmode

\ifPar@

\ifnum\Parcount@ > 5

\Err@{Only 5 \string\place's allowed per

\string\Par...\noexpand\endPar paragraph}%

\else

\expandafter\expandafter\expandafter

\global\expandafter\setbox

\csnameParfigboxnumber\Parcount@\endcsname

\bos\islandbox@

\global\advance\Parcount@ by 1

\xdef\Parlist@{\Parlist@#1}%

\fi



concluding that it does fit (near the top of the next page). The \allobreak causes TEX to compute the page total \(t\) before it sees the \Aplace0, so that it will realize in time that the line doesn't fit. (The procedure isn't foolproof, however; even if line \(L_{1}\) does fit, TEX may end up breaking before this line if a break point with smaller cost occurred earlier).

The full definition of \Aplace@ is:

\let\AList@=\empty \def\Aplace@{\allowbreak \dimen@=\ht\island\Abox@ \advance\dimen@ by \abovebottfiskip \ht\island\Abox@=\dimen@ \advance\dimen@ by \dp\island\Abox@ \storedim@ \ifAA@ \xdef\AList@{\AAlist@1}% \advancedimtopins@ \else \xdef\AAlist@{\AAlist@0}% \ifnum\topinscount@>1 \else \advancedimtopins@ \fi \insert\topins{\penalty0 \splittopskip=Opt \floatingpenalty=0 \box\island\Abox@}% \global\advance\topinscount@ by 1 \

### 34.4. \Bplace

The definition of \Bplace is analogous to that for \Aplace:

\long\def\Bplace#i{\prevanish@ \place@true \island@false \#1% \place@ b\Bplace@ \postvanish@} with all the work going into the definition of \Bplace@.

### 34.4. \Bplace

A \Bplace is supposed to force an \island to the bottom of the page if it would normally go at the top of the current page. In other words

\ifnum\topinscount@=0

we need to force the \island to the bottom of the page. To do this, we will basically first \Aplace an island consisting of an empty box

\vbox to -\bolewtopfigskip{}

of negative height -\bolewtopfigskip, so that when this island is followed by \vskip\bolewtopfigskip we will be back at the top of the page. We actually want to our island to be a box of the form

\vbox{\vbox to -\bolewtopfigskip{}}

so that it can be taken apart, like any other \box\islandbox@, with our \unvbox'ing mechanism, so we start with

\setbox0=\vbox{\vbox to -\bolewtopfigskip{}}

The next steps,

\dimen@=\ht0

\advance\dimen@ by \abovebotfigskip

set \dimen@ to \abovebotfigskip - \bolewtopfigskip, and are thus equivalent to

\dimen@=-\skip\topins (c.f. page 399)

after which we want to set

\ht0=\dimen@and then  \storedim@  \advancedimtopins@  \insert\topins{\box0}  \global\advance\topinscount@ by 1 as

\xdef\AAlist@{\AAlist@0}

This should then be followed by the instructions for \Aplace'ing the \box\islandbox@ that we want to force to the bottom:

\def\Bplace@{\allowbreak  \ifnum\topinscount@=0  \setupox0=\vbox{\vbox to -\beltopfigskip{}}%  \dimen@=-\skip\topins  \ht0 =\dimen@  \storedim@

\advancedimtopins@  \insert\topins{\box0}%  \global\advance\topinscount@ by 1  \xdef\AAlist@{\AAlist@0}%  \fi  \dimen@=\ht\islandbox@  \advance\dimen@ by \abovebotfigskip  \ht\islandbox@=\dimen@  \advance\dimen@ by \dp\islandbox@  \storedim@  \xdef\AAlist@{\AAlist@0}%  \ifnum\topinscount@>1 \else \advancedimtopins@ \fi  \insert\topins{\penalty0 \splittopskip=Opt  \floatingpenalty=0  \box\islandbox@}%  \global\advance\topinscount@ by 1 \

#### Changing \pagecontents

Our definition of \Bplace forces the first change in our preliminary definition of \pagecontents (page 411). Recall that we first

\setbox\topins=\vbox\unvbox\topins \global\setbox1=\lastbox\

so that \box1 now contains the material we want to put on top, and then took \box1 apart with

\setboxO=\vbox\unvbox1 \global\setbox1=\lastbox \global\skipi@=\lastskip \unskip \global\setbox3=\lastbox\

In the case where \box1 is

\vbox\vbox to -\belowtopfigskip\

the new \box1 will be \vbox to -\belowtopfigskip\, while \skiip\will be \Opt and \box3 will be empty (compare the small print remark on page 410). The problem now is that when we add the combination

\centerline\box3} \nointerlineskip \vskip\skipi@ \centerline\box1} the last \hbox,

\centerline\box1}=(\hbox\to\hsize\))

will not have the negative height -\beltowtopfigskip that we want it to have: an \hbox never has negative height or depth (_The TEXbook_, page 77). So wemust change this to \centerline{box3} \nointerlineskip \vskip{skipi@ \ifdim}ht1 < Opt \box1 \else \centerline{box1}\%i

6. \breakisland@ and \printisland@. The construction by which we just took apart \box1 will appear several times, so we introduce the abbreviation

\def\breakisland@{\global\setbox1=\lastbox \global\skipi@=\lastskip \unskip \global\setbox3=\lastbox}%

Similarly, for the combination that puts the \island back on the page we introduce the abbreviation

\def\printisland@{\centerline{box3}\% \nobreak \nointerlineskip \vskip{skipi@ \ifdim}ht1 < Opt \box1 \else \centerline{box1}\%i}

Of course, the final \ifdim...\(\forall\)i clause will normally be equivalent to \centerline{box1}, and will be operative only when our macros have created a \box1 of negative height. Similarly, although the added \nobreak will sometimes be needed (page 489), at other times it will be superfluous.

\begin{tabular}{l} \end{tabular} For other styles, which treat \island's differently, a completely different \printisland@ routine might be in order; in such cases \end{tabular} may combine \box1islandbox@ and \box1Captionbox@ in an entirely different way.

7. \bottomfigs@. The possibility of \Aplace's, and thus more than two \island's per page, forces us to change the preliminary version of \bottomfigs@ (page 411) to a loop. We also use the newly defined routines \breakisland@ and \printisland@ in the definition.

#### 34.8. \resetdimtopins@

\def\bottomfigs@\% \count@=1 \loop \ifnum\count@ < \flipcount@ \nointerlineskip \vskip\abovebotfigskip \setbox\topins=\vbox\(\{\)unvbox\topins\setbox0=\lastbox \unvbox0 \breakisland@\% \printisland@ \advance\count@ by 1 \repeat}

As we will see later (page 439), there may be occasions during the use of this \bottomfigs@ routine when the \box1 in the \printisland@ routine has negative height.

#### 34.8. \resetdimtopins@.

We also have to change the definition of the routine \resetdimtopins@. Recall that at the time \resetdimtopins@ is called, \box\topinsdims@ will be a \vbox of the form

\hbox to \(\dimens_{3}\)\hbox to \(\dimens_{2}\)\hbox to \(\dimens_{1}\)\hbox

where \(\langle\dimens_{1}\rangle\) is the width of the first box that was still in the \topins insertion class just before this page was made, \(\langle\dimens_{2}\rangle\) is the width of the second such box, etc. Of these boxes in the \topins insertion class, \flipcount@ actually appeared in \box\topins, and were thus put on the page; the first thing we do is to diminish \topinscount@ by \flipcount@, so that \topinscount@ is then the number of boxes still in the insertion class.

At this time, the list \AAlist@ (of 0's and 1's) will have as many membersas \box\topinsdims@. As we perform the next step,

\global\setbox\topinsdims@=\vbox{% \unvbox\topinsdims@ \count@=0 \loop \ifnum\count@ < \flipcount@ \setbox0=\lastbox \advance\count@ by 1 \repeat

which removes the bottom \flipcount@ boxes from \box\topinsdims@, we are also going to want to remove the first \flipcount@ members from (the left end of) \AAlist@. To do this, we use

\global\setbox\topinsdims@=\vbox{% \unvbox\topinsdims@ \count@=0 \def\next@####1##2\next@{\gdef\AAlist@{##2}} \loop \ifnum\count@ < \flipcount@ \setbox0=\lastbox \expandafter\next@\AAlist@\next@\advance\count@ by 1 \repeat

The next \loop in the definition,

\loop \ifnum\count@ < 2 \setbox0=\lastbox \advance\dimen@ by \wdo \setbox2=\vbox{\box{\novbox2} \advance\count@ by 1 \repeat

requires more modifications. After the second iteration of the \loop, we want to continue as long as the boxes we encounter correspond to \Aaplace'dmaterial. To determine whether that is the case, we

\def\nextiii@{\AAlist@}

\def\next@##1##2\next@{\def\nextii@{\#\#1}\def\nextiii@{\#2}}

so that \expandafter\next@\nextiii@\next defines \nextii@ to be the next element of \AAlist@, and removes it from the copy \nextiii@ of \AAlist@ (we use a copy because we don't want these elements to be removed once the \vbox is finished).

Our \loop will iterate at least two times and at most \topinscount@ times. For values of \count@ in between, we continue the iteration only when \nextii@ is 1:

\loop

\test@false

\ifnum\count@ < \topinscount@

\expandafter\next@\nextiii@\next@\ifnum\count@ < 2

\test@true

\else

\if\nextii@ 1\test@true\fi

\fi

\iftest@

\setupbox0=\lastbox

\advance\dimen@ by \wd0

\setupbox2=\vbox{\box0\unvbox2}%

\advance\count@ by 1

\repeat

Thus, our whole (and final) definition is:

\def\resetdimtopins@{\%

\global\advance\topinscount@ by -\flipcount@

\global\setupstobx\topinsdims@=\vbox

\unvbox\topinsdims@

\count@=0

\def\next@##1##2\next@{\gdef\AAAlist@{\#\#2}}%}loop  {ifnum\count@<\flipcount@\setbox0=\lastbox  {expandafter\next@\AAllist@\next@  {advance\count@by1  }repeat  {dimen@=Opt  {count@=0  {setbox2=\vbox[\%]  }edef\nextiii@\AAllist@\%  }def\next@####2\next@\def\nextii@\%  }def\nextiiie{##2}}%  }loop  {test@false  {ifnum\count@<\topinscount@  \expandafter\next@\nextiii@\next@  {ifnum\count@<2  }test@true  }else  {if\nextii@\test@true\fi  }iftest@  {setbox0=\lastbox  {advance\dimen@by\wdo  }setbox2=\vbox\box\unvbox2)%  }advance\count@by1  {repeat  }unvbox2  }global\dimen\topins=\dimen@\}

**Chapter 35**.: \Cplace, \Mplace, and \MXplace

Next we consider the variants \Cplace, \Mplace, and \MXplace, which must be used between paragraphs, or in the special \Par...\endPar construction.

_35.1._\Place@. Just as \Aplace, \AAlplace, and \Bplace are defined in terms of \place@, the \Cplace, \Mplace, \MXplace constructions are defined in terms of \Place@. This is similar to \place@, except that (1) in horizontal mode if we are not in a \Par...\endPar region, we will give an error message rather than using a \vadjust, and (2) if we are in a \Par...\endPar region we will add a \vadjust{\break}:

\def\Place@#1#2\% \ifisland@ \ifhmode \ifPar@ \fnum\Parcount@ > 5 \Err@{Only 5 \string\place's allowed per \string\Par...\noexpand\endPar paragraph}% \else \expandafter\expandafter\global\expandafter\setbox \csname\Parfigbox\Parcount@\endcsname =\box\islandbox\global\advanced\Parcount@ by 1 \xdef\Parlist@\{\Parlist@\#1\}% \vadjust{\break}% \fi \else \Err@{\noexpand#2allowed only in a \string\Par...\noexpand\endPar paragraph}% \fi \else \#2% \fi \}else \Err@{Whoa... there's no \string\Figure, \string\Table,  etc., here}% \fi \place@false} Note that the \vadjust{\break} occurs within the \box\Parbox@ that we are setting; it will be used (in section 4) when we pull the box apart.

_35.2_ \Cplace@. We first declare a new flag and a new (dimen) register:

\newif\ifC@ \newdimen\Cdim@

The definition of \Cplace is analogous to all the previous \...place's,

\long\def\Cplace@i{\prevanish@ \place@true \island@false #1% \Place@ \Cplace@ \postvanish@} leaving all the work to \Cplace@. \Cplace@ basically just calls \Aplace@, except that when \topinscount@ is 0, so that there are no insertions waiting to go on the page, it sets the flag \ifC@ to be true, and the (dimen) \Cdim@ to \pagetotal; this information will then be used by the \output routine.

\def\Cplace@{\allowbreak \ifnum\topinscount@ > 0 \else \global\C@true \global\Cdim@=\pagetotal \fi \Aplace@} Here we start with \allowbreak, even though this occurs in the \Aplace@, because it might give \TEX the opportunity to call the \output routine, which will reset \topinscount@.

35.3. VMplace@_and_ VMplace@ 437

35.3. VMplace@_and_ VMplace@. The VMplace and VMplace constructions are going to be defined together, much like VAdplace and VAdplace. First we define

\long\def\Mplace#1{\prevanish@\place@true\island@false
#1% \Place@ m\Mplace@ \postvanish@}

so that the work goes into defining VMplace@.

Similarly, we define

\long\def\MXplace#1{\prevanish@\place@true\island@false
#1% \Place@\M\MXplace@ \postvanish@}

where we define VMplace@ in terms of \Mplace@ and a flag:

\newif\ifMX@

\def\MXplace@{\MX@true\Mplace@\MX@false}

The definition of VMplace@ begins with \allowbreak,

\def\Mplace@{\allowbreak.}

just as with other \...place's. Then, however, it is quite different, because we must calculate whether or not \box\islandbox@ will fit on the current page, together with \abovebottfigskip glue above it (there is no need to consider the glue below the box, since it is allowed to disappear at a page break). Actually, \abovebottfigskip is merely supposed to be the minimum amount of glue before the box: if \lastskip is less than \abovebottfigskip, then we will \unnskip before adding this glue, and if \lastskip is equal or greater to \abovebottfigskip, we will do nothing. Moreover, this glue will disappear if there is nothing else on the current page.

We begin with

\dimen@=\ht\islandbox@ \advance\dimen@ by \dp\islandbox@ \ifdim\pagetotal=Opt \else \ifdim\lastskip < \abovebottfigskip \advance\dimen@ by \abovebottfigskip \advance\dimen@ by \lastskip \fi \fi so that \dimen@ is the amount of space required for the box.

Then we

\advance\dimen@ by \pagetotal

and use the test

\ifdim\dimen@ > \pagegoal

If this test is true, then there is _not_ enough space for the box, so we use

\idime@

to convert the \Mplace to an \Aplace.

On the other hand, when the test

\ifdim\dimen@ > \pagegal

is false, so that \box\islandbox@ _does_ fit, we basically want to treat the 

### 35.3. \Mplace@ and \Mxplace@

\Mplace like a \place, except for adding the requisite space:

\nointerlineskip \ifdim\lastskip < \abovebottfigskip \removelastskip \vskip\abovebottfigskip \fi \setbox0=\vbox{\unvbox\islandbox@ \breakisland@} \printisland@

Unlike the situation for \bottomfigs@, which simply adds things to the \vbox created by \pagebody, the \nobreak appearing in the definition of \printisland@ is required here, when we are simply contributing things to the main vertical list.

Now we have to make sure that no later \Aplace will end up at the top of this page, and hence out of order. We handle this in much the same way as \Bplace, by essentially \Aplace'ing a box of height -\belowtopfigskip if \topinscount@ is 0:

\ifnum\topinscount@=0 \setbox0=\vbox{\vbox to-\belowtopfigskip{} \dimen@ = -\skip}topins \nt0 = \dimen@ \storedim@ \advancedimtopins@ \insert\topins{\box0} \global\advanced\topinscount@ by 1 \xdef\AAlist@{\AAlist0} \fi

Finally, suppose that \ifMX@ is true. Then we are considering an \Mxplace, which means that we want to prohibit an \island from appearing at the bottom of the page. To do this, we essentially want to \Aplace a box of height -\abovebottfigskip if \topinscount@ is 1. (This box of negative height will be contributed to the page by \bottomfigs@, a circumstance alluded to on page 431.))

So we start with

\setbox0=\vbox{\vbox to-\abovebotfigskip{}}

In this case, making the height of \box0 bigger by \abovebotfigskip is just the same as making it Opt, and we set \dimen@ to this value before the \storedim@:

\ht0=Opt \dimen@=Opt \storedim@ \advancedimtopins@ \insert{topins{\box0} \global\advance\topinscount@ by 1 \xdef\Allist@{\Allist@0}

And after all that, we add

\nointerlineskip \vskip\belowtopfigskip

below our Mplace^d \island:

\def\Mplace@{\allowbreak\dimen@=\ht\islandbox@ \advance\dimen@ by \dp\islandbox@ \ifdim\pagetotal=Opt \else \ifdim\lastskip < \abovebotfigskip \advance\dimen@ by \abovebotfigskip \dvance\dimen@ by -\lastskip \fi \dvance\dimen@ by \pagetotal \ifdim\dimen@ > \pagegoal \Aplace@


_Chapter 35_. \Cplace, _Mplace, and_ VMXplace

'\Parfigboxn' and the letter a, A, or b in \Parlist@ (section 34.2), while a \Cplace, \Mplace, or \Mplace stores the \box\islandbox@, and the letter c, m or M, and also adds a \adjust{\break} within the \box\Parbox@ that we are setting (section 1).

When we get to the \endPar that matches the \Par, we will first supply the \egroup that ends the setting of \box\Parbox@,

\def\endPar{\egroup

The remaining task is to take the material in \box\Parbox@ and restructure it as if all the \Cplace's, \Mplace's and \MXplace's actually occurred between paragraphs. The idea is to use \vsplit to take \box\Parbox@ apart, splitting it after the lines where \vadjust{\break}'s were added at these \...place's, and treat the pieces as separate paragraphs. The pieces into which we split \box\Parbox will be stored in new boxes that we declare:

\expandafter\newbox\csname\Parbox1\endcsname \expandafter\newbox\csname\Parbox2\endcsname \expandafter\newbox\csname\Parbox3\endcsname \expandafter\newbox\csname\Parbox4\endcsname \expandafter\newbox\csname\Parbox5\endcsname

To split \box\Parbox@, we use a \loop,

\count@=1 \loop \ifnum\count@ < \Parcount@

This \loop will be enclosed in a group where we have set

\vfuzz=\maxdimen \vbadness=10000

so that Overfull and Underfull \vbox'es will not be reported. In this group we will also set \splitmaxdepth to \maxdimen, since we already know where our boxes will split, and don't want to impose any extraneous constraints on their depths, and we will set \splittopskip=\ht\strutbox, so that in essence a strut will have been added at the beginning of each box.

#### 35.4 \endPar

Before beginning the \loop, we will

\setbox0=\vsplit\Parbox@ to\ht\Parbox@

Because of the \break at the beginning of \box\Pparbox@ (page 420), this simply splits off the \break and the following \parskip glue into \box0 (which will not be used), so that the remaining \box\Pparbox@ doesn't begin with extraneous glue.

Now we will continue to

\vsplit\Parbox@ to \ht\Pparbox@

storing the results in '\Pparbox1', '\Pparbox2',... The \vadjust{\break}'s that we inserted by \Cplace, \Wplace, or \MXplace will force these new (Underfull) boxes to end after the line in which this \...place's appeared.

At the same time, we want to store the depth of '\Pparbox1' in the \(\langle\)dimen\ register '\Pparprev2', the depth of '\Pparbox2' in '\Pparprev3',... (recall, page 420, that '\Pparprev1' is used to store the depth of the line before the \Ppar begins):

\loop \ifnum\count@ < \Parcount@ \expandafter\expandafter\global \expandafter\setbox \csname \Pparboxnumber\count@\endcsname =\vsplit\Pparbox@ to \ht\Pparbox@ \count@@=\count@ \advance\count@ by 1 \global\csname\Pparprev\number\count@@\endcsname =\dplus\csname\Pparbox\number\count@\endcsname \advance\count@ by 1 repeat

When this \loop is over, \box\Pparbox@ will contain the text after the line containing the last \...place (or will be void if there was no such text). Even though we need to \global\setbox\Pparbox\(n\)', the \vsplit operation defines the remainder of the split \box\Pparbox@ globally, so the final \box\Pparbox@ will persist after the end of the group.1

Footnote 1: This does not seem to be stated explicitly anywhere in _The TeXbook_, though page 259 deals with related matters.

Having finished with this, we now insert the \parskip glue, and get ready for another \loop to put things back:

\vskip\parskip \count@=1

For this loop we first define a routine

\def\nextv@##1##2\nextv@{\def\next@{##1}\gdef\Parlist@{##2}}

that extracts the first letter from \Parlist@ and stores it in \next@.1

Our \loop has several stages:

\loop \ifnum\count@ < \Parcount@ \dimen@=\csname\Pparprev\number\count@\endcsname \advance\dimen@ by \ht\strutbox\ifdimdimen@ < \baselineskip \advance\dimen@ by -\baselineskip \vskip -\dimen@ \else \vskip\linskip \fi Thus, we first set \dimen@ to be the depth of the previous line plus the height of a strut, which will be the height of the first line of the next piece of text (unless this contains some extra tall symbol). If \dimen@ is less than \baselineskip, then we want to insert

\baselineskip -\dimen@

#### 35.4 \endPar

extra glue, or equivalently,

\[-(\dimen@-\baselineskip)\]

hence the code

\advance\dimen@ by -\baselineskip \vskip -\dimen@ Otherwise, the two lines are already too far apart for \baselineskip glue to be used, so we just add the \lineskip glue.
2. Next we

\unvbox\csname\parbox\number\count@\endcsname

to put the next part of the text on the vertical list; recall (see the footnote on page 379), that no extra space is added before or after this material, and that its depth does not influence \predepth, which is why we have stored the various depths in registers, and have added the extra space between these various pieces by hand.
3. The next step is to deal with the corresponding \...place'd material, stored in

\box\csname\parfigbox\number\count@\endcsname

We first move this material into \box\islandbox@,

\global\setup\islandbox@ =\box\csname\parfigbox\number\count@\endcsname

and then use

\expandafter\nextv@\Parlist@\nextv@

so that \next@ will have the value

a if the material was \...place'd with \Aplace

A if the material was \...place'd with \Aplace

b if the material was \...place'd with \Aplace

c if the material was \...place'd with \Cplace

m if the material was \...place'd with \Cplace

M if the material was \...place'd with \Mplace





code

\specialsplit@false \ifvoid\topins\else\ifdim\ht\topins=Opt \specialsplit@true \if\fi

to set \ifspecialsplit@ to be true only if \box\topins has height Opt, but isn't void (the latter test must be made explicitly because a void \box\topins will also satisfy the condition \ifdim\ht\topins=Opt), and thus precisely when (section 33.6) our \box255 is too high by -\skip\topins (= 3pt), in which case we will eventually have to prune down \box255.

Remember that we are going to be using code like

\ifdim\ht255 < \minpagesize \else\unvbox255 \fi

so that we are not going to \unvbox255 at all when the test

\ht255 < \minpagesize

is true. But when \ifspecialsplit@ is true, we really want the test

\ht255 < \minpagesize - \skip\topins

(0) To achieve this, we will simply use

\specialsplit@false \ifvoid\topins\else\ifdim\ht\topins=Opt \specialsplit@true \advance\minpagesize by -\skip\topins \if\fi

(\minpagesize will be restored to its usual value at the end of the \output routine, since TeX implicitly encloses the \output routine within a group.)

After this step, we follow the procedure outlined on page 415:

(1) We use \fliptopins@, to prepare \box\topins for use by \pagecontents, which will take care of properly positioning any \island's that have shown up in \box\topins.

#### 36.1. \plainoutput

(2) Instead of plain TeX's direct \shipout, we will declare a new box \newbox\outbox@ and also \let\shipout@=\shipout and then \setbox\outbox@=\vbox\makeheadline\pagebody\makefootline\{noexpands@\let\style=\relax \shipout@\boxbox\outbox\} The \noexpands@ and \let\style=\relax are necessary before the \shipout@ because various \write's in \pagebody will contain page numbering control sequences, whose expansion we want to prohibit (compare pages 58 and 87), and they might also contain \style (pages 204 and 382).

\def\crop#i\vbox{... #1... } which puts crop marks around a box #1, and then \def\shipout@\shipout\crop\box\outbox\} (3)-(6) Then come \advancepageno \resetdimtopins@ \ifvoid 255 \else \unvbox255 \penalty\outputpenalty \ifnum\outputpenalty > -20000 \else \dosupereject \fi The whole definition is:


#### 36.3. \pagecontents

The \kern\hsize moves the entries over to the right side of the page, the \rlap allows them to stick into the right margin, the \vbox toOpt allows them to be arbitrarily long, and the \kern4pt, chosen empirically, starts the entries slightly below the top line, to look better.

#### 36.3. \pagecontents

The only thing left to define is \pagecontents, for which we have given a preliminary definition on page 36.3.1, with the modification of section 36.3.1.

We will need one final flag

\newif\ifonlytop@

which will be set true when the only thing on the page is a figure on top.

The definition of \pagecontents begins

\def\pagecontents{\onlytop@false

\ifdim\ht255 < \minpagesize

\ifnum\flipcount@ < 2

\ifvoid\footins

\onlytop@true

\if\if\if\fi

Thus, we set \onlytop@true only when three conditions all hold: (1) \ht255 is less than \minpagesize, so that we will not \unvbox255 after the top figure; (2) \flipcount@ is less than 2, so that there are no figures to go after the one on top; (3) \box\footins is void, so that there are no footnotes to go after the figure on top either.

The main change in \pagecontents is that special work may be needed if \flipcount@ has the value 1 and \ifC@ is true, so that there is just one 


#### 36.3. \pagecontents

so that \dimen@ is \ht255 plus the difference in the space we are going to add (page 399), and then replace \unvbox 255 with

\setbox1=\vsplit 255 to \dimen@

\unvbox1

(anything remaining in \box255 will be put back on the main vertical list later). During the \vsplit we want to set \vfuzz=\maxdimen, \vbadness=10000, \splitmaxdepth=\maxdepth, and \splittopskip=\topskip, as in the definition of \endPar (page 442):

\vfuzzy=\maxdimen \vbadness=10000 \splitmaxdepth=\maxdepth \splittopskip=\topskip

\setbox1=\vsplit 255 to \dimen@

\unvbox1}

The new value of \box255 will persist after the end of the group (see page 444).

If \skiptopins is negative, i.e., if \belowtopfigskip is greater than \abovebotfigskip, our \vsplit simply gives the original \box255, and we just have to hope that the glue can stretch enough to make up the difference. Compare section 5.

And then, having put the proper amount of \box255 at the top of the page, we add the \island in \box\topins, with the proper amount of space above it:

\setbox\topins=\vbox\{\unvbox\topins

\global\setbox0=\lastbox\}

\setbox0=\vbox\{\unvbox0

\breakisland@}

\nointerlineskip

\vskip\abovebotfigskip

\printisland@}

(b) When \iftest@ is false (the usual case), we simply put the first \islandin \box\topins, if any, at the top,

 \ifnum\flipcount@ > 0  \setbox\topins=\vbox{\unvbox\topins  \global\setbox0=\lastbox)%  \setbox0=\vbox{\unvbox0  \breakisland@}%  \printisland@

Normally, this should be followed by \belowtopfigskip. But we don't want to do that if nothing else goes on the page, because the figure may be too large to allow \belowtopfigskip glue below it. Instead we use

 \ifonlytop@  \kern-\prevedepth \vfill  \else  \vskip\belowtopfigskip  \fi The \kern-\prevedepth is inserted for the following reason.1 We might have an island whose height is less than or equal to \resize, but whose height plus depth exceeds \vsize. Since \pagecontents will become

 \vbox to\vsize{(the top \island) \vfill}

this will give an Overfull \vbox (without the \vfill we wouldn't have this problem, because the depth of the \island would just become the depth of the \vbox to\vsize). The \kern-\prevedepth' eliminates this extra depth, so that \vfill can safely be added.

Our preliminary definition of \pagecontents then had

 \ifdim\ht255 < \minpagesize \vfill \else \unvbox255 \fi

#### 36.3. \pagecontents

but now we will have to prune down \box255 when \ifspecialsplit@ is true. This is similar to the routine used for a \Cplace:

 \ifspecialsplit@  {\vfuzz=\maxdimen \vbadness=10000  \splitmaxdepth=\maxdepth \splittopskip=\topskip  \dimen@ii=\ht255 \advance\dimen@ii by \skip\topins  \setboxi=\vsplit255 to\dimen@ii  \unvboxi1\% \else  \unvbox255 \fi We might as well also replace the  \ifdim\ht255 < \minpagesize  \vfill with  \ifdim\ht255 < \minpagesize  \ifonlytop@ \else \vfill \fi so that a page containing a single large figure will have \vfill below it rather than two \vfill's (this just might make a difference if some one were trying to reposition things).

Finally, having taken care of the text, we just have to add \bottomfigs@, and the footnote material, if any:

 \def\pagecontents{\onlytop@false  \ifdim\ht255 <\minpagesize  \ifnum\flipcount@ < 2  \ifvoid\footins  \onlytop@true  \if\fi\fi \test@false


36.4. And we are done!

\ifspecialsplit@ {\vfuzzy=\maxdimen \vbadness=10000 \splitmaxdepth=\maxdepth \splittopskip=\topskip \dimen@ii=\ht255 \advance\dimen@ii by \skip\topins \setbox0=\vsplit255 to\dimen@ii \unvbox0)% \else \unvbox255 \fi \fi \bottomfigs@ \ifvoid\footins\else \vskip\skip\footins\footnototerule\unvbox\footins\fi}

When \vskip\topins is small we might elect simply to forget about the flag \ifspecialsplit@, and always \unvbox255 when its height is greater than or equal to \minpagesize. Only very very rarely would we encounter difficulties, and these could always be fixed by hand--after all, nothing is perfect (compare section 13).

#### 36.4. And we are done!

This finishes off everything concerned with the first part of the \(\mathit{IA}_{\mathcal{A}}\mathcal{S}\)-\(\mathit{TEX}\) Manual, except for front and back matter, which are dealt with in Part VI. Commutative diagrams are dealt with in Volume II, but all that material could just as well be considered as separate files that we could \input. And all the material for tables, except for a few things like \paste and \measuredable are actually in a separate file (except in \(\mathit{MUT}^{\mathit{TEX}}\)); these are also dealt with in Volume II. So let us now skip to the very end of the lamster.tex file.

First, we introduce the more formal \enddocument as a synonym for \bye:

\let\enddocument=\bye

Then, since we have no \new... constructions to use, we restore \alloc@ to its original plain meaning (see page 38), so that any further uses of the \new... constructions will write to the.log file:460

_ch@ck#1##2#3#4#5{\global\advance\count1#iby}@ne_{ch@ck#1#4#2\allocationnumber=\count1#1_{global#3#5=\allocationnumber}_{wlog{\string#5=\string#2\the\allocationnumber}}_}

And finally, we make @ active:

_catcode'\@=\active_

#### 36.5. When \box255 is too small.

At the end of section 33.6, we mentioned the fact that \box255 will be too small, rather than too big, when \belowtopfigskip is greater than \abovebotfigskip, so the splitting maneuvers used in defining \pagecontents won't do us any good.

Fortunately, that situation is unlikely to occur, since good style design calls for more space to be left above constructions than below them. (This holds for headers also; they look better when the space above exceeds the space below, something that more TEX style file designers should bear in mind.)

I don't see any easy way to deal with the problem of a style that chooses a value of \belowtopfigskip greater than \abovebotfigskip. The best I can suggest in that case is the following.

First of all, \Aplace will also have to be disallowed within paragraphs (except for special \Par...\endPar regions, which reduce back to use between paragraphs). Then, when we \Aplace an \island we would make a special check if \topinscount is 0 (so that this is the first \island to be considered for the page). In this case, we would use the same calculations as for \Wplace, to see if the \island will fit. If it does fit, we would simply insert it (essentially converting the \Aplace to an \Wplace). If it doesn't fit, so that it will have to float, we would set

\skiptopins=Opt

so that \box255 for this page will have just the right size. Finally, we would add

\global\skiptopins=(original value of \skip\topins)

at the end of the \output routine.

7. The endgame once again

36.6. The endgame. Although the \dosupereject's in the \output routine ensure that all \Aplace'd material will eventually make its way onto the page, some of this material may have to be printed after all the other text, with the final pages consisting entirely of \island's. These \island's will still be allocated only two to a page, so it will probably be necessary to change some of the final \Aplace's to \Mplace's or \Aplace's in order to improve the appearance of these final pages.

There doesn't seem to be any easy way to have \d_S-TEX do this automatically. We might try to change \dimen\topins to \resize when we have run out of text (i.e., when it is no longer true that \outputpenalty > -20000), but this change would be made too late--after TEX has already decided not to include some members of the \topins insertion class in \box\topins, since that decision is made at the time of the \insert.

One possibility is to have a box, say \box\remainingplaces@, in which we store copies of all the \...place'd \islands, eliminating copies as \pagecontents uses up boxes in \box\topins. Then, when we run out of text, we would change \pagecontents so that it ignores \box\topins, and instead takes things from \box\remainingplaces@, putting as many on the page as will fit. At this stage we would change the definition of \dosupereject from

\ifnum\insertpenalties > 0

\line\kern-\topskip\nobreak\vill\superject\fi

to

\ifvoid\remainingplaces@ \else

\line\kern-\topskip\nobreak\vill\superject\fi

#### 36.7. The endgame once again.

In addition, there is one minor defect that is encountered even in plain TEX. The plain TEX file

\vsize=22pt

\hsize=2in

\raggedright

Here is some stuff, taking up more than a line.

\pageinsert \hbox{A}\vfil\hbox{B}\endinsert

\byewill produce _time_ pages of output: The text will all occur on page 1; the

\vbox to\vsize{\hbox{\}vfill\hbox{B}}

will take up page 2; and page 3 will be _blank_ (except for the page number).

If we add

\def\plainoutput{\%}

\showbox255\showbox\topins\showthe\outputpenalty

\hdisput\vbox{\makeheadline\pagebody\makefootline}\%

\vdvance\pageno

\ifnum\outputpenalty>-20000\else\dosupereject{\%}

at the beginning of this file (compare page 416), the.log file will show that before page [1] is shipped out \box255 contains the text, box\topins is

> box2553=

\vbox(0.0+0.0)x0.0

(because of the split insert) and the Outputpenalty is 10000 (set by TEX because the chosen breakpoint for the page was not a penalty item).

Before page [2] is shipped out, \box255 will be an empty box, while \box\topins will now be the \vbox to\vsize{\hbox{A}vfill\hbox{B}} (and the value of \outputpenalty will still be 10000).

Finally, before page [3] is shipped out, we will have

> box255=

\vbox(22.0+0.0)x144.54, glue set 12.0fill

(A).\glue(\topskip) 10.0

\hbox(0.0+0.0)x144.54

\glue 0.0 plus 1.0fill

and \outputpenalty will be -1073741824 (= -'10000000000). As explained in _The TEXbook_, page 264, TEX inserted the equivalent of

\line{\}vfill\penalty -'10000000000

into the main vertical list when it saw the \end from the \bye (apparently because this \end was seen before the text had been output, though I don't understand the details).

7. The endgame once again

The L_M_S_-TEX file

\vsize=22pt

\hsize=2in

\raggedright

\minpagesize=22pt

\Figureproofing

Here is some stuff, taking up more than a line.

\Aplace{\Figure\Hbyw{in}\endFigure}

\bye

will also produce a blank third page,2 although the.log file will tell a somewhat different story if we add the appropriate \show's to the definition of \plainoutput in lamstex.tex.

Before page [1] is shipped out, \outputpenalty will be -20000 (presumably from a \dosupereject).

Before page [2] is shipped out, \box255 will be

\vbox(-15.0+0.0)x0.0

(see page 418), and \outputpenalty will again be -20000.

Before page [3] is shipped out, \outputpenalty will again be -20000, and we will have

> \box255=

\vbox(22.0+0.0)x144.54, glue set 22.0fill

.\glue(\topskip) 10.0

\hbox(0.0+0.0)x144.54

.\kern -10.0

.\penalty 10000

.\glue 0.0 plus 1.0fill

This \vbox, somewhat different from (A), has come from the material inserted by \dosupereject.



again having a total height of Opt].

At the time the footnote was considered, in the middle of the page, TeX carefully checked that the height plus depth of the footnote, plus the height plus depth of the page so far, plus \skip\footins, was less than the page goal, which was the \vsize of 480pt. Since this was true, so that the insert fit, the goal \(g\) for the page was reduced by 72pt [the height plus depth of the footnote plus the (dimen) part of \skip\footins], to 408pt. (The stretch and shrink part of \skip\footins was added to the page total _t_).

After that, TeX considered the page total \(t\) each time it encountered a possible break point; this page total reflects only the _height_ of the material so far, not its depth. At the point where the page was finally broken, TeX calculated that

t=444.72726 plus 35.0 minus 37.0 g=408.0

with a badness of 97. The'minus 37.0' meant that the page total could be shrunk down to 407.72726, which seems to allow just enough room for the footnote in \pagebody:

\[407.72726pt+12pt+60pt=479.72726pt\] \[<480pt\]

But there are two flaws in this calculation:

1. In the first place, when we make \pagebody, which is a \vbox to\vsize, the depth 2.5pt of the footnote at the bottom of the box is irrelevant, since it does not contribute to the height of the box. Thus, we seem to have an extra 2.5pt of breathing room.
2. Unfortunately, the depth of \box255, which no longer appears at the bottom of the \vbox to\vsize, is _not_ irrelevant, and must be added in.

It happens that the depth of the display at the bottom of page 74 is 3pt (there is a strut of depth 3pt inserted into each line of \(\mathcal{A}_{\mathcal{M}}\mathcal{S}\)-TeX's \sl align, which was used for the display). Consequently, the height of \pagebody is

\[407.72726pt+3pt+12pt+57.5pt=480.22726pt\]

leading to the Overfull \vbox (0.22726pt too high).

13. A final warning

(You can easily simulate this phenomenon with the plain TeX file

\vsize=480pt

\topskip=Opt

\insert\footins{\hbox{\vrule height 57.5pt

depth 2.5pt width 0pt}} %% the ''footnote''

\hbox{\ointerlineskip

\vskipopt minus34pt

\hbox{\vrule

height 444.72726pt depth 3pt width 0pt} %% the ''text''

\bye

which gives a single page with an Overfull \vbox, instead of two pages with a seriously Underfull \vbox on the first page. However, the two-page output will occur once the depth of the "text" exceeds 4pt, the value of \maxdepth.)

Moral: In theory, the \output routine really ought to examine the depth of \box255 before blithely \unvbox'ing it, because it might prove necessary to prune down \box255, just as we did when \ifspecialsplit@ was true (page 457). In practice, this refinement is probably just a terrible waste of time. It might become important when there is almost no stretch or shrink on a page (though one would presume that \vskip\footins would need to have some stretch and shrink in such cases).

)Part VI

_Front and_

_Bach Matter_* [15]




Because our lines have \strut's, which already make the baselines 12pt apart, it is essential that we have

\lineskiplimit=Opt

while we are setting the table of contents, so that additional \lineskip glue isn't inserted between lines (compare page 242). 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 \hhangafter 1 \hhangindent=\thehang@ Now the idea is to set a \vbox that looks like

**Chapter 1. This chapter has such a long title that it will be necessary to split it into two parts**

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 \hhangafter 1 \hhangindent=\thehang@ \rm{\n}noindent@\strut\hbox{\#1}#2}\vphantom{\{\#3#4}}struct}

#### Setting an entry

We put #1 inside an \bbox 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, _and also after the \noindent@ (so that it doesn't start a paragraph prematurely)._

As with footnotes (section 25.2), 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:

\def\endstrut@{\lower\dp\strutbox\vbox to\dp\strutbox{}}

Although we will have \lineskiplimit=Opt 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 Opt, 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=\lastboxThis makes the inner \box0 the last line of the paragraph, a "short" line that ends with \parfillskip glue, and then yet another glue, namely \rigftskip. 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\93#4\endstrut@}

}

to create the desired final line. And then we simply \unvbox0:

\negthang@

\long\def\longentry@11#2#3#4{\setbox0=\hbox{#1}%

\thehang@=\wdo\advance\thehang@ by 10pt

\setbox0=\hbox{#4}%

\setbox0=\vbox{\advance\hsize by -\wdo}

\advance\hsize by -20pt

\normalbaselines

\hangafter! thangindent=\thehang@

\vskip-\parskip

\rm\noindent@\vbox to\ht\strutbox{\%}

\hbox(\#1)#2\vphantom{\#34}\endstrut@}%

\setbox0=\vbox{\unvbox0

\setbox0=\lastbox

\hbox to\hsize{\kern\thehang@

\unhbox0 \unskip\unskip\93#4}endstrut@}%

\hbox0 \(\}\)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 379); 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.

#### 37.3 Further preliminaries for the table of contents.

The \maketoc command is going to \input the appropriate.toc file, which will have entries like

\HL {i}{word}}{(formatted heading number)}

\Page...

and/or entries like

\chapter {(word)}-{(formatted heading number)}

\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 NHL 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

\newif\iftemptynumber@

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

\def\Style@{\emptynumber@false\futurelet\style@0} \def\Style@@{\ifx\next"\expandafter\Style@0@ \else\expandafter\Style@0@@{\if}

For \Style@0@, when no " occurs, we might expect to use

\def\Style@0@#1\Style@{\#1}

Instead, however, we will use

\def\Style@0@@#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@0@ is defined by

\def\Style@0@"#1"\Style@\% \def\next@{\#1}\ifx\next@\emptynumber@true\else\#1\if}

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 \hll entries, we will also declare a new dimension \digits,

\newdimen\digits \setbox0\hbox{0.00} \digits=\wd0so 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

\def\maketoc@W{CONTENTS}

so that \newword\maketoc can be used to choose a different word.

#### Starting the \maketoc command

The \maketoc command first uses \checkmainfile@ (page 207) 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).1 Then we produce a centered bold heading '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 16.4 and 16.5). 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=\relaxWe also add

\everpar={}\parindent=Opt

for good measure.

Furthermore, as mentioned previously (page 474), it is essential that we set

\lineskiplimit=Opt. So our definition of \maketoc will start

\def\maketoc{\checkmainfile}

\par\forall\forallbreak

\inoset@\unlabel@

\let\nopunct=\relax\let\nospace=\relax

\let\overlong=\relax

\everypar={}\parindent=Opt

\lineskiplimit=Opt

#### Redefining \HL and \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 477) that it will occur in a combination like

\HL {(heading level)}{(heading word)}{(formatted heading number)}

(The heading)

\Page{...}{...}{...}{...}

so that we need a definition like

\def\HL#1#2#3#4\Page#5#6#7#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 






\makelist\c#1#2\endmakelist, like \maketoc, first uses the test \checkmainfile@, and then ends the previous page. After this we want to add

\noset@ \mabel@ \let\nopunct=\relax \let\nospace=\relax \let\overlong=\relax \everypar=\parindent=Opt \lineskiplimit=Opt

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 \Hl0@S was defined, so that we could \let\style=\Hl0@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 \Hl0@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,

\Figure {(Figure number)} \(caption) \Page...

in the.tic file will translate to \island \at@\Figure \c{F}\{Figure}\{(Figure number)} (A) \(caption) \Page...

--here \at@ is simply an arbitrarily chosen \LMS-TEX control sequence that the user can't insert--while an explicitly typed \island, like

\island \c{M}\{map}\{(map number)}


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}}

When something like

\newisland\map\c{M}{Map} appears, an occurrence of

\map {(map number)} \(\{\)(caption) \Page...

should translate to

\island \at@\map \c{M}{Map}{(map number)} \(\{\)(caption) \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@\(\)\{#2}{#3}{#1}##2\(\)\(\}\)\(\}\)Page{#3}{#4}{#5}{#6}}


\newisland\Figure}c{F}{Figure}% \newisland\Table}c{T}{Table}% \vbox{\Let@\tabskip\centeringe@\halign to\hsize {\bf\hfil\ignorespaces#\nuskip\hfil\cr\#2\crcr}}% \vskip30ptplus10ptminus10pt \input\mainfile@.tic \endgroup} ```

#### 37.9. Fini

Then, as in section 36.4, we finish with

\def\alloc@#i#2#3#4#5{\global\advance\count1#1by\@ne \ch@ck#i#4#2\allocationnumber=\count1#1 \global\3#5=\allocationnumber \wlog{\string#5=\string#2\the\allocationnumber}} \catcode'\@=\active



use VFNSS@ 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:

\def\ignorepars@{\FNSS@\ignorepars@@} \def\ignorepars@@{\ifx\next\par \def\next@\par{\fluturelet\next\ignorepars@@}\else \let\next@=\relax\if\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,

\newcount\ctype@

but the definitions

\def\nocolumnbreak@{\ctype@=1 } \def\columnbreak@{\ctype@=2 } \def\newcolumn@{\ctype@=3 } 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.

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:

\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

\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 \ncolumnbreak or \nnewcolumn 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 \pagetotal > \pagheight (i.e., we already have enough on the page for the first column), but true otherwise:

\def\cbreak@#1#2{\ifcase\ctype@#1\or\nobreak#2\else\nglobal\leftcolbreak@true\nifdim\pagetotal > \pagheight@\nglobal\leftcolbreak@false\n38.2. \LETTER and \Entry
495

\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

\newif\ifshortlastcolumn@

for a final index feature not mentioned in the \LAM\$-TEX Manual,

\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.

38.2. \LETTER and \Entry. The first \Entry after a \LETTER will be treated somewhat specially, so we will need a flag

\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 



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.

When the paragraph with this entry is completed, the \mark{10{...}} will migrate out so that it occurs right after the first line (before any \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 \bothmark 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 \splitbottomark rather than \bothmark when we do two-column setting.)

In summary, our definition begins:

\def\Entry#1#2#3#4#5#6#7{\par\entry@true \marktokos@i={#3}\marktokos@ii={#4}\marktokos@ii={#5}% \marktokos@iv={#6}\marktokos@v={#7}% \ifcase#1% \or \ifletter@\else\mark{}\fi \cbreak@\relax\relax\noindent@ \mark{10{the\marktokos@i}}\% \hangafter1 \hangindent=.5em{#3}% \or

Now let's consider the next case, \(d_{1}=\#1=2\), so that we have a first order subentry. In this case \(d_{2}=\#2\) may be either 0 or 1. When #2 = 0, we have a subentry that does _not_ have the same main entry as the previous line, like the situation

\Entry 10{abracadabra}\\\OODO}

\Page {5}

\Entry 20{acetyl-CoA}{action of}\{\OOD}

\page {32}

As mentioned on page 116 of the IA_N_S-TEX Manual, in some styles this might be printed as

abracadabra, 5

acetyl-CoA, action of, 32

In the default style, we will still print

abracadabra, 5

acetyl-CoA

action of, 32

but we still have to treat the \mark's differently for the cases \(d_{2}=\#2=0\) and \(d_{2}=\#2=1\).

For the case #2 = 0 we want

\if

\check@\relax\relaxrelax\

\noindent

\mark{20{\the\marktoks@i}{\the\marktoks@i}}%

\hangafter1\hangindent=.5em{#3}\par\nobreak

\noindent\hangafter1\hangindent=1.5em\quad{#4}%

Thus:

1. We clear the previous mark (the one for abracadabra).
2. We emit the mark
20{#3}{#4}

[20{acetyl-CoA}{action of}, in the above example]

and then set up the proper format for printing things. If the page breaks in the middle of this entry, then \bothmark will have the value
20{#3}{#4}

and the \output routine will be clued in as to what sort of continuation lines to add.

The other case, when #2 = 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@i}}%

\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 Opt) before this paragraph. If the page breaks at this point, then \bothmark 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 \bothmark 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.

be considered better to break right before an entry than right before a subentry. We might use something like

\check@{\ifletter@\else\penalty-20 \fi}relax

for the case #1 = 1, thereby slightly encouraging a column break before main entries, except those immediately following a \LETTER.

The case \(d_{1}=\#1=3\) begins similarly: When #2 = 0 we use

\ifletter@\else\mark{\}\fi \check@\relax\relax\relax\noindent \mark{30{\the\marktoks@i}\{\the\marktoks@iii}\}\% \hangafter1\hangindent=.5em{#3}\par\nnobreak \noindent@\hangafter1\hangindent=1.5em\quad{#4}\par\nnobreak \noindent@\hangafter1\hangindent=2.5em\quad{#5}\%

and when #2 = 1 we use

\mark{10{\the\marktoks@i}\}\% \check@\relax\relax\relax\noindent@ \mark{31{\the\marktoks@i}\{\the\marktoks@i}\{\the\marktoks@iii}\}\% \hangafter1\hangindent=1.5em\quad{#4}\par\nnobreak \noindent@\hangafter1\hangindent=2.5em\quad{#5}\%

But the case #2 = 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\number\dii}{\the\marktoks@i}\{\the\marktoks@i}\% \check@\relax\relax\noindent@ \mark{32{\the\marktoks@i}\{\the\marktoks@i}\{\the\marktoks@iii}\}\% \hangafter1\hangindent=2.5em\quad{#5}\%









1. 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 324).
2. 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 326).

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 to3Opt{\vskip10pt \hbox to\pagewidth@{\hfill}bf \uppercase}expandafter{\makeindex@W}\hfill}\vfill}% \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@...\hinput@ in a group, so that the \noexpands@ won't interfere with font change instructions in "continuation" lines contributed later (see page 326) by the \output routine. (Compare page 326.)

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:

\def\makeindex@W{Index} \def\combinecolumns@{\% \setbox\outbox@=\vbox\{makeheadline}

#### 38.8 \doublecolumns@ routine, used for all but the last page, we will need a new (dimen) register

The routine begins with

\dimen@=\pageheight@ \iffirstindexpage@ \advance\dimen@ by -3Opt \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 \newcolumn command caused the \output routine to be invoked. Moreprecisely, 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,1 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 '...' 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 510), 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.1

Footnote 1: I.e., when \pageetotal is \pageheight@.

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 \setbox=\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 \vspliting 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@ lor % case 1 (originally 0 or 1)

\setup2=\vsplit255 to\dimen@

\globalprevcoldepth@=\dp2

\or % cases 2 and 3

\global\prevcoldepth@=\dp255 % store the depth first

\setup2=\vbox to\dimen@{\unvbox255

\ifnum\Ctype@=3 \vfill\kern-\prevcoldepth@\vfill\}

\fi

Once we've determined the columns, \box0 and \box2, in this way, we use \combinocolumns@


###### Abstract

The \continuue@routine is followed by at least 7 (possibly empty) arguments,

\def\continue@#1#2#3#4#5#6#7#8\continue@


#### 38.8 \doubllecolumns@

But now we need new glue \(g^{\prime}\) such that

\prevdepth + g' + h = \baselineskip

So we need to add \prevcoldepth@ - \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

\dimen@=\prevcoldepth@ \advance\dimen@ by -\prevdepth \kern\dimen@ because \prevcoldepth@ won't be used any more.)

(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 \(g\) is simply enough to make

\[g + h = \topskip\]

We want glue \(g^{\prime}\) such that

\[g^{\prime} + h + \prevdepth = \baselineskip\]

so we need to add

\baselineskip - \prevdepth - \topskip extra glue.

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

The whole definition is thus

\def\continue@#1#2#3#4#5#6#7#8\continue@{% \def\next@{#1}\ifx\next@\empty


9. \balancedcolumns@ routine basically follows that of page 417 of _The TeXbook_, except that we have to be a little more careful about the final glue (the routine in _The TeX book_ was used for setting _The TeXbook_, 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=\topskipand 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 \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@=\dpd3 \unvbox3  \ifshortlastcolumn@ \kern-\dimen@ \forall\fi}


yak (continued) **Z**

 habitat of, 124

 yam, 124

 zap, 13-18

 z-axis, 12, 256, 300

 yang, 187

 zebra, 121

 y-axis, 89, 845

 zcd, 103, 105

 yclept, 102

 Zen, iii, vi, 122

 yellow, 103

 zenith, 97,103

 zero, 11, 14, 56, 79

 yellow fever, 108

 zero-sum, 118

 Yellow Pages, 223

 zeta(), 133

 yeti, 301

 zilch, _see_ zero

 yin, 186

 zone, 204, 208

 yodel, 224

 Zorn's lemma 112, 145

with the first column Underfull. This is the best vsplit, for if the left column were any bigger it would have to include the **Z** and the space after it, and at least one more line (not to mention all the extra space that would normally go _before_ the **Z**).

If we added a \newcolumn right before the zebra \Entry in the.xdx file (and also specified \shortlastcolumn), the output would look acceptable,

 yak (continued) **zebra, 121**

 habitat of, 124

 zed, 103, 105

 yam, 124

 Zen, iii, vi, 122

 yang, 187

 zenith, 97,103

 y-axis, 89, 345

 zero, 11, 14, 56, 79

 yclept, 102

 zero-sum, 118

 yellow, 108

 zeta(), 133

 yellow fever, 108

 zilch, _see_ zero

 Yellow Pages, 223

 zone, 204, 208

 yeti, 301

 Zorn's lemma 112, 145

 yin, 186

 yodel, 224

 zap, 13-18

 z-axis, 12, 256, 300

 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@).


**Chapter 39. The index program**

The index program takes the raw data in an.ndx file and creates an.xdx file. Specifically, it is invoked as

index (filename)

to operate on (filename).ndx, producing (filename).xdx. Among its many tasks, the index file essentially sorts entries alphabetically. As indicated below, the *a{(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 *a{(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 *a 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.

_39.1. The.ndx file._ The.ndx file may contain certain lines

\define(control sequence)...

that come from \idefine's in the main file, as well as certain lines

\abbrev*(control sequence){...}

that come from \iabbrev's in the main file. Moreover, as explained on

#### The.ndx file

page 113 of the LM_S_-TEX Manual, a sequence of commands of the form

\pageorder\control sequence)\(\{\)pre page material\(\}\)\t(\{\)post page material\(\}\)\t(\{\)order\(\}\)may have been inserted at the very beginning of the.ndx file (after the.ndx file was automatically made by TEX); here each (control sequence) is some numbering style command, and the \order\(\}\)'s are 1, 2, 3,..., in that sequence.

Aside from this, the.ndx file should consist of pairs of lines

\(\{\)entry\(\}\)\(\{\)options\(\}^{\dagger\)\(\{\)number\(\}\)\t(\{\)control sequence\(\}\)\t(\{\)prefix\(\}\)\t(\{\)postfix\(\}\)\(\}\)where \(\{\)number\(\}\) is a decimal number, \(\{\)control sequence\(\}\) 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 \(\{\)control sequence\(\}\) is normally '\arabic\({}_{\sqcup}\)'.

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 10.8) to have something like

\(\{\)entry\(\}\)\(\{\)options\(\}\)\(\}\)\(\{\)\(\{\)number\(\}\)\t(\{\)control sequence\(\}\)\t(\{\)prefix\(\}\)\t(\{\)postfix\(\}\)\(\}\)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

\(\{\)entry\(\}_{1}\)

\(\{\)entry\(\}_{1}\), \(\{\)entry\(\}_{2}\)

\(\{\)entry\(\}_{1}\), \(\{\)entry\(\}_{2}\), \(\{\)entry\(\}_{3}\)

\(\{\)entry\(\}_{1}\), \(\{\)entry\(\}_{2}\), \(\{\)entry\(\}_{3}\), \(\{\)entry\(\}_{4}\)

\(\{\)entry\(\}_{1}\), \(\{\)entry\(\}_{2}\), \(\{\)entry\(\}_{3}\), \(\{\)entry\(\}_{4}\), \(\{\)entry\(\}_{5}\)

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 treatedas 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):

*a{string}} (alphabetize as)
*{n}a{string}} (same for subentry at level (n))
*-{string}} (print before entry)
*{n}-t{string}} (same for subentry at level (n))
*+{string}} (print after entry)
*{n}+{string}} (same for subentry at level (n))
*e(control sequence) (apply control sequence to entry)
*{n}e(control sequence) (same for subentry at level (n))
*p(control sequence) (apply control sequence to page number)
*f (begin page span)
*F (begin page span, variant form)
*t (end page span)
*x{string}} (cross reference as)
*X{string}} (list and cross reference as)

In each

\abbrev*(control sequence){...}

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 *x and *X options are meant to be mutually exclusive, so an error message should be given if both occur in the same (options) list.

### 39.2. The index program

Here now are the steps taken by the index program.

**(I) Preprocessing:**

(1) The index program first uses any pageorder lines at the beginning,

\pageorder{control sequence}1{pre1}{post1}1

\pageorder{control sequence}2{pre2}{post2}2to set up an ordering for arrays of the form

\[\{(number)\}\}\ \ \{(control\ sequence)\}\ \ \ \{(prefix)\}\ \ \{(postfix)\}\]

Namely, all arrays

\[\{(number)\}\}\{(control\ sequence)_{1}\}\{pre_{1}\}\{post_{1}\}\]

come first, with the ordering then determined by the \(\langle\)number\(\rangle\)'s, all arrays

\[\{(number)\}\ \ \{(control\ sequence)_{2}\}\ \ \{pre_{2}\}\ \{post_{2}\}\]

come next,... All other arrays come after these, and are simply ordered first by the order of the \(\langle\)number\(\rangle\), 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*(control\ sequence)\{...\}\]

(which may appear anywhere in the.ndx file).

In each case, any occurrence of *\((control\ sequence)\) 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.

(II) Sorting:

(1) For each

\[{}^{n}\langle\ entry\rangle\langle\options\rangle^{n}\]

line, if *a\(\{\langle\string\rangle\}\) appears, replace \(\langle\entry_{1}\rangle\) by \(\langle\string\rangle\), and define \(\langle\entry_{1}\rangle\) to be the old \(\langle\entry_{1}\rangle\). Otherwise define \(\langle\entry_{1}\rangle\) to be empty.

Similarly, if *\(\langle\nrangle\)a\(\{\langle\string\rangle\}\) appears, replace \(\langle\entry_{n}\rangle\) by \(\langle\string\rangle\), and define \(\langle\entry_{n}\rangle\) to be the old \(\langle\entry_{n}\rangle\). Otherwise define \(\langle\entry_{n}\rangle\) to be empty.

(2) Each pair of lines

"\(\langle\)entry\(\rangle\langle\)options\(\rangle\)"

\(\{\langle\)number\(\rangle\}\{\langle\)control sequence\(\rangle\}\{\langle\)prefix\(\rangle\}\{\langle\)postfix\(\rangle\}\)

now gives rise to a collection \(\mathcal{F}\) of fields:

E1 is \(\langle\)entry\({}_{1}\rangle\) followed by one space.

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

E1- is empty unless **+\(\{\langle\)string\(\rangle\}\) appears, in which case it is \(\langle\)string\(\rangle\) followed by one space.

E2 is \(\langle\)entry\({}_{5}\rangle\) followed by one space (hence just a space if \(\langle\)entry\({}_{5}\rangle\) is empty).

E2- is empty unless *2-\(\{\langle\)string\(\rangle\}\) appears, in which case it is \(\langle\)string\(\rangle\) followed by one space.

E2+ is empty unless *2+\(\{\langle\)string\(\rangle\}\) appears, in which case it is \(\langle\)string\(\rangle\) followed by one space.

E3, E3+, E3-,..., E5, E5+, E5- are similar.

P# is \(\langle\)number\(\rangle\).

Pn is \(\langle\)control sequence\(\rangle\) (usually '\(\langle\)arabic\(\rangle\)').

P- is the \(\langle\)prefix\(\rangle\).

P+ is the \(\langle\)postfix\(\rangle\).

\(\overline{\mathbb{E}}\)1,..., \(\overline{\mathbb{E}}\)5 are \(\langle\)entry\({}_{1}\rangle\),..., \(\langle\)\(\overline{\text{entry}}_{5}\rangle\).

E1c is empty unless **\(\langle\)control sequence\(\rangle\) appears, in which case it is \(\langle\)control sequence\(\rangle\), followed by one space.

E2c is empty unless *2e(control sequence) appears, in which case it is \(\langle\)control sequence\(\rangle\), followed by one space.

E3c, E4c, E5c are similar, using *3e, *4e and *5e.

Pc is empty unless *p\(\langle\)control sequence\(\rangle\) appears, in which case it is \(\langle\)control sequence\(\rangle\), followed by one space.

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

x is empty unless **x\(\{\langle\)string\(\rangle\}\) appears, in which case it is \(\langle\)string\(\rangle\), followed by one space.

X is empty unless *X\(\{\langle\)string\(\rangle\}\) appears, in which case it is \(\langle\)string\(\rangle\), followed by one space.

(3) We first sort these collections \(\mathcal{F}\) alphabetically on E1, then among those with identical E1 on E1-, then on E1+, then on E2,..., E5+. If we ignore the - and + fields for the moment, this just alphabetizes the entries and subentries. The spaces that were added after each \(\langle\)entry\({}_{n}\rangle\) are meant to ensure that these entries are really sorted alphabetically; for example, it produces the order

 Time

 Time table

 Times tables

 which will eventually appear in the index as

 Time

 table

 Tables

 Times

 tables

 The other fields, E1-, E1+,..., allow entries with additional elements to appear in the proper order. For example, for the entry

 "Time *-{''} **{''}"

 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

 Time

 "Time"

 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 (I).

There may be certain collections \(\mathcal{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 E1,...,E5, E1c,..., 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.

**(III) Writing the.xdx file:**

(1) First, as indicated in step (3) of part (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 \LETTER! can appear if entries begin with! (though normally one would expect the *a option to be used for such entries).

(2) In most cases, each collection \(\mathcal{F}\) gives rise to a pair of lines in the.xdx file:

\Entry \(d_{1}d_{2}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\)\(\{\ldots\}\)\(\{\ldots\}\)\(\{\ldots\}\)\(\{\ldots\}\)\(\{\ldots\}\)

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.

#### The index program

For the first {...} in the \Entry line, '...' is

{E1-}{E1c{E1}}-{E1+} except that E1 is replaced by \(\overline{\rm E}1\) if this is non-empty.

Note that there are braces around E1 (or \(\overline{\rm E}1\)) 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.

\(d_{1}\) is the number of {...} that are non-empty, i.e., not of the form {}.

\(d_{2}\) is the number of {...}_that agree with the most recent \Entry line_.

Normally, the \Page lines have the form

\Page {Pc{{P-}{Pn{P#}}{P+}}} But Pn is omitted when it is '\arabic_i' (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

\% /////////////// /////////////// /////////////// % \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).


#### The index program

Case 1: Every occurrence of the \(\left\langle\text{entry}\right\rangle\) involves **x** (and thus not **X**):

\(\left\langle\text{entry}\right\rangle\)... **x{\(\left\langle\text{string}_{1}\right\rangle\)}**

\(\left\langle\text{entry}\right\rangle\)... **x{\(\left\langle\text{string}_{5}\right\rangle\)}**

\(\left\langle\text{entry}\right\rangle\)... **x{\(\left\langle\text{string}_{8}\right\rangle\)}**

In this case the.xdx file should contain

\Entryxref \(d_{1}d_{2}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\{\ldots\}\{ \left\langle\text{See \{\{\left\langle\text{string}_{1}\right\rangle\}}}\right\rangle\}\)

\Morexref \{\(\left\langle\text{See \{\{\left\langle\text{string}_{5}\right\rangle\}}}\right\rangle\)}

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

(1) \(\left\langle\text{entry}\right\rangle\) occurs at least once with the **X** option, so that the corresponding page number should appear. Other occurrences of \(\left\langle\text{entry}\right\rangle\) may or may not have **x** options.

(2) \(\left\langle\text{entry}\right\rangle\) occurs at least once with _neither_ **x** nor **X**, and thus there is at least one page number that should appear because no cross-referencing is involved at all. Other occurrences of \(\left\langle\text{entry}\right\rangle\) may have either **x** or **X** options.

In these cases, let \(\left\langle\text{string}_{1}\right\rangle\), \(\left\langle\text{strings}_{5}\right\rangle\),..., be all the \(\left\langle\text{string}\right\rangle\)'s, in alphabetical order, that occur in either **x** or **X** options, and let

\Page \(\{\ldots\}\)

\Page \(\{\ldots\}\)

\Page \(\{\ldots\}\)

be the lines that would be written considering all instances that do not involve the **x** option (but possibly the **X** option). These lines may actually involve \Pagespan, \PageSpan and \Topage.

Then the.xdx file should contain\Entry \(d_{\_}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\{\_\_\}\}\) \(\backslash\)Xref \(\{\backslash\)See \(\{\langle\)string\({}_{1}\rangle\}\}\) \(\backslash\)Morexref \(\{\backslash\)See \(\{\langle\)string\({}_{5}\rangle\}\}\)_Part VII_

_The Style Files_* [15]


### Chapter 40. The paper style

The file paper.st begins

\catcode'\@=11

to allow us to access and create private control sequences, followed by

\ifx\paperst@relax\catcode'\@=\active \endinput\else\let\paperst@=\relax\fi

which prevents paper.st from being read in twice (compare section 1.2), a necessity because of the \NameHL commands that occur later (we can't \NameHL1\heading twice, since that involves \define\heading twice). Then we have

\let\alloc@=\alloc@\

so that we can create new counters, etc., without having them written to the.log file (compare page 38).

### 40.1. Basic settings

Next we set basic parameters that differ from the default style:

\hsize=30pc

\rsize=42pc

\parindent=item

\normallineskiplimit=1pt

\advance\hoffset 48pt

\advance\voffset 78pt

\hoffset and \voffset are changed to center these small pages within an 84% x 11 inch piece of paper.


}ifcmbsyloaded@ \font@\eightcmbsy=cmbsy8\skewchar\eightcmbsy='60 \font@\sixcmbsy=cmbsy6\skewchar\sixcmbsy='60 \fi ```
(If even more crazy families are to be loaded, like eufb, eusm, eusb, eurm, eurb, further clauses will have to be added, but I couldn't bear including them.)

Now we want to define \tenpoint and \eightpoint, following the basic scheme used in Appendix E of _The TeXbook_. For literal mode, we will want spaces to give different amounts of glue in the two different point sizes, so we first declare a new glue register,
``` \newskip\ttglue@ ```
A few macros need to know what point size is currently used, so this information is kept in a control sequence \pointsize@. Thus, the definition of \tenpoint will be of the form:
``` \def\tenpoint{\def\pointsize@{10}% } ```
After \pointsize@ is defined, \normalbaselineskip is set to 12pt (at the end of the definition, \normalbaselines will be stated, which actually sets \baselineskip to this value); on the other hand, \normallineskip and \normallineskiplimit will each have the value 1pt for both 10 point and 8 point type.

Then values of \abovedisplayskip,..., for the spacing above and below displayed formulas are set.

Next we use
``` \textonlyfont@\rm\tenrm \textonlyfont@\bf\tenbf ```


Before ending, however, we have to set \box\strutbox, which determines struts,

\setbox\strutbox=\hbox{\vrule\height8.5pt\depth3.5pt\widthOpt} as well as \strutbox@, which \(\mathcal{A}\mathcal{B}\mathcal{S}\)-TEX uses for its special math struts,

\setbox\strutbox@=\hbox{\vrule\height8pt\depth3pt\widthOpt} We also set the \(\mathcal{A}\mathcal{B}\mathcal{S}\)-TEX dimen

\ex@=.2326ex

(as explained in amstex.doc, I don't remember why this value is chosen!). And then the definition of \tenpoint ends with

\normalbaselines so that we have set \baselineskip, etc., to their "normal" values, and then

\ifmmode\else\rm\fi to switch to \rm; the \ifmmode test is required in case a construction like

\itempoint... $$

is used, since \rm will give an error message in math model

After the definition of \tenpoint, we still have to give the definition

\def\tenbig@#1{\hbox{\$}left#1\vbox to8.5pt\right.\hbox{\#} and then we can switch to \tenpoint:

\tenpoint

### 40.2. Fonts and point sizes

NOTICE that we must not say \tenpoint until \tenbig@ has been defined, or \big will initially be undefined.

The definition of \eightpoint is exactly analogous, and followed by the definition

\def\eightbig@#1{{\hbor{$}\textfont0=\ninerm\textfont2=\ninesy\left#1\vboxto6.5pt{}\right.\n@space$}}}

which is where \ninerm and \ninesy get used; then, for example, \big( in \tenpoint selects the \ninerm (.

Then we use

\catcode' =\active\gdef\litcodes@@{\def\allowbreak\hskip\tt{ttglue@}}}

so that if literal mode is used within \tenpoint or \eightpoint, the active space will have the desired width.

With the fonts now declared, we can properly print the \(\LMS\)-TEX logo; for best effects somewhat different choices are required at different point sizes:

\def\LamSTeX[\L\kern-.4em\raise.3ex\hbox\{\$\ssize\|Cal\&\}%

\def\next@{10}\lifx\next@\pointsize@@

\kern-.25em\else\kern-.3em\fi\lower.4ex\hbox\{\def\next@{10}\lifx\next@\pointsize@@

\eightsy\else\exists\forall iM\%

\kern-.1em\{\$\Cal\&\}-\{\text{Tex}\}

Although \claimformat is supposed to be the same as in the default style, most people don't have an 8 point "caps and small caps" font, so \tenpoint and \eightpoint don't define \smc, which simply has the default lamstex.tex meaning of \tensmc (choosing the font cmcsc10). So we substitute \rm\uppercase instead:

\def\claimformat@@#1#2#3{\medbreak\noindent@@

\def\next@{8}\ifx\pointsize@@next@

\rm\uppercase{#1 {\claim@@@@F\#2} #3}%

\punct@@{\null.}\addspace@\enspace}else {\smc#1{\claim@@@F#2}#3\punct@{\null.}% \addspace@\enspace \fi \sl} ```
Finally, since we have the smaller \eightpoint fonts, we might as well use them in the \windex@ routine for printing index entries at the right margin, for proofing; we change the strut so that it gives only 10pt between lines.
``` \def\windex@{\ifindexing@ \expandafter\unmacroof\meaning\stari@\unmacro@ \edef\macroof\string"\macdef@\string"\"\% \edef\next@\write\ndx@{\macdef@}\next@ \write\ndx@{\number\pageno}{\page@N}{\page@P}{\page@Q}}% \fi \ifindexproofing@ \ifx\stariii@\empty\else \expandafter\unmacroof\meaning\stariii@\unmacroof\fi \insert\margin@{\hbox{\eightpoint \vvruleheight7\vp@\depth3\vp@\width\v2@\v\starii@ \ifx\stariii@\empty\else\tt\macdef@\fi}\}\{\ii} ```
### The.toc levels

Since paper.st has so many different heading levels,
``` \HL1_alias_\chapter \h11_alias_\section \h12_alias_\subsection \h13_alias_\topic \h14_alias_\subtopic ```

we want to allow \toclevel to indicate how many levels should be written to the.toc file: \toclevel1 should indicate that only \chapter's are written, \toclevel2 that \chapter's and \section's are written, etc. We might as well allow \toclevel0 to mean nothing is written (although then it was fairly silly to specify \tocfile to begin with).

### 40.4. Setting up heading levels

We do this in terms of a counter \toclevel@, initially with the value 3 (so that \chapter's, \section's and \subsection's--the only numbered heading levels in this style--are written):

\newcount\toclevel@ \toclevel@=3 \def\toclevel@1\toclevel@=#1\relax\

To get this to work, we have to restate the definitions of \Hltoc@ and \hltoc@ from lamster.tex. The only difference in the definition of \Hltoc@ is that we don't do anything if \toclevel@ is less than 1:

\def\Hltoc@\% \iftoc@ \ifnum\toclevel@ < 1 \else \(\old code for \Hltoc) \fi \fi \fi \

Similarly, \hltoc@ only writes to the.toc file when \hltlevel is less than \toclevel@ (so if \toclevel@ is 1, no \hlt is written, if \toclevel@ is 2, only \hll is written, etc., as desired):

\def\hltoc@\% \iftoc@ \ifnum\hillevel@ < \toclevel@ \(\old code for \hltoc@) \fi \fi \fi

### 40.4. Setting up heading levels

Next we have to set up the heading levels. As mentioned on page 217, we want to make sure that the basic \NameHL's in this style file don't write information to the.toc file even if \tocfile has been specified before the \docstyle line. So we define}def\notocwrite@#1#2#3{\iftoc@\test@true\else\test@false\fi \toc@false#1{#2}#3\iftest@\toc@true\fi} For example,

```
```
```

```
```
```

```
```
```

```
```
```

```
```
```

```
```
```

```
```
```

```
```
```

First stores the value of \iftoc@ in \iftest@, declares \tocfalso@, calls \NameHL1\heading, and restores \toc@true if \iftoc@ was initially true. The \NameHL and \Namehl constructions don't involve \iftest@, so this is safe. (The definition of \notocwrite@encloses argument #2 in braces in case we have something like \NameHL{i0}....)

Next we state

```
\newfontstyle\heading{\smc}
```

Thus, \HL1, _alias_heading, has numbers set in \smc (which will also be used for the heading title, in the definitions to follow).

One additional feature of the paper style is that a \subsection (\hl12) is only allowed within a \section (\hl1), not directly within a \heading. So we need a flag

```
\newififinsection@
```

which \heading will set false and \section will set true. Aside from this, \heading is handled by defining \HL@1' almost exactly as in the default style,

``` \expandafter\def\csnameHL@1\endcsname#1\endHL{% \global\insection@false \biggreak\medskip \locallabel@ \global\setbox1=\vbox{\Let@\tabskip\hss@ \halignto\size{\smc}\hfil\ignorespaces%%\unskip\hfil\cr \expandafter\ifx\csnameHL@W1\endcsname\empty\else \csnameHL@W1\endcsname\space\fi \endcsname\space\40.4. Setting up heading levels

{\hL@@F\ifx\thelabel@@\empty\else\thelabel@@\space\fi\% \ignorespaces@i\crcr})}% \unvbox1 \nobreak\nodskip}

merely adding some extra space before the heading, and setting the heading in \smc.

One of the interesting features of the paper style is the definition

\def\appendices\% \NameHL1\appendix \Reset\appendix1% \nennumstyle\appendix\Alph \nenword\appendix\Appendix\% \} This means that after \appendices has appeared, \appendix may be used (and \heading may no longer be used--compare page 218); the new headings created by \appendix will be numbered 'A', 'B',..., and the headings will now say 'Appendix A...', etc.

Notice that when \appendices is used, \NameHL1\appendix _will_ be written to the.toc file. As we will see in section 8, this will enable \maketoc to properly process any \appendix lines that appear afterwards.

Next we have

\notocwrite@\Namehl1\section \nenwstyle\section#1{#1\null.}

so that \section can be used for \h11; in addition, we now have a period printed after the \section number (the default style omits the period).

Although each \heading normally resets \section numbers to 1 (this will be handled by '\HL@I1', to be defined shortly), we will allow

\keepsection

analogous to \keepitem, to be typed before \heading, to prevent this. \keepsection will merely set a flag * \newifififcontinunesction@ \def\keepsection{\global\continuesection@true} which each \section should set false (with this arrangement, if \keepsection is typed before a \heading with no \section's, then it carries over to the next \heading). The definition of \section, via \h1@1', also sets \ifinsection@ to be true, and the formatting is somewhat different from the default style: instead of running the \section title into the text, we start a new paragraph, after a \smallskip: \expandafter\def\csnamehl@1\endcsname#1{\global\insection@true \global\continuesection@false \medbreak\noindent@@@ \{\locallabel@ \ bf{\h1@er\ifx\thelabel@@\empty\else\thelabel@\space\%i}\% \ignorespaces#1\unskip\punct@{\null.}\}\W \par\nobreak\smallskip} ```
For \h12, eventually to be named \subsection, we must first declare counters and default values:
``` \expandafter\newcount\csnamehl@C2\endcsname \csnamehl@C2\endcsname=0 \expandafter\def\csnamehl@S2\endcsname#1{\#1\null.} \expandafter\let\csnamehl@N2\endcsname=\arabic \expandafter\let\csnamehl@P2\endcsname=\empty \expandafter\let\csnamehl@Q2\endcsname=\empty \expandafter\def\csnamehl@F2\endcsname{\bf} \expandafter\let\csnamehl@W2\endcsname=\empty ```
Then we can
``` \notocwrite@\Namehl2\subsection


)
550 _Chapter 40. The paper style_

 {locallabel@  {}b\ignorespaces#1\unskip}punct@{\null.}%  {addspace@\enspace}}

while \subtocic, defined via '\h1@4', starts as an ordinary paragraph:

\expandafter\def\csnamehl@4\endcsname#1{%  \smallbreak  {\locallabel@\bf\ignorespaces#1\unskip  \punct@{\null.}}addspace@\enspace}}

The initializations are fairly simple:

\expandafter\def\csnameHL@I1\endcsname{\ifcontinuesection@  \else\Reset\h11\f\ expandafter\def\csnamehl@I1\endcsname{\Reset\h121%  \if\pref\empty\newpre\h12\else\new\h12\pref.}\{\right\}  \expandafter\def\csnamehl@I2\endcsname{\Reset\h131}  \expandafter\def\csnamehl@I3\endcsname{\Reset\h141}

Thus, \section numbers are reset to 1 after each \heading, unless \keepsection preceded it; \subsection numbers are reset to 1 at each \section, and the \nth subsection number is printed as _m.n_, where \(m\) is the \section number, unless empty (because of a \section\" command); and \subsection resets \topic numbers to 1, while \topic resets \subtopic numbers to 1, even though these numbers aren't printed (they can still be referred to by \nref, if the \topic or \subtopic is given a \label).

### Footnotes

The definition of \vfootnote@ is modified so that the footnotes will be printed in 8 point type:

\def\vfootnote@#1{\insert\footins  \bgroup  \floatingpenalty2000  \interlinepenalty=\interfootnotelinepenalty}leftskip=Opt \rightskip=Opt \spaceskip=Opt \xspaceskip=Opt \rightpoint{splittopskip=ht\strutbox \splitmaxdepth=\dp\strutbox \locallabel@)\nondent@@{foottext@#1}\modifyfootnote@ \footstrut\futurelet\next\foo\} Note that the \strutbox will now have the value set by \eightpoint.

#### 40.6 Additional "top matter" and "end matter" constructions

In addition to \title, \author, \affil, and \date, which already appear in the default style, the paper style also has several other constructions that go at the beginning of the paper, and a few that go at the end.

For \abstract...\endabstract, as for \title and \author, we declare a box

\newbox\abstractbox@

to hold the abstract. Because we are printing a word 'Abstract' at the beginning, followed by punctuation and spacing, we then

\rightadd@\abstract\to\norfillslist@ \def\abstract@W\abstract\

The \box\abstractbox@ is going to be set with

\leftskip=24pt \rightskip=\leftskip=\leftskip

rather than as a \vbox with smaller \hsize, so that we can simply \unvbox it at the proper time, instead of having to include it in \centerline, and worrying about spacing before and after it. We will increase the \tolerance to 800 for these smaller lines.

Unfortunately, these values of \leftskip and \rightskip _do not_ influence \displaywidth and \displayindent, which determine the positioning of displayed formulas within the \abstract; the latter are influenced only by \parshape--see _The TeXbook_, page 188. Moreover, we can't simply assign them the desired values, because, as explained on that page, TeX assigns them values immediately after the \$\$ that begins a display, based on the value 


\long\def\address#1{\global\advance\addresscount@by1 \expandafter\gdef \csnameaddress\number\addresscount@\endcsname {\ignorespaces#1}}} ```
Since \keywords, \subjclass, and \address's are printed at the end of the paper in the paper style, we redefine \bye to include this material before adding the \vfill\superject\end:
``` \def\bye{\par \nobreak \vskip12ptminus6pt \eightpoint \ifx\keywords@\relax\else \noindent@@{\itKeywords.\enspace}\keywords@\par\fi \ifx\subjclass@\relax\else \noindent@@emptyset1980 {\itMathematicssubject classifications\/\}\\\\colon@\space\subjclass@\par\fi \ifnum\addresscount@>0 \nobreak \vskip12ptminus6pt \loop\ifnum\addresscount@>0 \csnameaddress\number\addresscount@\endcsname\endgraf \global\advance\addresscount@ by -1 \repeat \fi \vfill\superject \end} ```

Notice that instead of a : we used \colon@ (page 162). No \keywords@W or \subjclass@W has been provided, to change 'Keywords' or 'Mathematics subject classifications', since those are presumably somewhat standard terms; but they could easily be added if needed. In the \loop for the \address's, we needed \endgraf instead of \par, since \loop isn't \long.

And then we make \enddocument synonymous with this new \bye:




### 40.8. \maketoc

Then the definition of \maketoc starts

 \def\maketoc{\par  \begingroup  \eightpoint \tolerance=800  \unlabel@\noset@  \let\nopunct=\relax \let\nospace=\relax  \let\overlong=\relax  \everypar=\\parindent=Opt  \lineskiplimit=Opt  The \checkmainfile@ in the lamstex.stf definition is naturally deleted, and the \par\forallbreak is replaced by a \par. We use \begingroup, because we will be making redefinitions of \HL, etc., and the old definitions will have to be restored after the table of contents is finished; and the \lineskiplimit=Opt, which is so important for the entries of the table of contents (compare section 37.2), will also be confined to this group.

And then come the various redefinitions that also occur in \maketoc in lamstex.stf:

 \def\HL...  \setbox0=\hbox{0.00}  \digits=\wd0  \def\h1...  \def\NameHL...  \def\Namehl...  The definitions of \HL and \hl are somewhat different, reflecting both the larger number of heading levels, and somewhat different formatting in the table of contents. Then we have to add

 \NameHL1\heading \Namehl1\section \Namehl2\subsection  \Namehl3\topic \Namehl4\subtopic so that \heading,..., \subtopic will be suitably redefined while making the table of contents. Naturally we can't add \NameHL1\nopendix at the same time, but \appendices will add this to the.toc file, so that \appendix will be suitably redefined at the necessary time when printing the Contents.

Finally, we print the properly centered heading, diminish \hsize by 24 points, (so that the right margin will match that of the \abstract), \input the file \jobname.toc, end the group, and add some vertical space:

\centerline{\smc\maketoc\}

\nobreak

\vskip18pt plus12pt minus6pt

\advance\hsize by -24pt

\input \jobname.toc

\endgroup

\vskip 12pt plus8pt minus4pt

The definitions involving \island's from lamstex.stf are not needed, since paper.st does not print a list of Figures, Tables, etc., even when a table of contents is made.

And nothing from lamstex.stb is required, since paper.st does not provide for an index.



#### 41.5. \part and \chapter

(using the \par\vfill\superject that occurs in the definition of \bye). Unfortunately, that may not be sufficient when we have a situation like

\Aplace{...}

\chapter

because the \Aplace'd material may not get printed until after the remaining aspects of \chapter have already set things up for preparing pages for this next \chapter. For example, flushed out figures from Chapter 9 might end up having heading levels saying 'Chapter 10...'!--which is even worse than having extra blank pages.

Therefore \part and \chapter will, in all situations, use something like

\par\vfill\break\null\kern-\topskip\nobreak\vfill\superject (\)(essentially the construction that appears in the plain definition of \dosuperject), so that we can be sure that any held-over figures are flushed out before the remaining aspects of \chapter are brought into play. The problem with this approach is that a blank page will now be produced when there are no figures to be flushed out. However, we will take care of that problem later, during the \output routine. We will need a flag

\newif\if\if\flush\@

to indicate such special pages, and then we define

\def\flush@{\par\vfill\break\null\kern-\topskip\nobreak\global\Sflush@true\vfill\superject}

5. \part and \chapter. The book style has a new heading level \HL0, _alias_ part. We will need a new font for setting it,

\font\BF=cmbx10 scaled \magnstep3

and then we set up things for \HL0:562 _Chapter 41. The book style_

\expandafter\newcount\csnameHL@CO\endcsname \csnameHL@CO\endcsname=0 \expandafter\def\csnameHL@SO\endcsname#1{#11/} \expandafter\let\csnameHL@NO\endcsname=\Roman \expandafter\let\csnameHL@PO\endcsname=\empty \expandafter\let\csnameHL@QQ\endcsname=\empty \expandafter\def\csnameHL@FO\endcsname{\BF} \expandafter\def\csnameHL@WO\endcsname{Part}

So \HLO levels will be numbered I, II,.... The word preceding the number will actually be 'PART' rather than 'Part', but we will use \uppercase for this, rather than defining '\HLOWO' as PART, so that Part will appear in the.toc file; this allows the style file for the front matter to print things differently, if desired.

Once these definitions have been made, we can then \NameHL@O\part (see page 215). As with the paper style, however, we need to have

\def\nnotocwrite@#1#2#3{\iftoc@\test@true\else\test@false\fi \toc@false#1{#2}#3\iftest@\toc@true\{\fi}

so that we can

\nnotocwrite@\NameHL@\part

We introduce a new flag

\newif\ifpart@

since \part pages will be special (they will have no number at the bottom and also no running head). Then we define \part, via '\HLO', which involves quite a few tricky maneuvers.

Our definition of \csnameHL@O\endcsname begins with

\flush@ \global\part@true \ifodd\pageno\else\advancepageno\fiwhere the \flush(section 4) flushes out any figures remaining from the previous \chapter, and the third clause insures that \part's always begin on odd-numbered pages.

And then we want something like

{\locallabel@ \global\setbox{\Let@ \baselineskip=21pt \halign{\BF\ignorespaces4##\unskip\hfillcr \expandafter\ifx\csname HL@W0\endcsname}empty \else\csname HL@W0\endcsname\space\space\fi {\HLE@F\thelabel@\}\cr \noalign{\vskip30pt\% \uppercase{\ignorespaces4##\cr\}}}

printing something like 'PART II' on the first line, an extra 30 points of vertical space, and then the title #1 in uppercase letters.

But we want to eliminate the first line and the extra 30 points if both the (word) and the number happen to be empty. Moreover,

\uppercase{\csname HL@W0\endcsname}

won't uppercase the letters in \csname HL@W0\endcsname, and even

\uppercase\expandafter{\csname HL@W0\endcsname}

won't do the trick, so we need to resort to a strategy used before (compare pages 218 and 223),

\expandafter\def\csname HL@0\endcsname#1\endHL{% \flush@ \global\part@true \ifodd\pagno\else\advancepagno\fi {\locallabel@ \global\setbox{\Let@ \baselineskip=21pt \halign{\BF\ignorespaces4##\unskip\hfill}cr}


We need the new flag \diffirstchapterpage@, because initial pages of chapters will be treated specially, with no running heads, and page numbers at the bottom. As with the paper style, we also have the flag

\newif\ifinsection@

Even-numbered pages will normally have the \chapter title at the top. However, we will allow

\runningchapter{...}

to be used before \chapter to specify a different running chapter (this change from version 1, where \runningchapter was supposed to occur after the \chapter, makes things much easier). We need a new flag to alert \chapter to the fact that \runningchapter has been used; the argument of \runningchapter will be stored in a token list, for reasons that will soon become apparent:

\newif\ifrunningchapter@

\newtoks\runningchaptertoks@

\def\runningchapter#1{\global\runningchapter@true

\runningchaptertoks@={#1}}

The running heads at the top of odd-numbered pages will normally contain the most recent \section title, an arrangement that will require the use of \mark's, except that we will use the \chapter title if no \section has appeared. \chapter is going to start a new page, issue an empty \mark{}, to clear \mark's from the previous \section's, and then define \thechapter@ to be the desired running head on even-numbered pages.

Just in case there are pages before a \chapter, we begin with

\let\thechapter@=\relax

We then define \chapter, via '\HL@1', by expandafter\def\csnameHL@1\endcsname#1\endHL-% \flush@ \global\insection@false \ifrunningchapter@\else\runningchaptertoks@={#1}\fi \global\runningchapter@false \noexpands@ \xdef\thechapter@{\ifx\Thepref@\empty\else \Thepref@null.\f\f\the\runningchaptertoks@}\% \global\firstchapterpage@true \locallabel@ \global\setbox1=\vbox\Let@\tabskip\hss@ \halign\to\hsize\{\bf\hfil\hfil\ignorespaces##\unskip\hfil\hfil\cr\expandafter\ifx\csnameHL@W\1\endcsname\empty\else \csnameHL@W\1\endcsname\space\getfi \{\hHL@OF\ifx\thelabel@@\empty\else\thlabel@@\space\{\fi\}\% \ignorespaces#1\crcr}\% \unvbox1\mark\{\% \nobreak\vskip\baselineskip \%firstparflush@ \} Note that:

(1) As with '\HL@0,' we need to flush out any figures from the previous \chapter.

(2) The tokens #1 are stored in the token list \runningchaptertoks@, unless \runningchapter has already been used, and has thus already stored something in \runningchaptertoks@. After this decision for \runningchaptertoks@ has been made, we can reset the flag \frunningchaptertoks@ to be false.

(3) Then \thechapter@ is created by an \xdef, inside a group containing \noexpands@, so that appropriate control sequences in \Thepref@ are left alone. Even though we have an \xdef, our chapter title (or abbreviated title, specified by \runningchapter) appears as originally typed, since it is the value of \the\runningchaptertoks@--thus, we do not have to worry about expansion of control sequences in \thechapter@, and do not have to resort 

#### 41.5. \part and \chapter

to the \unmacro@meaning trick (this works because \thechapter@ is not going to be written to a file, but merely typeset at the appropriate time).

(4) At the very end of the definition the line

\firstparflush@

is designed to start the next paragraph unintended; it has been commented out, since it is not used in the book style, but other book styles might want to use it.

The definition of \firstparflush@, for those styles that want it, is given immediately afterwards:

\def\firstparflush@{\partindent=Opt\everypar{\global\parindent=ipt\global\everypar{\}}}

Thus, the first paragraph will be set with \parindent equal to Opt, but this paragraph will set \everypar, for all successive paragraphs, to

\global\parindent=1Opt\global\everypar{\}

This means that \parindent will be 1Opt for the second paragraph, and, moreover, \everypar will be back to the empty list for the third paragraph. The \global's are needed because a paragraph might start with something like

\(\left\{\lit Consequently\right\}\), we see that...

Having defined \part and \chapter, which set special flags \ifpart@ and \firstcharperpage@, we also define \footline, which uses them, printing nothing at the bottom of \part pages, but a centered page number, in 9 point type at the bottom of the first page of each chapter. In essence we want

\nininpoint\folio

except that there is no \nininpoint command, merely \ninerm to switch to the 9 point roman font. So we have to use568

_Chapter 41. The book style_

\footline={\ifpart@\hfil \else \iffirstchapterpage@\hfil \ninerm\page@S{\page@P\page@N{\number\page@C}\page@Q}\hfil \fi \global\firstchapterpage@false \fi}

--thus, \newfontstyle\page won't effect the page numbers at the bottom of initial chapter pages.

At this point we also want to prevent any \Aplace'd material from occurring on the first page of each \chapter, by modifying \advancedimtopins@, as indicated on page 402:

\def\advancedimtopins@{\iffirstchapterpage@ \else \advance\dimen@ by \dimen\topins \global\dimen\topins=\dimen@ \fi}

#### 41.6. \plainoutput

The \part and \chapter heading levels are the only ones that flush out figures, so now is the time to consider the necessary modifications to \plainoutput, as already indicated in section 4.

We are going to need a new flag and a new box,

\newfont\topinsbox@

and also a counter in which we store the special penalty

-1073741824 (= -'10000000000) that TEX inserts when it sees \end (page 462):

### 41.6. \plainoutput

\newcount\endpenalty@

\endpenalty@=-'1000000000000

Most of our extra manipulations will be done only when \ifflush@ is true. However, we will also be doing extra manipulations when \iffSlush@ is true and \insertpenalties is 0 (which is when the additional

\null\kern-\topskip\nobreak\forallfill

will create a blank page). So we first use

\test@false \ifflush@\test@true \else\iffSlush@\global\Sflush@false \ifnum\insertpenalties=0 \test@true\fi \ifl\fi

to set \iftest@ true in either of these cases, and reset \ifSlush@ to false.

Then, if this test is passed, we first test if \boxlfootins is void and also \boxltopins is void or has height Opt; and if that test is true, we then use the code on page 464 to test whether box255 is essentially blank, reducing the page number by 1, and setting \ifblankpage@ true, if it is:

\def\plainoutput\\test@false \iffflush@\test@true \else\iffSlush@\global\Sflush@false \ifnum\insertpenalties=0 \test@true\fi \ifl\iftest@false \ifvoid\footins \ifvoid\footins \else\iffdim\htt\topins=Opt\test@true \ifl\fi


### 41.6. \plainoutput

This seems to work fine at the end of all \chapter's except when there are figures to be flushed out at the end of the last \chapter, before the \bye or \enddocument. In that case, after each round of the \output routine, which now increases \deadcycles by 1, since nothing is shipped out, TeX keeps adding

\line{} \vill\penalty -''10000000000 so that we eventually get an error message like

! Output loop---25 consecutive dead cycles.

Page 264 of _The TeXbook_ says "When TeX sees an \end command, it terminates the job only if the main vertical list has been entirely output and if \deadcycles=0. Otherwise it inserts the equivalent of

\line{} \vill\penalty-''10000000000 into the main vertical list, and prepares to read the '\end' token again." Apparently, the main vertical list has not been "entirely output" because \box\topins hasn't been shipped out. Emptying out \box\topins with something like

\setupox0=\box\topins doesn't seem to help, so I resorted to

\ifblankpage@ \ifnum\outputpenalty=\endpenalty@ \shipout\vbox{\hrule\width\heightOpt\box\topins}% \fi \global\blankpage@false \else \shipout@\box\outbox@ \fi which seems to work--the only adverse side-effect is the possibility of extra, totally blank, pages at the end.



I originally had simply

\ifblankpage@else

\setupoutbox=\vbox{\makeheadline

\pagebody\makefootline}

\fi

But this lead to the dead cycles error message, though I don't understand why.

Since the extra test in \plainoutput always regards a "blank" page as a mistake, actual blank pages can't be produced with something like

\newpage\null\vfill\break or \pagebreak\null\vfill\break

but we can use something like

\newpage\blankpage

where we have defined

\def\blankpage{\null\null\vfill\break}

just in case that's needed. [Of course

\Aplace{\Figure\Hypv{\...}endFigure}

possibly with a \caption, would be used if a blank page were required for a picture, the most usual reason for such a request. Also,

\NoFlushedFigs

\newpage\null\vfill\break

would work.]

#### 4.1.7 Other heading levels

\appendices is treated exactly as in the paper style, so we won't repeat the definition here.

Next we have 
#### Other heading levels?

\nnotocwrite@Namehl1\section

\nnewstyle\section#1{#1\null.}

as in the paper style.

The running heads at the top of odd-numbered pages will normally contain the most recent \section title, except that we will use the \chapter title if no \section has yet appeared. We also want to allow \runningsection to be used before \section (again a change from version 1), which is treated just like \runningchapter:

\newif\firunningsection@

\newtoks\runningssection\def\runningsection#1{\global\runningsection@true \runningsectiontoks@{#1}}

In the definition of \section, via \hl@1', instead of defining \thechapter@, we need to make an appropriate \mark; since \mark's are expanded, this requires a little more care, using now familiar tricks:

\noexpands@

\nedef\next@\toks@={\ifx\Thepref@\empty\else

\Thepref@\null. \fi

\the\runningsectiontoks@}}%

\next@

\mark{\the\toks@}}

Here the \nedef\next@ makes \next@ mean

\toks@=(\sectionnumber). \section title)

so that \next@ actually assigns \toks@ that value, and then

\mark{\the\toks@}

produces the \mark, with no further expansions. The whole definition is 




/newnumstyle\page\roman

and then loads the same fonts as book.st, and defines \tenpoint and \eightpoint as in that file.

Two new fonts

\font\BF=cmbx10 scaled \magstep1

\font\BF=cmbx10 scaled \magstep3

are also loaded; \BF is used for the 'CONTENTS' headings, etc., while \BF is used for the Part entries in the table of contents (Chapter entries will be printed in ordinary \bf and other heading level entries in \rm).

Pages with \BF headings are handled specially, with no running heads, and page numbers at the bottom, and we have the flag

\newif\ifspecialpage@

to indicate such pages.

The material for running heads will be stored in \headline@, initialized by

\let\headline@=\relax

The \makepiece command is supplied for special pieces like a Preface:.

\def\makepiece#1{\par\rfill}break

\global\specialpage@true

\gdef\headline@\signorespaces#1\unskip}%

\centerline\BF\uppercase{\signorespaces#1\unskip}%

\vskip30pt plus10pt minus10ptpt minus10ptpt

The argument #1 is stored in \headline@, which will be used in the running heads of this piece, except for the first page. Here we assume that the heading fits on a single line. A variant

\makepiece#1\endmakepiececommand, allowing \\ to indicate line breaks, could be specified in an obvious way. If this were allowed, then there should probably be a

\runningpiece

command to specify a shortened form for the running heads. This would work like the \runningchapter command.

As with paper.st, for \maketoc we now how to include many of the definitions from lamstex.stf:

\def\dotleaders... \def\Page@... \long\def\widerthanhsize@... \long\def\setentry@... \def\endstrut@... \newdimenUthehang@ \long\def\longentry@... \newififemptynumber@ \def\Style@... \def\Style@... \def\Style@... \digits isn't used, because the \hl entries are set differently.

Because the \Style@... \Style@000 complex involves \style, which will be set to \HL@S or \hl@S, we need to provide definitions for all cases that will occur:

\expandafter\def\csnameHL@S0\endcsname#1{#1\/} \expandafter\def\csnameHL@S1\endcsname#1{#1\null.} \expandafter\def\csnamehl@S1\endcsname#1{#1\null.} \expandafter\def\csnamehl@S2\endcsname#1{#1\null.} \expandafter\def\csnamehl@S3\endcsname#1{#1\/} \expandafter\def\csnamehl@S4\endcsname#1{#1\/}

As in paper.st, we

\def\maketoc@W{Contents}



with the Part title, in uppercase, starting 35 points from the word 'PART' (but if there is no part number, we \hskip back 35 points). We use \uppercase{#2}, since, as mentioned on page 562, the.toc file has 'HL@WO', which is 'Part', rather than 'PART', allowing other front matter style files to handle things differently. The second argument (which normally would be the part title) is empty; the third argument, normally \dotleaders is \hfil, and the fourth argument, normally \Page... is also empty, so that 'Part' entries are printed without dot leaders or page numbers.

Similarly, the definition of \makelist in book.stf is almost the same as that in lamstex.stf, except that we add

\global\spsecialpage@true \gdef\headline@{\ignorespace#2}\unskip} and use

\BF\baselineskip=22pt

for setting the heading instead of \bf.

Finally, \footline and \headline are reset as in book.st, except using the flag \ifspecialpage@ rather than the flags \ifpart@ and \iffirstchapterpage@.

1.1. book.stb. The back matter style file book.stb also begins with the same basic settings as book.st, except that redefinition of \makeheadline and \makefootline is deferred; and then it loads the same fonts as before.

Then we have numerous definitions from lamstex.stb:

\def\adjustpunct@... \def\ignorepars@... \def\ignorepars@... \newcount\ctype@ \newcount\ctype@ \newif\ifleftcolbreak@ \def\cbreak@... \newif\ifleftter@ \newtoks\marktoks@1.. \newtoks\marktoks@v




We will need to define

\def\bibliography@W{Bibliography}

so that

\newword\bibliography

can be used prior to this (in lamstex.tex this definition is made by \UseBibTeX, which won't appear in the back matter file).

The redefinition of \bibliography, with no argument, will begin with \checkmainfile@, since \mainfile@.bbl is the file we will want to \input:

\def\bibliography{\checkmainfile@ \immediate\openin\bbl@=\mainfile@.bbl \ifeof\bbl@ \W@{No.bbl file}% \else \immediate\closein\bbl@ \begingroup \input bibtex \input\mainfile@.bbl \endgroup \fi}%

Recall that bibtex.tex defines \begin{thebibliography}{...} in terms of \begingthebibliography@{...}, which now has to be redefined to give the same sort of information and formatting as \makebib for this file:

\def\beginthebibliography@#1{\par\vfill\break\global\specialpage@true \gdef\headline@{\makebib@W}% \eightpoint \setbox0=\hbox{#1}\bibindent@=\wd0 \sfcode'\.=1000 \everypart{\parindent=Opt \hbox{\hfil\b\f\uppercase\expandafter{\bibliography@W}\hfil\f\%}iftoc@ {expandafter{unmacro@meaningunakebib@W{unmacro@ {}noexpands@ {}edef{\nert@{write}toc@{\noexpand}noexpand}{\ibliography{{}macdef@}}}{next@}% {write}toc@{\noexpand}Page {{number}\pageno}{\page@N}{\page@P}{\page@Q}~~JJ}% {\fi \nobreak\biggskip} ```
The definition of \makeindex is virtually the same as in lamstex.stb, except that we again write to the.toc file, and set up information for the heading levels and foot line,
``` {}def\makeindex{\checkmainfile@\par\forall}break {}iftoc@ {\expandafter\unmacro@\meaning\makeindex@W\unmacro@ {\noexpands@ {}edef\next@{\write}toc@{\noexpand}noexpand\makeindex{\makeof}}}{next@}% {\write}toc@{\noexpand}Page {\number}\pageno}{\page@N}{\page@P}{\page@Q}~~JJ}% {}if {}global\specialpage@true {}global\firstindexpage@true {}gdef\headline@{\makeindex@W}% {}beginroup (material from lamstex.stb definition,  starting with \let\asterisk=*, and  ending with \def\shortlastcolumn... ) \hsize=14pc \global\visize=\doublepageheight@ \maxdepth=\maxdimen \global\firstindexpage@true \global\advance\visize by -6Opt \everypar-{}\parindent=Opt


