\part Particular\\Constructions\\Allowing Labels\\ \noalign{\vskip 8pt} {}\quad\hskip-3pt {\eighteenbfit and their associates} \endpart \chapter Displayed formulas\label{DF}\endchapter The next part of \lamstex\ is concerned with displayed formulas and the *\tag* mechanism; it is the first place where we define *\thelabel@* \dots. However, numerous special considerations for *\tag* are also required, and sections~\Sref{LOCL} and~\Sref{maketag} are the only ones specifically related to the *\label* mechanism. \section{\label{pretend1}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~\Sref{ZZZ}): The *\prevanish@* sets *\saveskip@* to *0pt* (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 \lamstex\ 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: ** \everydisplay{\csname displaymath \endcsname} \expandafter\def\csname displaymath \endcsname#1$${% #1$$\FNSS@\pretendspace@} ** Note that here we need *\FNSS@* (section~\Sref{FIX}), not just *\futurelet\next*, since we have to skip over any space after the final *$$*. We will introduce the abbreviation \C** \def\FNSSP@{\FNSS@\pretendspace@} "8DEFFNSSP"8 ** not only because it will save numerous tokens, but also because at one point (section~\Sref{VF}), it will be essential to have it. So we use \C** \everydisplay{\csname displaymath \endcsname} \expandafter\def\csname displaymath \endcsname#1$${% #1$$\FNSSP@} ** \small The control sequence ** \csname displaymath \endcsname ** (compare *\csname align \endcsname* etc., as explained in *amstex.doc*) shows up on the screen as ** \displaymath" "0 ** so if a blank line occurs before the closing *$$*, we will get the error message ** ! Paragraph ended before \displaymath" " was complete. ** [If we defined `*\displaymath" *' 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" *', would also be presented.] \andsmall! Notice that a construction like \pagelabel{BADOUTER} ** $$ . . .$$ \bye ** 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@. ** \andsmall! Unlike the situation for *\noindent* (section~\Sref{ZZZ}), 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-1pt\hskip1pt* added by the *\prevanish@* in *\label* will have a dire effect: it will cause a {\it 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@, \setbox0\hbox{\it\, n\,} ** A line of text. $$ . . . $$ \write"box0{...} 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.\pagelabel{WARNPAR} \endsmall 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 \lamstex~Manual), one can ** \def\Math{\begingroup\everydisplay{}$$} \def\endMath{$$\endgroup\futurelet\next\pretendspace@} ** and then use *\Math...\endMath* instead of *$$...$$*. (We don't need *\FNSS@* here, since there won't be a space token after the control sequence *\endMath*.)\pagelabel{DDD} Some people, of course, might argue that this is really the ``logical'' way to do things anyway. If such a definition were to be instituted permanently, then the basic \amstex\ definition of *\tag* (see ({\bf A}) below) would have to be changed, so that the argument of *\tag* is delimited by *\endMath* rather than by *$$*. (When the \lamstex~Manual required literal mode in a displayed formula with a *\tag*, the literal mode material was first set in a box, which was then used within the usual *$$...\tag$$* construction.) It should also be noted that the \amstex\ construction *\align....\endalign* must read in *...* as an argument, in which case category code changes within *...* will still be ignored. The same is true of the \lamstex\ *\CD"allowbreak..."allowbreak\endCD* construction. So, all in all, *\Math..\endMath* should be reserved for special effects. \small There is a way of allowing category changes within a display *$$...$$* if we are willing to change the category code of *$* itself: ** \let\dollar@=$ \newif\ifindisplay@ \catcode`\$=\active "2 \def${\futurelet\next\dollar@@} "2 \def\dollar@@{% \ifx\next$% \ifindisplay@ \def\next@${\dollar@\dollar@\FNSSP@}% "2 \else \def\next@${\dollar@\dollar@\indisplay@true}% \fi "2 \else \let\next@=\dollar@ \fi \next@} ** (We never need to set *\indisplay@false*, since our *\indisplay@true* occurs within the display, which \tex\ implicitly encloses within a group.) I wanted to avoid additional category changes as much as possible, but perhaps this approach is really preferable. If such definitions were made, we would also have to restate any definitions that involved *$* as part of their syntax. For example, we would have to restate \amstex's definition of *\tag*, \Litbox0=** \def\tag#1$${\iftagsleft@\leqno\else\eqno\fi \maektag@#1\maketag$$} ** $$\vcenter{\box0}\tag"\style{\bf A}"$$ at some point after *$* has been made active. It would naturally also be sensible to replace any *$...$* combinations in macros by *\dollar@...\dollar@* (many such appear in the \amstex\ macros, or their replacements in \lamstex@, e.g., those in sections~\Sref{relax} and~ \Sref{relax2}). But a *$* in an *\xdef* (e.g., as on page~\ref{Xdefs}) would instead have to be replaced by *\noexpand$*. Moreover, we would have to add `*\let$=\relax*' to *\noexpandtoks@* (or, equivalently, state *\Nonexpanding$*). \andsmall One advantage of this approach, by the way, is that one could modify the definition of *\dollar@@* to be: ** \def\dollar@@{% \ifx\next$% . . . \else "2 \ifhmode \def\next@{\saveskip@=\lastskip\unskip\/% \ifdim\saveskip@>0pt \hskip\saveskip@\fi\dollar@}% \else "2 \let\next@=\dollar@ \fi \fi \next@} ** With such a definition, something like \setbox0\hbox{(1)}\setbox1\hbox{(2)} ** "copy0 If $|x|<3$, then ... ** would be treated as if it had been typed ** "copy1 If\/ $|x|<3$, then ... ** (On the other hand, input (2) would remain as is, since *\/* has no effect except after a character or ligature.) This arrangement is quite useful if the current font is slanted or italic, as in the statement of a *\claim*, because \medskip \centerline{\tenpoint\cmtensl If\hskip3.3333pt $|x|<3$,\hskip3.3333pt then\hskip3.333pt\null \dots\null} \medskip \noindent looks much better if the italic correction is added: \medskip \centerline{\tenpoint\cmtensl If\/\hskip3.3333pt $|x|<3$,\hskip3.3333pt then\hskip3.3333pt\null \dots\null} \medskip \noindent (See page~\ref{SAMP} for other examples where the italic correction seems called for.) I used this approach in the style file for the Publish or Perish {\it Mathematics Lecture Series}. As far as I can tell, there is no other way of achieving this: *\everymath* doesn't do any good, because a *$* puts a `*\mathon*' on the horizontal list, and one can't remove it, in order to *\unskip*. \endsmall \section{Localizing labels\label{LOCL}} As already mentioned in section~\Sref{bl}, \lamstex\ uses *\thelabel@*, \dots, for the values of *\ref*, \dots, *\pref* associated to a \, and any \lamstex\ construction that can be given a \ must define these control sequences. It turns out that these four components will always have to be defined {\it globally}, because they have to be made within a group beginning with *\noexpands@*---compare page~\ref{plex}---even though we want *\thelabel@*, \dots, to be defined only locally. So \lamstex\ uses *\Thelabel@*, \dots, *\Thelabel@@@@* for the four components that it defines globally, and then uses the constructions \setbox0\hbox{\,, \dots} ** \let\thelabel@=\Thelabel@"box0 ** to create locally defined ones. Since this is used so often, we abbreviate it: \C** \def\locallabel@{\let\thelabel@=\Thelabel@ \let\thelabel@@=\Thelabel@@\let\thelabel@@@=\Thelabel@@@ \let\thelabel@@@@=\Thelabel@@@@} ** \section{{\tt\bs tag}\label{maketag}} We introduce the counter *\tag@C* for *\tag*, and the initial values for the other associated things for labelling: \C** \newcount\tag@C \tag@C=0 \let\tag@P=\empty \let\tag@Q=\empty \def\tag@S#1{{\rm(}#1\/{\rm)}} "8tagit"8 \let\tag@N=\arabic \def\tag@F{\rm} ** As in the case of *\page@F* (page~\ref{pagef}), we use *\def\tag@F{\rm}* rather than *\let\tag@F=\rm*, so that *\fontstyle\tag* will work correctly. In *\tag@S* we specified roman parentheses even if *\tag@F* is changed\pagelabel{BB} (compare page~\ref{CCC}); of course, *\tag@S* could be changed if we didn't want this. Unlike the situation for *\page@N*, we can *\let\tag@N=\arabic*, because *\tag@N* appears only in certain *\xdef*'s (page~\ref{Xdefsa}), and then this value of *\tag@N* will simply disappear,\pagelabel{TAGATN} resulting in a shorter string than if we kept *\arabic* unexpanded. \medskip \noindent{\bf NOTE: Nevertheless, we must use *\def* instead of *\let* for other numbering styles.} Note that *\newnumstyle* does this (Chapter~\ref{acces}). \medbreak \amstex\ already defines the combination *\tag#1$$* to be *\leqno* or *\eqno* followed by *\maketag@#1\maketag$$*, and we just have to redefine *\maketag@* for \lamstex@, although the argument *#1* will now have a rather different significance: in \amstex@, *#1* 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 *""...""*, 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*. \C** \def\maketag@{\futurelet\next\maketag@@} ** However, for reasons that will be explained in section~\Sref{relax}, if *\maketag@* is followed by *\relax""...""* we will want to get the same result as if it were followed simply by *""...""*. So we will call *\maketag@@@* if *\maketag@* is followed by *""* and *\maketag@@@@* if it is followed by anything else other than *\relax*. But if *\maketag@* is followed by *\relax*, we call a control sequence that swallows this *\relax* and then reiterates the process: \C** \def\maketag@@{\ifx\next\relax \def\next@\relax{\futurelet\next\maketag@@}\else \ifx\next""\let\next@=\maketag@@@\else \let\next@=\maketag@@@@\fi\fi\next@} ** The definition of *\maketag@@@@* (when *\tag* is not followed by a *""*) illustrates the general scheme by which \lamstex\ deals with labels. \list \item First we globally advance the *\tag* counter, *\tag@C*, by one. \item\label{xdeft} Then we *\xdef* the values of *\Thelabel@*, \dots, *\Thelabel@@@@* appropriately, using the current values of *\tag@C*, *\tag@P*, etc. \item Then we use *\locallabel@* to (locally) set the values of *\thelabel@*, \dots, *\thelabel@@@@*. \item 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*). \endlist In step~\nref{xdeft} we will be doing something like ** {\noexpands@ \xdef\Thelabel@@@{\number\tag@C} \xdef\Thelabel@{\tag@N{\Thelabel@@@}} "2 \xdef\Thelabel@@@@{\ifmathtags@$\tag@P\Thelabel@\tag@Q$\else \tag@P\Thelabel@\tag@Q\fi} \xdef\Thelabel@@{\tag@S{\Thelabel@@@@}} } ** All of the \lamstex\ constructions that can be given a \ will define *\Thelabel@*, \dots, *\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@@*: \C** \def\xdefThelabel@#1{\xdef\Thelabel@{#1{\Thelabel@@@}}} \def\xdefThelabel@@#1{\xdef\Thelabel@@{#1{\Thelabel@@@@}}} ** Thus, we define *\maketag@@@@* by \C** \def\maketag@@@@#1\maketag@{\global\advance\tag@C by 1 "2 {\noexpands@ \xdef\Thelabel@@@{\number\tag@C}% \xdefThelabel@\tag@N "8Xdefsa"8 "2 \xdef\Thelabel@@@@{\ifmathtags@ $\tag@P\Thelabel@\tag@Q$\else "8Xdefs"8 \tag@P\Thelabel@\tag@Q\fi}% "2 \xdefThelabel@@\tag@S }% "2 \locallabel@ \hbox{\tag@F\thelabel@@}% #1} ** \medskip When *\tag* is followed by *""*, it might occur in constructions like \setbox0\hbox{or}\setbox1\hbox{etc.,} ** \tag ""\style{...}"" "box0 \tag ""\style{\pre 3}"" "box1 ** 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@*, \dots, *\Thelabel@@@@* must be suitably interpreted. For this we use a routine that is also used by many other constructions:\pagelabel{ql} \C** \def\Qlabel@#1{{\noexpands@\xdef\Thelabel@@{#1}% \let\style=\empty\xdef\Thelabel@@@@{#1}% \let\pre=\empty\let\post=\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 \list \item *\Thelabel@@* (which is what *\Ref* is supposed to produce), will give *#1*, with *\pre* interpreted as *\tag@P*, etc. \item *\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. \item *\Thelabel@* (what *\ref* is supposed to produce), also ignores *\pre* and *\post* if they appear. \item *\Thelabel@@@* (what *\nref* is supposed to produce), also ignores *\numstyle* if it appears. \endlist \C** \def\maketag@@@""#1""#2\maketag@{% {\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} ** \small 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. \andsmall! Because of the *\xdef*'s in *\Qlabel*, any ``quoted'' number *""...""* following *\tag* (or any other construction that allows a \) 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~\ref{LBL1} was labelled `*STARTLABEL*' and Chapter~\ref{RAF} was labelled `*ENDLABEL*'. If the next chapter were commentary on these chapters, and for some reason we wanted this commentary to be called \bigskip \centerline{\bf Chapter \ref{LBL1}$'$--\ref{RAF}$'$. Remarks on Labels and Cross References} \bigskip\noindent 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 ... ** In such a case, we might even use a *\label* with this ``quoted'' number, ** \chapter ""..."" . . . \label{...} \endchapter ** in order to refer to this new chapter later on. \endsmall \section{{\tt\bs align}\label{relax}} This section presumes familiarity with \amstex's *\align* construction (see *amstex.doc*). Before considering this construction in detail, we need to consider one aspect of the general scheme. \setbox0\hbox{\} \setbox1\hbox{\} \setbox2\hbox{\} When \amstex\ sees something like ** \align "copy0 & "copy1 \tag "box2 \\ . . . ** the *\align* is an *\halign* whose preamble contains three *&*'s, of the form {\advance\litindent-10pt ** \halign{ ...#... & ...#... & ... \maketag@#\maketag@ ... \cr . . . ** Within the *\align*, a *\tag* is simply interpreted as an *&*.} But this means that after a *\tag*, \tex\ will examine the next token, {\it expanding if necessary}, to see if a *\noalign* or *\omit* follows ({\it The \tex book}, page ~240). So if ** "copy0 & "copy1 \tag ""..."" \\ ** appears, the first *""* {\it will already be expanded out\/} to *\futurelet\next\quote@* before being submitted to *\maketag@*. Consequently, *\maketag@* will think that the next token is *\futurelet*, rather than *""*\,! To get around this, we will instead have *\tag* interpreted as *&\relax*, to insure that the *""* is not expanded out. Thus, *\tag""...""* will lead to ** \maketag@\relax""...""\maketag@ ** and we have already arranged for this to give the same result as if the *\relax* weren't there (section~\Sref{maketag}). \def\p.{\vphantom{p}} The definition of *\tag* for *\align* is made by \amstex's control sequence *\align@*, which is now redefined to include the *\relax*, together with other changes that will be explained later. \C** \def\align@{\inalign@true\inany@true \vspace@\allowdisplaybreak@\displaybreak@\intertext@ \def\tag{\global\tag@true\ifnum\and@=0 "8deftag"8 \def\next@{&"9\omit"p."9","9\global\rwidth@=0pt"9&"9\relax"p."9}\else \def\next@{&"9\relax"9}\fi\next@}% \iftagsleft@\def\next@{\csname align \endcsname}\else \def\next@{\csname align \space\endcsname}\fi\next@} ** Still further changes to the rest of the \amstex\ *\align* construction itself are also required, because the remainder of this construction first calls *\measure@* to measure all the formulas, before actually setting them. Even in \amstex@, this can produce problems: if a user puts a constructed *\box* within an *\align*, it will be emptied out by *\measure@* and hence produce nothing at all when the typesetting is done (this means that the user needs to use *\copy* rather than *\box*). In \lamstex@, the problem is that we want to ignore any *\Reset\tag* and *\Offset\tag* constructions during the *\measure@*, since these globally change the *\tag* counter, and we don't want to do that twice (*\Reset* and *\Offset* are described in Chapter~\ref{acces}). We introduce a special abbreviation for a more general construction that disables *\Offset* and *\Reset* (but keeps them invisible): \C** \def\noset@{\def\Offset##1##2{\prevanish@\postvanish@}% \def\Reset##1##2{\prevanish@\postvanish@}} ** Now we redefine *\measure@* so that *\noset@* is used: \C** \def\measure@#1\endalign{% \global\lwidth@=0pt \global\rwidth@=0pt \global\maxlwidth@=0pt \global\maxrwidth@=0pt \global\and@=0 "2 \setbox0=\vbox {"9\noset@"9\everycr{\noalign{\global\tag@false \global\and@=0}}\Let@ "2 \halign{\setbox0=\hbox{$\m@th\displaystyle{\@lign##}$}% "8measure"8 \global\lwidth@=\wd0 \ifdim\lwidth@>\maxlwidth@ \global\maxlwidth@=\lwidth@\fi \global\advance\and@ by 1 "2 &\setbox0=\hbox{$\m@th\displaystyle{{}\@lign##}$}% \global\rwidth@=\wd0 \ifdim\rwidth@>\maxrwidth@ \global\maxrwidth@=\rwidth@\fi \global\advance\and@ by 1 &\Tag@\eat@{##}\crcr#1\crcr}}% \totwidth@=\maxlwidth@ \advance\totwidth@ by \maxrwidth@} ** (Here *\eat@* from \amstex\ is defined by *\def\eat@#1{}*, see section~\Sref{AC}.) The assignments of *\lwdith@*, \dots\ at the beginning of the definition don't really have to be *\global*, but they do have to be *\global* later in the definition, so we make them *\global* at all times (compare section~\Sref{LANDG}). Now, in the definition of `*\align" *' and `*\align" " *' (called by *\align*), after we *\measure@* we can allow *\Offset* and *\Reset* to have their usual meanings, but there is a different problem. When we have something like \setbox1\hbox{\}\setbox2\hbox{\} ** "box1 & "box2 \Offset\tag0 \newpost\tag{$'$} \tag \\ ** the new values of *\tag@C* and *\tag@P* created by *\Offset* and *\newpost* are processed as part of \ (since the *&* that ends this formula is supplied by the *\tag*). But the new value of *\tag@P* is created only {\it locally}, so it will not be known when *\tag* has to do its work. To get around this problem, we need to pass such information through by means of two new globally defined control sequences, *\tag@P@* and *\tag@Q@*, and we make a special abbreviation for this: \C** \def\prepost@{\global\let\tag@P@=\tag@P \global\let\tag@Q@=\tag@Q} ** We also have an abbreviation for the construction that (locally) sets *\tag@P* and *\tag@Q* to the globally defined *\tag@P@* and *\tag@Q@*: \C** \def\reprepost@{\let\tag@P=\tag@P@\let\tag@Q=\tag@Q@} ** Now we redefine *\align" * and *\align" " * from \amstex\ using *\prepost@* within the formulas, and using *\reprepost@* when the formula number is being printed; note that we use *\prepost@* at the {\it end\/} of each formula, so that any *\newpre* or *\newpost* will have been discovered, but *\reprepost@* at the {\it beginning\/} of each formula number. (These maneuvers aren't needed for *\measure@*, since we simply *\eat@* each formula number.) First comes `*\align" " *': \C** \expandafter\def\csname align \space\endcsname#1\endalign {\measure@#1\endalign\global\and@=0 "2 \ifingather@\everycr{\noalign{\global\and@=0}}\else \displ@y@\fi "2 \Let@\tabskip\centering@ "2 \halign to\displaywidth {\hfil\strut@\setbox0=\hbox{$\m@th\displaystyle {\@lign##"9\prepost@"9}$}% \box0 \global\advance\and@ by 1 \tabskip\z@skip& "2 \setbox0=\hbox{$\m@th\displaystyle{{}\@lign##"9\prepost@"9}$}% \global\rwidth@=\wd0 \box0 \hfil \global\advance\and@ by 1 \tabskip\centering@ & "2 \setbox0=\hbox{\@lign\strut@"9\reprepost@"9 \maketag@##\maketag@}% "2 \dimen@=\displaywidth \advance\dimen@ by -\totwidth@ \divide\dimen@ by 2 \advance\dimen@ by \maxrwidth@ \advance\dimen@ by -\rwidth@ "2 \ifdim\dimen@<2\wd0 \llap{\vtop{\normalbaselines\null\box0}}% "2 \else\llap{\box0}\fi "2 \tabskip\z@skip \crcr#1\crcr \black@\totwidth@}} ** Note that in a formula like \setbox0\hbox{\} ** \align . . . "copy0 \newpre\tag{a}\tag ... \\ . . . ** where there is a line without any *&*, the definition of *\tag* in *\align@* (page~\ref{deftag}) means that this line will be interpreted as ** "copy0 \newpre\tag{a}& "9\omit"p."9","9\global\rwidth@=0pt"9 &\relax \reprepost@ \maketag@...\maketag@ \cr ** The *\prepost@* in the first part of the preamble for *\align* globally defines *\tag@P@* to be `*a*', and the *\reprepost@* then makes *\tag@P* properly defined for *\maketag@*. But if the *\omit* were not inserted, then the *\prepost@* for the {\it 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@=0pt*, which would normally be set by an empty formula. The extra clause ** \ifdim\rwidth@>\maxrwidth@ \global\maxrwidth@=\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\centering@* 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: \C** \expandafter\def\csname align \endcsname#1\endalign {\measure@#1\endalign\global\and@=0 "2 \ifdim\totwidth@>\displaywidth\let\displaywidth@=\totwidth@ \else\let\displaywidth@=\displaywidth\fi "2 \ifingather@\everycr{\noalign{\global\and@=0}}\else \displ@y@\fi "2 \Let@\tabskip\centering@ \halign to\displaywidth {\hfil\strut@\setbox0=\hbox{$\m@th\displaystyle {\@lign##"9\prepost@"9}$}% \global\lwidth@=\wd0 \global\lineht@=\ht0 \box0 \global\advance\and@ by 1 \tabskip\z@skip&\setbox0=\hbox{$\m@th\displaystyle{{}\@lign ##"9\prepost@"9}$}% \ifdim\ht0>\lineht@ \global\lineht@=\ht0 \fi \box0 \hfil \global\advance\and@ by 1 \tabskip\centering@ & \kern-\displaywidth@ \setbox0=\hbox{\@lign\strut@"9\reprepost@"9 \maketag@##\maketag@}% \dimen@=\displaywidth \advance\dimen@ by -\totwidth@ \divide\dimen@ by 2 \advance\dimen@ by \maxlwidth@ \advance\dimen@ by -\lwidth@ \ifdim\dimen@<2\wd0 \rlap{\vbox{\normalbaselines\box0 \vbox to\lineht@{}}}% \else\rlap{\box0}\fi \tabskip\displaywidth@\crcr#1\crcr \black@\totwidth@}} ** The extra clause ** \ifdim\ht0>\lineht@ \global\lineht@=\ht0 \fi ** appearing in the second part of the preamble doesn't have to be added to the definition of *\tag* in *\align@*, along with the *\omit*, since it would always be inoperative for a blank formula. \section{\CS{alignat} and \CS{xalignat}\label{relax2}} This section presumes familiarity with \amstex's *\alignat* and *\xalignat* constructions, which also require changes (no changes are required for *\xxalignat*, which doesn't allow *\tag*'s). *\alignat* and *\xalignat* process their arguments twice, like *\align*, although the initial processing provides much less information. In these constructions a *\tag* might even end up overlapping a formula, but at least a black box is produced at the end, to indicate such overlapping (which is easy to miss when proofreading). The initial processing is done with empty *\tag*'s, but as if the *\tag*'s were set at their minimum distance from the formula (i.e., at a distance equal to their widths), and the result is saved in *\box\savealignat@*. During the second processing the only role played by this box is in the ** \black@{\wd\savealignat@} ** that is appended after the *\halign*, to give a black box if the whole construction turns out to be too wide. Unlike the situation for *\align*, where we specify the preamble for the first process in *\measure@*, the \amstex\ routine *\attag@* is used to produce the preambles for both processes of *\alignat* and *\xalignat*, using a flag *\ifmeasuring@* to determine whether we are making a preamble for the first process or for the second, as well as the flag *\ifxat@* to determine whether we are making preambles for *\alignat* or for *\xalignat*. The definition of *\attag@* from \amstex\ has to be modified in the same way as the definitions of *\measure@*, `*\align" *' and `*\align" " *', by inserting *\prepost@* and *\reprepost@* in the appropriate places: \C** \def\attag@#1{\let\Maketag@=\maketag@\let\TAG@=\Tag@ "9\let\Prepost@=\prepost@"9","9\let\Reprepost@=\reprepost@"9 \let\Tag@=\relax\let\maketag@=\relax "9\let\prepost@=\relax"9","9\let\reprepost@=\relax"9 "2 \ifmeasuring@ \def\llap@##1{\setbox0=\hbox{##1}\hbox to2\wd0{}}% \def\rlap@##1{\setbox0=\hbox{##1}\hbox to2\wd0{}}% \else\let\llap@=\llap\let\rlap@=\rlap\fi "2 \toks@={\hfil\strut@ $\m@th\displaystyle{\@lign\the\hashtoks@"9prepost@"9}$% \tabskip\z@skip\global\advance\and@ by 1 & $\m@th\displaystyle{{}\@lign\the\hashtoks@"9\prepost"9}$\hfil \ifxat@\tabskip\centering@\fi\global\advance\and@ by 1}% "2 \iftagsleft@ \toks@@={\tabskip\centering@&\Tag@\kern-\displaywidth \rlap@{\@lign"9\reprepost@"9 \maketag@\the\hashtoks@\maketag@}% \global\advance\and@ by 1 \tabskip\displaywidth}\else \toks@@={\tabskip\centering@&\Tag@ \llap@{\@lign"9\reprepost@"9\maketag@ \the\hashtoks@\maketag@}\global\advance\and@ by 1 \tabskip\z@skip}\fi "2 \atcount@#1\relax\advance\atcount@ by -1 \loop\ifnum\atcount@>0 \toks@=\expandafter{\the\toks@&\hfil $\m@th\displaystyle{\@lign\the\hashtoks@"9\prepost@"9}$% \global\advance\and@ by 1 \tabskip\z@skip& $\m@th\displaystyle{{}\@lign\the\hashtoks@ "9\prepost@"9}$\hfil \ifxat@\tabskip\centering@\fi\global\advance\and@ by 1}% \advance\atcount@ by -1 \repeat "2 \xdef\preamble@{\the\toks@\the\toks@@}% \xdef\preamble@@{\preamble@}% \let\maketag@=\Maketag@\let\Tag@=\TAG@ "9\let\prepost@=\Prepost@"9","9\let\reprepost@=\Reprepost@"9} ** Now we must modify the definition of `*\alignat" *', which is called by *\alignat*, in several ways: \list \item *\tag* must mean *&\relax*; \item 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. \endlist 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@#\maketag@*. \keepitem \list \item This means that the tag counter *\tag@C* will be incremented during the first pass. So we will first store the current value of *\tag@C* in a new counter *\tag@CC*, and then restore *\tag@C* to this value before doing the second pass. \item Moreover, we want to disable *\label* during the first pass (or we will be using the same \ twice during the second pass, and get an error message). We could use *\let\label=\eat@* for this purpose, but we will instead call *\unlabel@*, defined by ** \def\unlabel@{\def\label##1{\prevanish@\postvanish@}% \def\pagelabel##1{\prevanish@\postvanish@}} ** since this construction will be needed later anyway (section~\Sref{FMTC}). \endlist \C** \def\unlabel@{\def\label##1{\prevanish@\postvanish@}% \def\pagelabel##1{\prevanish@\postvanish@}} \newcount\tag@CC "slip \expandafter\def\csname alignat \endcsname#1#2\endalignat {\inany@true\xat@false "2 \gdef\tag{\global\tag@true \count@=#1\relax\multiply\count@ by 2 "9\advance\count@ by -1"9 "9\gdef\tag@{&}"9\loop\ifnum\count@>\and@ \xdef\tag@{&"9\omit"9\tag@}\advance\count@ by -1 \repeat\tag@"9\relax"9}% "2 \vspace@\allowdisplaybreak@\displaybreak@\intertext@ \displ@y@\measuring@true"9\tag@CC=\tag@C"9 "2 "slop \setbox\savealignat@=\hbox{"9\noset@"9","9\unlabel@"9% $\m@th\displaystyle\Let@ \attag@{#1}\vbox{\halign{\span\preamble@@\crcr#2\crcr}}$}% "2 \measuring@false \Let@\attag@{#1}"9\tag@C=\tag@CC"9 \tabskip\centering@\halign to\displaywidth {\span\preamble@@\crcr#2\crcr\black@{\wd\savealignat@}}} ** Similar changes are made for `*\xalignat" *': \C** \expandafter\def\csname xalignat \endcsname#1#2\endxalignat {\inany@true\xat@true "2 \def\tag{\global\tag@true \count@=#1\relax\multiply\count@ by 2 "9\advance\count@ by -1"9 "9\def\tag@{&}"9\loop\ifnum\count@>\and@ \xdef\tag@{&"9\omit"9\tag@}\advance\count@ by -1 \repeat\tag@"9\relax"9}% "2 \vspace@\allowdisplaybreak@\displaybreak@\intertext@ \displ@y@\measuring@true"9\tag@CC=\tag@C"9 "2 "slop \setbox\savealignat@=\hbox{"9\noset@"9","9\unlabel@"9% $\m@th\displaystyle\Let@ \attag@{#1}\vbox{\halign{\span\preamble@@\crcr#2\crcr}}$}% "2 \measuring@false \Let@\attag@{#1}"9\tag@C=\tag@CC"9 \tabskip\centering@\halign to\displaywidth {\span\preamble@@\crcr#2\crcr\black@{\wd\savealignat@}}} ** \section{\tt\bs gather} Finally, the \amstex\ construction *\gather* also has a *\def\tag{&}* clause, which must be changed to *\def\tag{&\relax}*: \C** \def\gather{\relax\ifmmode\ifinner \def\next@{\onlydmatherr@\gather}\else \ingather@true\inany@true"9\def\tag{&\relax}"9% \vspace@\allowdisplaybreak@\displaybreak@\intertext@ \displ@y\Let@ \iftagsleft@\def\next@{\csname gather \endcsname}\else \def\next@{\csname gather \space\endcsname}\fi\fi \else\def\next@{\onlydmatherr@\gather}\fi\next@} ** \chapter New counters\label{NEWC}\endchapter Having seen how *\tag* deals with *\label*, we are now in a position to consider \lamstex's *\newcounter* construction for creating a new counter. \footnote{In version *1* of \lamstex@, this was called *\counter*, because *\newcounter* seemed too close to \tex's *\newcount* primitive for comfort, but it actually seems unlikely that anyone (except perhaps \tex perts!)\ % would mistakenly type *\newcount* instead of *\newcounter*, and *\newcounter* fits much better with all the other \lamstex\ names.} \section{{\tt\bs newcounter}\label{CNT}} We introduce a very frequently used abbreviation \C** \def\exstring@{\expandafter\eat@\string} "8EXSTRING"8 ** where *\eat@* from \amstex\ is simply defined (section~\Sref{AC}) as ** \def\eat@#1{} ** Note that if *#1* is a control sequence, say *\tag*, then something like ** \csname\exstring@#1@C\endcsname ** just becomes *\tag@C* (the *\eat@* eats the *\* at the beginning of *\string\tag*). The first thing *\newcounter\foo* will do is to ** \define\foo{} ** to give an error message if *\foo* has already been defined. Since *\foo\label{*\*}* is supposed to work, albeit not by the general mechanism for *\label*'s, *\foo* needs to be defined in terms of a *\futurelet*: ** \def\foo{\futurelet\next\foo@Z} ** We use *\foo@Z* because no control sequence from \amstex\ or \lamstex\ ends with *@Z*. The name `*\foo@Z*' will be created with ** \csname\exstring@\foo @Z\endcsname ** and to define *\foo* we use the same strategy that was used in section~\Sref{ATDEF}: ** \edef\next@{\def\noexpand\foo{\futurelet\noexpand\next \csname\exstring@\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@C*, \dots 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\Thelabel@{...}...} {\locallabel@\label{...}} ** 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@*, \dots 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}}% \ifx\next\label \def\next@\label##1{% {\noexpands@ \xdef\Thelabel@{...}...\xdef\Thelabel@@@@{....}}% {\locallabel@\label{##1}}}% \else \let\next@=\relax \fi \next@} ** 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~\Sref{ADDCSNAME}), so it is going to look pretty complicated (in particular, now our *####*'s will all have to be *########*'s, since an *\edef* changes *##* to *#*). The control sequence *\foo@C* will be specified within this *\edef\next@* as ** \csname\exstring@\foo @C\endcsname ** and similarly for *\foo@P*, \dots. 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*, \dots with their proper meanings, ** \expandafter\newcount@\csname\exsting@\foo@ C\endcsname \expandafter\let\csname\exstring@\foo @N\endcsname=\arabic . . . ** Note that here we use *\newcount@* (section~\Sref{NEWNEW}), since it appears within a definition, and thus might be used after *\alloc@* has been returned to its old definition.\pagelabel{NWNW} Note also that we use *\let* rather than *\def*, just as with *\tag* (page~\ref{TAGATN}), 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*: \C** \def\newcounter#1{\define#1{}% \edef\next@{\def\noexpand#1{\futurelet \noexpand\next\csname\exstring@#1@Z\endcsname}}\next@ "2 \edef\next@{\def\csname\exstring@#1@Z\endcsname {\global\advance\csname\exstring@#1@C\endcsname by 1 "2 {\csname\exstring@#1@F\endcsname \csname\exstring@#1@S\endcsname{\csname\exstring@ #1@P\endcsname\csname\exstring@#1@N\endcsname {\noexpand\number\csname\exstring@#1@C\endcsname}% \csname\exstring@#1@Q\endcsname}}% "2 \noexpand\ifx\noexpand\next\noexpand\label "2 \def\noexpand\next@\noexpand\label########1{% {\noexpand\noexpands@ "2 \xdef\noexpand\Thelabel@ {\csname\exstring@#1@N\endcsname {\noexpand\number\csname\exstring@#1@C\endcsname}}% "2 \xdef\noexpand\Thelabel@@@ {\noexpand\number\csname\exstring@#1@C\endcsname}% "2 \xdef\noexpand\Thelabel@@ {\csname\exstring@#1@S\endcsname {\csname\exstring@#1@P\endcsname \csname\exstring@#1@N\endcsname {\noexpand\number\csname\exstring@#1@C\endcsname}% \csname\exstring@#1@Q\endcsname}}% "2 \xdef\noexpand\Thelabel@@@@ {\csname\exstring@#1@P\endcsname \csname\exstring@#1@N\endcsname {\noexpand\number\csname\exstring@#1@C\endcsname}% \csname\exstring@#1@Q\endcsname}}% "2 {\noexpand\locallabel@\noexpand\label{########1}}% "2 \noexpand\else\let\noexpand\next@=\relax\noexpand\fi \noexpand\next@}}% \next@ "2 \expandafter\newcount@\csname\exstring@#1@C\endcsname "2 \expandafter\let\csname\exstring@#1@N\endcsname=\arabic "2 \expandafter\def\csname\exstring@#1@S\endcsname##1{##1\/}% "2 \expandafter\let\csname\exstring@#1@P\endcsname=\empty "2 \expandafter\let\csname\exstring@#1@Q\endcsname=\empty "2 \expandafter\def\csname\exstring@#1@F\endcsname{\rm}% } ** \section{{\tt\bs usecounter}} To follow through the definition of *\usecounter*, it helps to consider a specific case, like the following simplification of an example from the \lamstex~Manual (page~78): \Litbox0=** \usecounter\exno\example#1{{\it Example #1.}" } ** $$ \box0 \tag"\style{\hbox{\lower2pt\hbox{\bf\ast}}}" $$ Here we want \setbox1\hbox{*\example*} \setbox2\hbox{*{\it Example \exno.}" *} \setbox3\hbox{*\example""...""*} \setbox4\hbox{*{\it Example {\exno@F_",_",_",...}.}" *} \setbox5\hbox{*\example\label{...}*} \setbox6\hbox{*{\it Example \exno\label{...}.}" *} $$ \centerline{\vbox{\advance\baselineskip\jot \halign{#\hfil&\ \ to give\ \ #\hfil\cr \copy1&\copy2\cr \copy3&\copy4\cr \copy5&\copy6\cr}}} $$ 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 \lamstex~Manual suggest that the user should modify \style\tag{\hbox{\lower2pt\hbox{\bf\ast}}} 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~\ref{DEFFNSSP}) 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 \setbox1\hbox{({\bf E1}) *\example*} \setbox2\hbox{*{\it Example \exno.}" \FNSSP@*} \setbox3\hbox{({\bf E2}) *\example""...""*} \setbox4\hbox{*{\it Example {\exno@F_",_",_",...}.}" \FNSSP@*} \setbox5\hbox{({\bf E3}) *\example\label{...}*} \setbox6\hbox{*{\it Example \exno\label{...}.}" \FNSSP@*} $$ \leftline{\vbox{\advance\baselineskip\jot \halign{#\hfil\cr \copy1\cr \hbox{\hskip30pt to give \copy2}\cr \copy3\cr \hbox{\hskip30pt to give \copy4}\cr \copy5\cr \hbox{\hskip30pt to give\copy6}\cr}}} $$ \medskip 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. \pagelabel{ZZ} 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 \ and \. This suggests that *\usecounter\exno\example* should expand out as ** \def\example{\futurelet\next\exno@@Z} . . . . . . \def\exno@@Z@ ** where the *\def\exno@@Z@* at the end will then swallow up the subsequent \ and \, and thus, in our case, \setbox1\hbox{*\def\exno@@Z@#1{{\it Example #1.}" *} $$\overfullrule=0pt\boxed{\box1}$$ Once we have *\exno@@Z@*, it is easy to say what *\exno@@Z* should do: \Pitem If *\next* is neither *\label* nor *""*, then ({\bf E1}) we want ** {\it Example \exno.}" \FNSSP@ ** which can obtained as ** \exno@@Z@{\exno}\FNSSP@ ** \pitem If *\next* is *""*, so that we have *\example""...""*, then ({\bf 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@ ** \pitem If *\next* is *\label*, so that we have *\example\label{...}*, then ({\bf 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@} \fi\fi\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 {\it 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*: \pagelabel{EXNE} the *\csname"allowbreak..."allowbreak \endcsname* is first expanded to *\exno@F*, and then this expansion is placed in front of *\noexpand*, and consequently {\it not\/} expanded in the *\edef*\,! Similar maneuvers are needed for *\exno@P* \dots; 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~\ref{ZZ}). In this case, the control sequences ** \csname\exstring@#1@@Z\endcsname \csname\exstring@#1@@Z@\endcsname ** would also {\it 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*. \C** \def\usecounter#1#2{\expandafter \ifx\csname\exstring@#1@Z\endcsname\relax \Err@{\noexpand#1not created with \string\newcounter}\fi \expandafter\let\csname\exstring@#1@@Z\endcsname=\relax \expandafter\let\csname\exstring@#1@@Z@\endcsname=\relax "2 \edef\next@{\def\noexpand#2{\futurelet\noexpand\next \csname\exstring@#1@@Z\endcsname}}% \next@ "2 \edef\next@{\def\csname\exstring@#1@@Z\endcsname {\noexpand\ifx\noexpand\next\noexpand\label \def\noexpand\next@\noexpand\label ########1{\csname\exstring@#1@@Z@\endcsname {\noexpand#1\noexpand\label{########1}}\noexpand\FNSSP@}% \noexpand\else "2 \noexpand\ifx\noexpand\next\noexpand""% "2 \def\noexpand\next@\noexpand""########1\noexpand""% {\csname\exstring@#1@@Z@\endcsname{{\expandafter\noexpand \csname\exstring@#1@F\endcsname "2 \let\noexpand\pre= \expandafter\noexpand\csname\exstring@#1@P\endcsname "2 \let\noexpand\post= \expandafter\noexpand\csname\exstring@#1@Q\endcsname "2 \let\noexpand\style= \expandafter\noexpand\csname\exstring@#1@S\endcsname "2 \let\noexpand\numstyle= \expandafter\noexpand\csname\exstring@#1@N\endcsname ########1}}\noexpand\FNSSP@}% "2 \noexpand\else "2 \def\noexpand\next@{\csname\exstring@#1@@Z@\endcsname {\noexpand#1}\noexpand\FNSSP@}% \noexpand\fi\noexpand\fi\noexpand\next@}}% \next@ \expandafter\def\csname\exstring@#1@@Z@\endcsname} ** \chapter Lists\endchapter Now that we've discussed *\tag*, with just one counter *\tag@C*, it seems appropriate to discuss *\list*, because it has five~counters `*\list@C1*', \dots,\linebreak `*\list@C5*', corresponding to the five~levels of a list (Chapter~\ref{acces} explains how this is handled by the *\pre*, *\newpre*, \dots, constructions). As on pages~\ref{QTS1}, \ref{QTS2} and~\ref{QTS3}, \pagelabel{QTS4} we will always use quotation marks around control sequence names like `*\list@C1*', which really have to be named in the file by means of *\csname"allowbreak..."allowbreak\endcsname*. \newcounter\Exno \newnumstyle\Exno{\Alph} \newfontstyle\Exno{\bf} \usecounter\Exno\Topic#1{\medbreak\flushpar{\bf #1.\enspace}\ignorespaces} \section{Style choices\label{liststy}} Lists require four different style decisions, each in five versions, for the five different levels of a list. \newpre\list1{A.} \Topic First, \list \item *\listbi@* will be the material (usually vertical spacing and/or penalties) that goes before the first *\item* at the first level of a list. \item *\listbii@* will be the material that goes before the first *\item* at the second level. \endlist \lamstex\ begins by setting the default values \C** \def\listbi@{\penalty50 \medskip} \def\listbii@{\penalty100 \smallskip} \let\listbiii@=\relax \let\listbiv@=\relax \let\listbv@=\relax ** Thus, \list \item *\listbi@* will produce a *\penalty50 \medskip* before the very first *\item* at the top level of a *\list* (when we define *\item* we will use *\listbi@* only for the first *\item* at the top level [and after the previous paragraph has been ended], so this penalty and space will not apply to later *\item*'s at the top level). \item Similarly, *\listbii@* produces *\penalty100 \smallskip* before the first item at the second level of a list. \item In the default style, nothing is added before the first item at the third through fifth levels. \endlist \newpre\list1{B.} \Topic Next, \list \item *\listmi@* will be the changes to be made in the midst of *\item*'s at the first level (usually changing the left and/or right indentations). \item *\listmii@* will be the changes to be made in the midst of *\item*'s at the second level. \item"" . . . \endlist \lamstex\ sets the default values \C** \def\listmi@{\advance\leftskip by 30pt} \let\listmii@=\listmi@ \let\listmiii@=\listmi@ \let\listmiv@=\listmi@ \let\listmv@=\listmi@ ** Thus, \list \item *\listmi@* will indent the text for *\item*'s at the top level by *30pt*; \item *\listmii@* will indent the text for *\item*'s at the second level by yet another *30pt*; \item"" . . . \endlist As we will see later (page~\ref{btework}), although *\listbiii@*, \dots can be left undefined, it is important to have definitions for *\listmii@*, \dots, even if they are just the same as *\listmi@*. \newpre\list1{C.} \Topic Next, \list\item *\itemi@* will specify the formatting of the *\item* numbers at the first level; \item *\itemii@* will specify the formatting of the *\item* numbers at the second level; \item"" . . . \endlist \lamstex\ sets the default values \C** \def\itemi@#1{\noindent@@\llap{#1\hskip5pt}} \let\itemii@=\itemi@ \let\itemiii@=\itemi@ \let\itemiv@=\itemi@ \let\itemv@=\itemi@ ** For the use of *\noindent@@*, see Chapter~\ref{EVPAR}. Notice that if *\everypar* is non-empty, then new paragraphs within an *\item* (like the one shown on page~17 of the \lamstex~Manual), will have this *\everpar* material before them. \pagelabel{NOAT} (If we wanted to prohibit that, we could simply set *\everypar={}* right after the *\begingroup* in the definition of *\list* to follow, and use *\noindent@* instead of *\noindent@@* at this point.) Thus, \list\item *\itemi@* will format an *\item* number *#1* as\pagelabel{ITEMIAT} ** \noindent@@\llap{#1\hskip5pt} ** The *\llap{#1\hskip5pt}* simply causes the *\item* number to appear *5pt* to the left of the rest of the text; \item Similarly, *\itemii@* formats an *\item* number at the second level in exactly the same way; \item"" . . . \endlist \newpre\list1{D.} \Topic Finally, we have some control sequences that are numbered differently: \list \item *\liste@* will be the formatting (usually vertical spacing and/or penalties) that goes at the end of the last *\item* at the {\it first\/} level; \item *\listei@* will be the formatting that goes at the end of the last *\item* at the {\it second\/} level; \item"" . . . \Reset\list15 \item *\listeiv@* will be the formatting that goes at the end of the last *\item* at the {\it fifth\/} level. \endlist\pagelabel{EE} Thus, for reasons that will become clear (page~\ref{oneless}) these control sequences are ``numbered'' one less than the level to which they apply. \lamstex\ sets the default values \C** \def\liste@{\penalty-50 \medskip} \def\listei@{\penalty-100 \smallskip} \let\listeii@=\relax \let\listeiii@=\relax \let\listeiv@=\relax ** Thus, \list \item *\liste@* will produce *\penalty-50 \medskip* at the end of the list; \item *\listei@* will produce *\penalty-100 \smallskip* when we go from the end of the second level of the list back to the first level; \endlist but nothing will be added when we go from the end of the third level back to the second level, etc. \newpre\list1{} \nopunct\section{Counters, \label{liststy2}etc.} Next we must create the counters `*\list@C1*', \dots,\linebreak `*\list@C5*', which we initialize to *0*: \C** \expandafter\newcount\csname list@C1\endcsname \csname list@C1\endcsname=0 . . . ** We want `*\list@C1*', `*\list@C2*', \dots, in conformity with a general \lamstex\ principle for handling constructions with more than one counter (see Chapter~\ref{acces}), but we use *\listbi@*, *\listbii@*, \dots, 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*', \dots, `*\...C5*' to indicate counters at various levels, we also use `*\...@P1*', \dots for the pre-material at the various levels, and `*\...@Q1*', \dots for the post-material at the various levels. We initialize all of these to be empty: \C** \expandafter\let\csname list@P1\endcsname=\empty . . . \expandafter\let\csname list@Q1\endcsname=\empty . . . ** Then come the styles at each level (compare page~\ref{CCC}): \C** \expandafter\def\csname list@S1\endcsname#1{{\rm(}#1\/{\rm)}} . . . ** Note that these styles determine the formatting of an item number, but the spacing after the formatted number is determined by *\itemi@*, \dots\ (page ~\ref{ITEMIAT}). In conformity with this, style control sequences in \lamstex\ never address the question of the spacing after the formatted number, which has to be handled separately.\pagelabel{SPACESEP} Then come the numbering styles at each level: \C** \expandafter\let\csname list@N1\endcsname=\arabic . . . ** Note that here we once again use *\let* rather than *\def*, just as with *\tag* (page~\ref{TAGATN}), but *\def* would be required for anything other than *\arabic*. Finally, we also need the font styles at each level: \C** \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, \C** \newcount\listlevel@ \listlevel@=0 ** which will always hold the current list level, and then we \C** \def\list@@C{\csname list@C\number\listlevel@\endcsname} \def\list@@P{\csname list@P\number\listlevel@\endcsname} \def\list@@Q{\csname list@Q\number\listlevel@\endcsname} \def\list@@S{\csname list@S\number\listlevel@\endcsname} \def\list@@N{\csname list@N\number\listlevel@\endcsname} \def\list@@F{\csname list@F\number\listlevel@\endcsname} ** so that, for example, *\list@@C* will be `*\list@C1*' if we are at the first level, `*\list@C2*' if we are at the second level, etc. \section{Other preliminaries\label{llevel}} Since, as we've already indicated in section~\Sref{liststy}, the first *\item* at each level needs to be treated specially, we need flags \C** \newif\iffirstitemi@ \newif\iffirstitemii@ \newif\iffirstitemiii@ \newif\iffirstitemiv@ \newif\iffirstitemv@ ** Moreover, we need ways of setting the flag for each level true or false without explicitly mentioning the level: \C** \def\Firstitem@true{\csname firstitem\romannumeral\listlevel@ @true\endcsname} \def\Firstitem@false{\csname firstitem\romannumeral\listlevel@ @false\endcsname} ** We will also need to refer to *\listm...@*, *\item...@*, and *\liste...@* without having to specify the level `*...*'. So we define \C** \def\Listm@{\csname listm\romannumeral\listlevel@ @\endcsname} \def\Item@{\csname listformatt\romannumeral\listlevel@ @\endcsname} \def\Liste@{\csname listformate\romannumeral\listlevel@ @\endcsname} ** (For this to work, we must have *\listm...@*, *\item...@*, defined for all levels; *\Liste@* will be applied only for $1\le\hbox{*\listlevel@*} \allowbreak<\hbox{5}$.)\pagelabel{btework} \medskip Version *1* of \lamstex\ had *\continuelist*, which was meant to be used as ** \continuelist \list . . . \endlist ** although the \lamstex~Manual mistakenly indicated the usage ** \continuelist \item . . . \endlist ** (which would conflict with the general `*\foo ... \endfoo*' convention for \lamstex\ constructions). This was a natural mistake to make, however, so now `*\continuelist*' has been replaced by `*\keepitem*'. *\keepitem* itself will simply set a flag, \C** \newif\iflistcontinue@ \def\keepitem{\listcontinue@true} ** while *\endlist* will always reset *\listcontinue@false*. \section{\CS{list}\label{list}} Unlike the case of *\tag*, whenever we start a *\list* we want to reset the list counters `*\list@C1*', \dots\ to~ *0*, except if *\keeplisting* is in force, in which case `*\list@C1*' will not be changed.\pagelabel{reset} 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: \footnote{An *\item* outside a *\list* will continue to have its usual meaning from *plain* \tex@, though it might be preferable to specify *\Invalid@\item* (see section~\Sref{K}) and to *\let\itemitem="allowbreak\undefined*, since that usage more or less conflicts with \lamstex\ usage.} ** \def\list{% \iflistcontinue@\else \global\csname list@C1\endcsname=0 \fi "2 \global\csname list@C2\endcsname=0 "2 \global\csname list@C3\endcsname=0 "2 \global\csname list@C4\endcsname=0 "2 \global\csname list@C5\endcsname=0 "2 \begingroup \firstitemi@true \listlevel@=1 "2 \def\item{\futurelet\next\item@} ** At this point it might seem like it's time to end the previous paragraph, and get down to work. But we need a slight diversion, because we are also going to allow the possibility that *\list* is followed by *\runinitem* instead of *\item*, as in \amstex@. So we also need a *\futurelet* for that: \C** \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 \def\item{\futurelet\next\item@}% \futurelet\next\list@} ** *\runinitem* has no role except to serve as an indicator after *\list* [or after *\inlevel*, since we also allow *\runinitem* to be used instead of the first *\item* at each level], so (compare section~\Sref{K}) we first state \C** \Invalid@\runinitem ** In the definition of *\list@*, the test *\ifx\next\runinitem* can be used to detect if *\list* is followed by *\runinitem*. If *\list@* detects a *\runinitem*, it will then swallow this *\runinitem* and do yet another *\futurelet* (to see if *\runinitem* is followed by a quoted number). Otherwise, the first thing *\list@* should do is to end the current paragraph. At this point, however, the default style adds some adjustment for the space between paragraphs, since paragraphs are allowed within each *\item*. If our style does leave some space, say *1pt*, between paragraphs, we probably want to do the same for paragraphs within each *\item*. Normally, however, *\parskip* is something like `*0pt 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@ "8ELIM"8 ** (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@}\fi\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. \footnote{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@*: \C** \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@}% \fi\fi\next@} ** Leaving aside the definition of *\runinitem@* for the moment, we consider the case where *\item* occurs next. \section{\CS{item}\label{item}} *\item* 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 \C** \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.\pagelabel{runin}. In either of these cases, the appropriate flag for first *\item*'s at this level (*\iffirstitemi@* or *\iffirstitemii@* or \dots) will be {\it false}. The first thing *\item@* adds is ** \ifoutlevel@\Liste@\outlevel@false\fi ** So, for example, if our *\item* occurs at the top level ($ \hbox{*\listlevel@*}=\hbox{1}$), and we have just completed *\item*'s at the second level, we will add *\listei@*---recall (page~\ref{EE}) that this is the formatting that goes at the end of the last *\item* at the {\it second\/} level.\pagelabel{oneless} The reason for this approach is that in a situation like ** \list \item ... "2 \inlevel \item ... "2 \inlevel "2 \item ... \item ... "9\outlevel"9 "9\outlevel"9 \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 {\it 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*. \pagelabel{outlevel} 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 ** \listbi@ \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~\Sref{Outlevel}). Analogous code is added for the situation where we are at the second level (*\iffirstitemii@...\fi*); in this case, *\listbii@* will be occurring after the *\par* supplied by the previous code. And similarly for the third through fifth levels. Each of these *\iffirstitem...@* tests has to be made separately, and *\listbi@*, \dots\ 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 ** with *\next@* and *\nextii@* defined first.%\pagelabel{a\ b} The definitions of *\next@* and *\nextii@* are quite similar to the definitions of *\maketag@@@* and *\maketag@@@@*, using *\Qlabel@* from section~\Sref{maketag} for ``quoted'' *\item* numbers, but with some additions: ** \def\next@""##1""{{\let\pre=\list@@P \let\post=\list@@Q \let\style=\list@@S \let\numstyle=\list@@N "9\vskip-\parskip"9 \Item@{\list@@F##1}% \noexpands@ \Qlabel@{##1}}% \locallabel@ "9\FNSSP@"9}% "slip \def\nextii@{\global\advance\list@@C by 1 {\noexpands@ \xdef\Thelabel@@@{\number\list@@C}% \xdefThelabel@\list@@N \xdef\Thelabel@@@@{\list@@P\Thelabel@\list@@Q}}% \xdefThelabel@@\list@@S }% \locallabel@ "9\vskip-\parskip"9 \Item@{\list@@F\thelabel@@}% "9\futurelet\next\pretendspace@"9}% ** We add the *\vskip-\parskip* because *\Item@* will normally start a new paragraph, and we want the spacing before the *\item* to be explicitly specified by *\listbi@*, \dots, and not involve any *\parskip*, which is easy to forget about. And we add the *\FNSSP@* and *\futurelet\next\pretendspace@*'s because *\Item@* puts us into horizontal mode\pagelabel{NEEDFP} (in the default style it also produces some space after the *\item* number---the *\hskip5pt* at the end of the *\llap* in the definition of *\item...@*---but this space is ``hidden'' inside the *\llap*, and will not be discovered by *\lastskip*). So (compare section~\Sref{ZZZ}) ** \item \label{...}" Text ... ** would leave an extra space before the ``Text \dots''. 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~\ref{DDD}). 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 \dots, 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:\pagelabel{ADEQ} 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 \dots, will be inserted. Thus, the definition of *\item@* is: \C** \def\item@{% \ifoutlevel@\Liste@\outlevel@false\fi "2 \ifrunin@\runin@false\par \dimen@=\parskip \parskip=\dimen@ \Listm@\fi "2 \iffirstitemi@ \listbi@\listmi@\firstitemi@false \else\par\fi "2 \iffirstitemii@ \listbii@\listmii@\firstitemii@false \else\par\fi "2 \iffirstitemiii@ \listbiii@\listmiii@\firstitemiii@false \else\par\fi "2 \iffirstitemiv@ \listbiv@\listmiv@\firstitemiv@false \else\par\fi "2 \iffirstitemv@ \listbv@\listmv@\firstitemv@false \else\par\fi "2 \def\next@""##1""{{\let\pre=\list@@P \let\post=\list@@Q "8LISTQ"8 \let\style=\list@@S \let\numstyle=\list@@N "2 \vskip-\parskip \Item@{\list@@F##1} "2 \noexpands@ \Qlabel@{##1}}% "2 \locallabel@ \FNSSP@}% "2 \def\nextii@{\global\advance\list@@C by 1 {\noexpands@ "2 \xdef\Thelabel@@@{\number\list@@C}% \xdefThelabel@\list@@N "2 \xdef\Thelabel@@@@{\list@@P\Thelabel@\list@@Q}}% \xdefThelabel@@\list@@S }% "2 \locallabel@ "2 \vskip-\parskip \Item@{\list@@F\thelabel@@}% "2 \futurelet\next\pretendspace@}% \ifx\next""\expandafter\next@\else\expandafter\nextii@\fi} ** \section{\CS{runinitem\@}} *\runinitem@* is similar to, but simpler than, *\item@*. First, *\runinitem@* sets *\ifrunin@true* and *\Firstitem@false* (to be used by the next *\item* [page~\ref{runin}]). The preliminary formatting of *\item@* isn't necessary, so *\runinitem@* then immediately defines *\next@* and\linebreak *\nextii@* for the compressed format: ** \def\next@""##1""{{\let\pre=\list@@P \let\post=\list@@Q \let\style=\list@@S \let\numstyle=\list@@N \unskip\space{\list@@F##1}"9" "9% \noexpands@ \Qlabel@{##1}}% \locallable@ \ignorespaces} "slip \def\nextii@{\global\advance\list@@C by 1 {\noexpands@ "2 \xdef\Thelabel@@@{\number\list@@C}% \xdefThelabel@\list@@N "2 \xdef\Thelabel@@@@{\list@@P\Thelabel@\list@@Q}}% \xdefThelabel@@\list@@S }% \locallabel@ \unskip\space{\list@@F\thelabel@@}"9" "9} ** In other words, after suitably defining *\thelabel@*, \dots, 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: \C** \def\runinitem@{% \runin@true \Firstitem@false "2 \def\next@"##1"{{\let\pre=\list@@P \let\post=\list@@Q \let\style=\list@@S \let\numstyle=\list@@N \unskip\space{\list@@F##1}" % \noexpands@ \Qlabel@{##1}}% \locallabel@ \ignorespaces}% "2 \def\nextii@{\global\advance\list@@C by 1 {\noexpands@ "2 \xdef\Thelabel@@@{\number\list@@C}% "2 \xdefThelabel@\list@@N "2 \xdef\Thelabel@@@@{\list@@P\Thelabel@\list@@Q}}% \xdefThelabel@@\list@@S }% "2 \locallabel@ \unskip\space{\list@@F\thelabel@@}" }% \ifx\next""\expandafter\next@\else\expandafter\nextii@\fi} ** \section{\CS{inlevel}\label{inlevel}} We will keep each level of a list within its own group, to localize *\listlevel@*, etc. *\inlevel* will simply produce an error message if *\listlevel@* is already ~*5*. Otherwise it will provide a *\begingroup* and advance *\listlevel@* by~ 1; notice that this is {\it not\/} a *\global\advance*: the value of *\listlevel@* will be different within the different groups provided by different levels. Then we will set *\Firstitem@true* (i.e., set *\firstitemii@true* if we are at now at the second level, *\firstitemiii@true* if we are now at the third level, etc.). No special formatting has to be done by *\inlevel*, because, once *\listlevel@* has been correctly set, each *\item* will take care of all necessary formatting. But we are not quite done, because we need a *\futurelet* to see if a *\runinitem* follows: \C** \def\inlevel{\ifnum\listlevel@=5 \def\next@{\Err@{Already 5 levels down}}\else \def\next@{\begingroup\advance\listlevel@ by 1 \Firstitem@true\futurelet\next\inlevel@}\fi\next@} ** If *\inlevel@* detects a *\runinitem*, it just has to swallow this *\runinitem* and call *\futurelet\next\runinitem@*, exactly like *\list*; otherwise nothing remains to be done at all. However, just as in the case of *\list@*, we must also allow the possibility that a *\par* precedes a *\runinitem* \footnote{As in the case of *\list*, there's no way we can allow a blank line to occur before *\inlevel* in an `*\inlevel\runinitem*' combination; when a run-in *\item* is required at a new level, the *\inlevel* must appear in the same paragraph as the previous text.}: \C** \def\inlevel@{\ifx\next\par \def\next@\par{\futurelet\next\inlevel@}\else \ifx\next\runinitem \def\next@\runinitem{\futurelet\next\runinitem@}\else \let\next@=\relax\fi\fi\next@} ** \section{\CS{outlevel}\label{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.\pagelabel{ebeforee} 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*).\pagelabel{OUT} Finally, we want to set *\outlevel@true*, for use by the next *\item* (page~\ref{runin}~ff.). \C** \def\outlevel{\ifnum\listlevel@=1 \Err@{At top level}\else \par\global\list@@C=0 \endgroup\outlevel@true\fi} ** \section{\CS{endlist}\label{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={}% \count@=\listlevel@ {\loop "2 \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~\ref{reset}], even though *\outlevel* resets the counter for its level [\recentpageref{OUT}{see above}{see the previous page}{page~\value\page}].) The *\loop* is enclosed within a group for the unlikely eventuality that some *\list"allowbreak..."allowbreak\endlist* occurs within a *\loop* construction (compare page~\ref{POSSLOOP}). Because of this, we need a *\global* assignment of the token list, so we use *\toks1* (compare section~\Sref{LANDG}); 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~\ref{EE}), 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\pagelabel{listnopar} ** \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 {\it also\/} before the text following the *\par*. Together with the *\vskip-\parskip*, this means that 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\pagelabel{ADDFNP} ** \futurelet\next\pretendspace@ ** in case an invisible construction like *\pagelabel* happens to appear after the *\endlist* (compare page~\ref{NEEDFP}). Thus, the definition of *\endlist* is: \C** \def\endlist{\par "2 \global\toks1={}% \count@=\listlevel@ "2 {\loop \ifnum\count@>0 \global\toks1=\expandafter{\the\toks1 \endgroup}% \advance\count@ by -1 \repeat}% "2 \the\toks1 "2 \liste@ "2 \listcontinue@false "2 \vskip-\parskip \noindent@@ \futurelet\next\pretendspace@} ** \small! As on page~\ref{BADOUTER}, \pagelabel{BADOUTER2} note that if *\bye* were *\outer*, then *\endlist\bye* would give an error message. \endsmall 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 *\par* comes next (such uses of *\futurelet* in sections ~\Sref{list} and~\Sref{inlevel} were quite different---they were meant only to {\it 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 \setbox0\hbox{\}% ** \edef\parskip@{\parskip=\the\parskip} \parskip="box0 \noindent@@ \futurelet\next\pretendspace@ ** [The construction ** \edef\parskip@{\parskip=\the\parskip} "8=the"8 ** is similar to the construction ** \edef\@sf{\spacefactor\the\spacefactor} ** used in *plain* \tex@: the primitive *\parskip* is not expanded in the *\edef*, but `*\the*' {\it is\/} expanded, so *\parskip@* means \setbox0\hbox{\}% \setbox1\hbox{`}\setbox2\hbox{'} ** "box1\parskip="box0"box2 ** after the *\edef* is finished.] \chapter\CS{describe} and \CS{margins}\endchapter Although *\describe* and *\margins* don't really come next by any logical imperative, they come next in \lamstex\ because they are so similar to *\list*. \section{\CS{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*: \C** \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: \C** \def\describe{\par \begingroup \firstdescribe@true "2 \def\item##1{% \iffirstdescribe@ \penalty50 \medskip \vskip-\parskip \firstdescribe@false\else\par\fi \hangindent2pc \hangafter1 \noindent@@{\bf##1}\hskip.5em} ** (compare page~\ref{NOAT} for the use of *\noindent@@*). In the definition of *\item*, the ** \penalty50 \medskip \vskip-parskip \hangindent2pc \hangafter1 \noindent \noindent@@{\bf##1}\hskip.5em ** represent 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*: \C** \def\enddescribe{\par \penalty-50 \medskip\vskip-\parskip \endgroup} ** Since *\describe...\enddescribe* {\it 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~\ref{listnopar}); of course, they could always be added for a style that wants to handle this question differently. \section{\CS{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~\Sref{K}), \C** \Invalid@\pullin \Invalid@\pullinmore ** There is no special formatting before the first paragraph of a *\margins* construction. Nevertheless, we still need a flag \C** \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 {\it first\/} *\pullin* should not provide this extra *\endgroup*. *\margins*, like *\describe*, will end the previous paragraph, begin a group, set *\firstpull@true*, and then define *\pullin* and *\pullinmore*: ** \def\margins{\par\begingroup\firstpull@true \def\pullin##1##2{...}% \def\pullinmore##1##2{...}} ** *\pullin* will end the previous paragraph, and supply an *\endgroup*, except for the first *\pullin*, as already indicated, and then start yet another group: ** \def\pullin##1##2{\par \iffirstpull@\firstpull@false\else\endgroup\fi \begingroup ** (Notice that it is important to have the *\par* before the *\endgroup*, compare page~\ref{ebeforee}.) In this new group we want to set *\leftskip=##1* and *\rightskip=##2*. But we want \setbox0\hbox{or} ** \pullin{}{...} "box0 \pullin{" }{...} ** to yield *\leftskip=0pt*, and similarly for the second argument, so we explicitly have to check for these possibilities: ** \def\next@{##1}% \ifx\next@\empty\leftskip=0pt\else \ifx\next@\space\leftskip=0pt\else \leftskip=##1\fi\fi \def\next@{##2}% \ifx\next@\empty\rightskip=0pt\else \ifx\next@\space\rightskip=0pt\else \rightskip=##1\fi\fi\ignorespaces} ** The final *\ignorespaces* is needed to get rid of any spaces following the *\pullin{...}{...}*. 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 *0pt*, instead of simply leaving it alone. Since no other \lamstex\ 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 *0pt* 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=0pt\relax*' and `*\rightskip=0pt\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\rightskip} ** The effect of this *\xdef* (compare page~\ref{=the}) is to make *\Next@* mean \setbox0\hbox{\} \setbox1\hbox{\} ** \leftskip="box0 \rightskip="box1 ** We need *\xdef* rather than *\edef*, because this will be followed by an *\endgroup*; then, after the following *\begingroup* we can reinstate these values, before using the arguments of *\pullinmore* to decide how much to *\advance\leftskip* or *\advance\rightskip*: ** \def\pullinmore##1##2{\par \xdef\Next@{\leftskip=\the\leftskip \rightskip=\the\rightskip}% "2 \iffirstpull@\firstpull@false\else\endgroup\fi "2 \begingroup "2 \Next@ \def\next@{##1}% \ifx\next@\empty\else\ifx\next@\space\else \advance\leftskip by ##1\fi\fi "2 \def\next@{##2}% \ifx\next@\empty\else\ifx\next@\space\else \advance\rightskip by ##1\fi\fi \ignorespaces} ** We use the scratch token *\Next@* here, because it has been reserved for *\global* assignments (page~\ref{GNXT}). Thus, the definition of *\margins* is \C** \def\margins{\par\begingroup\firstpull@true \def\pullin##1##2{\par \iffirstpull@\firstpull@false\else\endgroup\fi "2 \begingroup \def\next{##1}% \ifx\next@\empty\leftskip=0pt\else \ifx\next@\space\leftskip=0pt\else \leftskip=##1\fi "2 \def\next{##2}% \ifx\next@\empty\rightskip=0pt\else \ifx\next@\space\rightskip=0pt\else \rightskip=##2\fi\fi \ignorespaces}% "2 \def\pullinmore##1##2{\par \xdef\Next@{\leftskip=\the\leftskip \rightskip=\the\rightskip}% "2 \iffirstpull@\firstpull@false\else\endgroup\fi "2 \begingroup \Next@ \def\next@{##1}% \ifx\next@\empty\else\ifx\next@\space\else \advance\leftskip by ##1\fi\fi "2 \def\next@{##2}% \ifx\next@\empty\else\ifx\next@\space\else \advance\rightskip by ##2\fi\fi \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*): \C** \def\endmargins{\par\endgroup\endgroup} ** \chapter \CS{nopunct}, \CS{nospace}, and \CS{overlong}\endchapter 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 \lamstex\ handled with the *\nofrills* construction. \section{\CS{nopunct}, \CS{nospace}, and \CS{overlong}\label{AGONY}} In \amstex's *amsppt* 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 \lamstex\ (see the small print on page~\ref{NOFC}). In version~*2* of \lamstex@, *\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 \lamstex\ 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 \lamstex@, *\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 \C** \newif\ifnopunct@ \newif\ifnospace@ \newif\ifoverlong@ ** a list, initialized as \C** \let\nofrillslist@=\empty ** of constructions to which both *\nopunct* and *\nospace* can apply, and a list, initialized as \C** \let\overlonglist@=\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*: \C** \def\nopunct{\nopunct@true\futurelet\next\nopunct@} \def\nospace{\nospace@true\futurelet\next\nospace@} \def\overlong{\overlong@true\futurelet\next\overlong@} ** 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*: \C** \def\nopunct@{% \ifx\next\nospace \def\next@\nospace{\nospace@true\futurelet\next\nopnos@}% \else \ifx\next\overlong \def\next@\overlong{\overlong@true\futurelet\next\nopol@}% \else \let\next@=\nopunct@@ \fi\fi\next@} ** We reach *\nopunct@@* when neither *\nospace* nor *\overlong* follows our original *\nopunct*, so now we have to check whether the control sequence that follows is in *\nofrillslist@*. If so, we simply execute this control sequence (the flag *\ifnopunct@* has already been set true); otherwise we reset *\ifnopunct@* to be false and give an error message, and still execute the control sequence: \C** \def\nopunct@@#1{\ismember@\nofrillslist@#1% \iftest@ \let\next@=#1% \else \def\next@{\nopunct@false \Err@{\noexpand\nopunct can't be used with \string#1}#1}$% \fi\next@} ** (We use an argument *#1* for *\nopunct@@*, 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 *\noexpand* in this, any future, error messages, compare section~\Sref{SACN}. Temporarily leaving aside *\nopnos@* and *\nopol@*, the other possible outcomes of *\nopunct@*, we use basically the same procedures for *\nospace@* and *\overlong@*: \C** \def\nospace@{% \ifx\next\nopunct \def\next\nopunct{\nopunct@true\futurelet\next\nopnos@}% \else \ifx\next\overlong \def\next@\overlong{\overlong@true\futurelet\next\nosol@}% \else \let\next@=\nospace@@ \fi\fi\next@} ** (notice that we use the same *\nopnos@* that appeared in *\nopunct@*) \C** \def\nospace@@#1{\ismember@\nofrillslist@#1% "2 \iftest@ \let\next@=#1% "2 \else \def\next@{\nospace@false \Err@{\noexpand\nospace can't be used with \string#1}#1}% \fi\next@} "2 \def\overlong@{% \ifx\next\nopunct \def\next@\nopunct{\nopunct@true\futurelet\next\nopol@}% \else \ifx\next\nospace \def\next@\nospace{\nospace@true\futurelet\next\nosol@}% \else \let\next@=\overlong@@ \fi\fi\next@} ** (notice that we use the same *\nopol@* and *\nosol@* that appeared in *\nopunct@* and *\nospace@*) \C** \def\overlong@@#1{\ismember@\overlonglist@#1% \iftest@ \let\next@=#1% \else \def\next@{\overlong@false \Err@{\noexpand\overlong 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: \C** \def\nopnos@{\ifx\next\overlong \def\next@\overlong{\overlong@true\nopnosol@}\else \let\next@=\nopnos@@\fi\next@} "2 \def\nopol@{\ifx\next\nospace \def\next@\nospace{\nospace@true\nopnosol@}\else \let\next@=\nopol@@\fi\next@} "2 \def\nosol@{\ifx\next\nopunct \def\next@\nopunct{\nopunct@true\nopnosol@}\else \let\next@=\nosol@@\fi\next@} ** The first of the newly created possibilities, *\nopnos@@* is easy: \C** \def\nopnos@@#1{\ismember@\nofrillslist@#1% \iftest@ \let\next@=#1% \else \def\next@{\nopunct@false\nospace@false \Err@{\noexpand\nopunct\noexpand\nospace can't be used with \string#1}#1}% \fi\next@} ** Notice that we may be giving the error message ** \nopunct \nospace can't be used with ... ** not worrying about niceties like commas between *\nopunct* and *\nospace*! For the next two, which require testing for both *\nofrillslist@* and *\overlonglist@*, we will *\let\nextiii@=T* or *F*, depending on whether or not the argument is in *\nofrillslist@*, and *\let\nextiv@=T* or *F*, depending on whether or not the argument is in *\overlonglist@*; we use *\nextiii@* and *\nextiv@* because *\ismember@* redefines *\next@* and *\nextii@*. It helps to define a routine that makes these tests, and then also sets *\iftest@* to be true precisely when both of the tests were positive: \C** \def\testii@#1{\ismember@\nofrillslist@#1% \iftest@\let\nextiii@=T\else\let\nextiii@=F\fi \ismember@\overlonglist@#1% \iftest@\let\nextiv@=T\else\let\nextiv@=F\fi \test@false \if\nextiii@ T\if\nextiv@ T\test@true\fi\fi} ** Then we define *\nopol@@* and *\nosol@@*: \C** \def\nopol@@#1{\testii@{#1}% \iftest@ \let\next@=#1% \else\def\next@{\if\nextiii@ T\else\nopunct@false\fi \if\nextiv@ T\else\overlong@false\fi \Err@{\if\nextiii@ T\else\noexpand\nopunct\fi \if\nextiv@ T\else\noexpand\overlong\fi can't be used with \string#1}#1}% \fi\next@} "2 \def\nosol@@#1{\testii@{#1}% \iftest@\let\next@=#1% \else\def\next@{\if\nextiii@ T\else\nospace@false\fi \if\nextiv@ T\else\overlong@false\fi \Err@{\if\nextiii@ T\else\noexpand\nospace\fi \if\nextiv@ T\else\noexpand\overlong\fi can't be used with \string#1}#1}% \fi\next@} ** Finally, *\nopnosol@*---when *\nopunct*, *\nospace*, and *\overlong* have all appeared---works almost the same: \C** \def\nopnosol@#1{\testii@{#1}% \iftest@\let\next@=#1% \else\def\next@{% \if\nextiii@ T\else\nopunct@false\nospace@false\fi \if\nextiv@ T\else\overlong@false\fi \Err@{% \if\nextiii@ T\else\noexpand\nopunct\noexpand\nospace\fi \if\nextiv@ T\else\noexpand\overlong\fi can't be used with \string#1}#1}% \fi\next@} ** \section{Using the flags} The additional punctuation for constructions that allow *\nopunct@* will be added precisely when *\ifnopunct@* is false, so we introduce an abbreviation for that: \C** \def\punct@#1{\ifnopunct@\else#1\fi} ** Similarly, we have \C** \def\addspace@#1{\ifnospace@\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 \C** \def\hss@{\ifoverlong@ 0pt plus1000pt minus1000pt \else 0pt plus1000pt\fi} ** So both stretch and shrink will be allowed when *\ifoverlong@* has been set true, but only stretch will be allowed otherwise.\pagelabel{HSS} \chapter\CS{demo} \label{Demo}\endchapter Since *\demo* is one of the constructions to which *\nopunct* and *\nospace* should apply, we put it in *\nofrillslist@*: \C** \rightadd@\demo\to\nofrillslist@ ** As in \amstex@, we will introduce a new flag, \C** \newif\ifclaim@ ** so that each *\claim* can set *\ifclaim@* to be true (within the group that that *\claim* will begin). Then *\demo* can give an error message when *\ifclaim@* is true, since we shouldn't be giving a proof within the statement of a *\claim*. (On the other hand, *\claim* will not make a similar check regarding *\demo*, since we {\it could\/} be stating subsidiary *\claim*'s within a *\demo*. In fact, the flag *\ifclaim@* is used only by *\demo*, since virtually anything other than a *\demo* can come within a *\claim*.) As we will see in the next chapter, whenever we have started a *\claim*, or something like *\Thm* that has been constructed using *\newclaim* or *\shortenclaim*, not only will *\ifclaim@* be true, but also *\claimtype@* will be defined to be *\claim* or *\Thm*, etc. So we can give an error message that mentions *\claim* when we are in the middle of a general *\claim*, but will instead state ** Previous \Thm has no matching \endThm ** when we are in the middle of a *\Thm* produced with *\newclaim*, etc. We can do this with ** \Err@{Previous \expandafter\noexpand\claimtype@ has no matching \string\end \expandafter\expandafter\expandafter\eat@\expandafter \string\claimtype@} ** Here (compare page~\ref{EXNE})\pagelabel{EXNE2} the *\expandafter* is expanded in the error message, so *\claimtype@* is expanded---to *\claim*, *\Thm*, or whatever---% before having *\noexpand* placed in front of it, which then prevents further expansion. See {\it The \tex book}, page~374 for the triple *\expandafter*;\pagelabel{tEXA} here *\claimtype@* is expanded first, to *\claim* or *\Thm*, etc., then *\string* is applied to this, and then *\eat@* (section~\Sref{AC}) is applied to the result of this *\string*, thus eating the *\* at the beginning of the *\string\claim* or *\string\Thm* or whatever. (Finally, see section~ \Sref{SACN} for the spacing after the *\noexpand*'ed control sequence.) {\advance\litindent-10pt The combination ** \expandafter\expandafter\expandafter\eat@\expandafter\string ** will} occur quite frequently, so we abbreviate it: \C** \def\exxx@{\expandafter\expandafter\expandafter "8EXXX"8 \eat@\expandafter\string} ** Normally (i.e., when *\ifclaim@* is false), *\demo#1* will end the previous paragraph and add a *\smallskip* (deleting the previous skip if smaller, or using the previous skip instead, if it is larger). Then it will begin a group and start an unindented paragraph with *#1* in *\smc* (with spaces before and after *#1* ignored, since they are presumably typing errors); we use *\noindent@@* for this (Chapter~\ref{EVPAR}). This will be followed by a colon, unless *\nopunct@* preceded the demo, ** \punct@: ** and an *\enspace*, unless *\nospace* preceded the *\demo*, ** \addspace@\enspace ** Instead of typing a (type~*12*)~*:*, we will \C** \let\colon@=: "8COLONAT"8 ** and use *\colon@* instead, so that a French style that makes *:*~active can change *\colon@* (compare~\Sref{ALF}). Moreover, we will use ** \punct@{\null\colon@} "8NULLPUNCT"8 ** 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 *\ifnopunct@* and *\ifnospace@* 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 \C** \def\demo#1{\ifclaim@ "2 \Err@{Previous \expandafter\noexpand\claimtype@ has no matching \string\end\exxx@\claimtype@}% \let\next@=\relax "2 \else \par "2 \ifdim\lastskip<\smallskipamount \removelastskip\smallskip\fi "2 \begingroup "2 \noindent@@{\smc\ignorespaces#1\unskip \punct@{\null\colon@}\addspace@\enspace}% "2 \nopunct@false\nospace@false \rm \def\next@{\FNSSP@}% \fi \next@} ** \pagebreak *\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*: \C** \def\enddemo{\par\endgroup \nopunct@false\nospace@false\smallskip} ** \chapter \CS{claim}'s\endchapter Now we come to *\claim* and related constructions, one of the more complicated complexes in \lamstex. \section{Preliminaries} First of all, *\claim* is another thing that can follow *\nopunct*, so we add it to *\nofrillslist@*: \C** \rightadd@\claim\to\nofrillslist@ ** The fontstyle for *\claim*'s, \C** \def\claim@F{\smc} ** will be needed right away, but, in fact, we will need something more general. In Chapter~\Sref{Demo}, we pointed out that *\claimtype@* will be defined to be *\claim* when we have started an ordinary *\claim*, but *\Thm* when we have started a construction like *\Thm* that has been constructed with *\newclaim* or *\shortenclaim*. Each construction like *\Thm* will have an associated font style *\Thm@F*@. This can be named (see page~\ref{EXSTRING}) as ** \csname\exstring@\Thm @F\endcsname ** or, more generally (recall the definition of *\exxx@* on page~\ref{EXXX}), as ** \csname\exxx@\claimtype@ F\endcsname ** Since we often need to refer to this general font style, we introduce the special construction \C** \def\claim@@@F{\csname\exxx@\claimtype@ @F\endcsname} ** [We use a triple *@@@*, rather than the double *@@* used in *\list@@F* to emphasize the distinction: *\list@@F* depends on the value of the counter *\listlevel@*, the level of a *\list*, while *\claim@@@F* depends on *\claimtype@*, the name of the *\claim*.] Now we can introduce *\claimformat@* to indicate the general format of a *\claim*: \C** \def\claimformat@#1#2#3{\medbreak \noindent@@{\smc#1 {\claim@@@F#2} #3% \punct@{\null.}\addspace@\enspace}\sl} ** (Compare page~\ref{NULLPUNCT} for the `*\null.*'\pagelabel{QW3} and Chapter~\ref{EVPAR} 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~\Sref{MODC} explains how a style file can modify *\claimformat@* to deal with numerous possibilities for formatting different sorts of *\claim*s in different ways. \section{\CS{claimformat\@\@}} Since *\claimformat@* is meant to be easily modified by a style designer, it omits several messy details: \list\item Any extraneous spaces at the beginning and end of arguments *#1* and *#3* should be removed. \item If *#3* is empty, or a space (which occurs if the user types *{ }* instead of *{}*), then the space before it must be removed. \item *#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. \item A space following the *\claim{...}{...}* should be ignored; more generally, we need *\FNSSP@*, in case an invisible construction follows. \endlist So instead of using *\claimformat@* directly, we will use *\claimformat@@*, which calls *\claimformat@* with all these details added. When we are using *\claimformat@@*, the control sequence *\thelabel@@* will contain the properly formatted claim number. \footnote{The formatting of the *\claim* number is specified by *\claim@S*---it should not be specified directly in *\claimformat@*.} In the definition below, argument *#2* corresponds to argument *#3* for *\claimformat@*. Only the next-to-last line of code needs further amplification. \C** \def\claimformat@@#1#2{% \claimformat@{\ignorespaces#1\unskip}% "2 {\ifx\thelabel@@\empty\unskip\else\thelabel@@\fi}% "2 {\ignorespaces#2\unskip}% "2 \let\Claimformat@@=\claimformat@@ \FNSSP@} ** 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~\Sref{MODC} 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@@*, which we will initially set to be the same as *\claimformat@@*: \C** \let\Claimformat@@=\claimformat@@ ** 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@@*, and hence ** \claimformat@@{Theorem} ** so that the `Theorem' label will automatically be inserted. Although the final *\endclaim* will return *\Claimformat@@* to its original state, so that any subsequent *\claim* will just be using *\claimformat@@* (unless it happens to be called by another construction that redefines *\Claimformat@@*), we add ** \let\Claimformat@@=\claimformat@@ ** at this point, just to minimize problems if the user forgets the *\endclaim*. \section{Further preliminaries} Although we won't consider all the complications of *\newclaim* until later, there are several other aspects that we need to mention before moving on. We've already used *\claimtype@* to define *\claim@@@F*. More generally, we will \C** \def\claim@@@P{\csname\exxx@\claimtype@ @P\endcsname} "2 \def\claim@@@Q{\csname\exxx@\claimtype@ @Q\endcsname} "2 \def\claim@@@S{\csname\exxx@\claimtype@ @S\endcsname}"8atat"8 "2 \def\claim@@@N{\csname\exxx@\claimtype@ @N\endcsname} ** The counter has to be treated differently, however, for the following reason. If the user directly types something like ** \claim\c{thm} ** then the style, numbering style, pre- and post-material for this *\claim* are just the standard ones. {\it But a new counter must be involved}, since such *\claim*'s are to be numbered independently from other *\claim*'s; this new counter is required even if no *\newclaim* construction has been used. To keep track of these different numbering classes, we will introduce *\claimclass@* in addition to *\claimtype@*. \setbox0\hbox{\} A *\claim* with a particular ``class'', produced by ** \claim\c{"copy0} ** defines *\claimclass@* to be this \ (ordinary *\claim*'s, which are equivalent to *\claim\c{}*, define *\claimclass@* to be empty). And the *\newclaim* construction ** \newclaim\Thm\c{thm}{Theorem} ** 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: \C** \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. \section{Starting a \CS{claim}} First we introduce the other components of a printed *\claim* number: \C** \newcount\claim@C \claim@C=0 \let\claim@P=\empty \let\claim@Q=\empty \def\claim@S#1{#1\/} \let\claim@N=\arabic ** Compare page~\ref{TAGATN} for the `*\let\claim@N=\arabic*'. *\claim* initializes *\ifclaim@* to be true, *\claimclass@* to be empty, and *\claimtype@* to be *\claim*, and then uses a *\futurelet* to see if we are ``quoting'' the claim number with a *""* or specifying a claim class with *\c*: \C** \def\claim{\claim@true \let\claimclass@=\empty\def\claimtype@{\claim}% \futurelet\next\claim@} ** If *\claim* is followed by *\c*, we will use *\claim@c*, and if it is followed by~ *""* we will use *\claim@q*, ** \def\claim@{% \ifx\next\c \let\next@=\claim@c \else \ifx\next""% \let\next@=\claim@q \else . . . ** Otherwise, we will use ** \begingroup ** to begin a group. [The definitions of *\claim@c* (section~\Sref{clc}) and *\claim@q* (section~\Sref{clq}) will each begin with *\begingroup* also; but we don't simply put the *\begingroup* into the definition of *\claim* because, as we will see later (page~\ref{bsc}), constructions produced by *\newclaim* or *\shortenclaim* lead us directly to *\claim@c*, without passing through *\claim*.] Then we will advance the *\claim* counter by *1*, define *\thelabel@*, \dots\ in the usual way, and then call *\Claimformat@@*. In the following, we can use *\claim@C*, \dots\ rather than the more general *\claim@@@C*, \dots\ because, as we have just mentioned, this clause of *\claim@* will only be called directly by *\claim*, never indirectly by something created by *\newclaim*: \C** \def\claim@{% \ifx\next\c \let\next@=\claim@c "2 \else \ifx\next""% \let\next@=\claim@q "2 \else \begingroup \global\advance\claim@C by 1 "2 {\noexpands@ \xdef\Thelabel@@@{\number\claim@C}% \xdefThelabel@\claim@N \xdef\Thelabel@@@@{\claim@P\Thelabel@\claim@Q}}% \xdefThelabel@@\claim@S }% \locallabel@ \let\next@=\Claimformat@@ \fi \fi \next@} ** \section{Starting a \CS{claim\@c}\label{clc}} The definition of *\claim@c* begins ** \def\claim@c\c#1{\claim@true\begingroup ** so that *\claim@c* swallows up the succeeding *\c*, sets *\ifclaim@* to be true, and then begins a group. We add the *\claim@true* even though this appears in *\claim*, because constructions created by *\newclaim* and *\shortenclaim* call *\claim@c* directly (pages~\ref{EEE}~ff. and~\ref{FFF}~ff.). Next we have to find out if the counter ** \csname claim@C#1\endcsname ** already exists (which will happen if *\claim\c{#1}* has already appeared); this is easily done with the test ** \expandafter\ifx\csname claim@C#1\endcsname\relax ** which is true when the counter hasn't been defined yet. If the counter {\it has\/} already been defined, we simply advance it by~*1*. If it hasn't been defined, we create it, with *\newcount@* (compare page~\ref{NWNW}), and set it to~*1*. Then we define *\claimclass@* to be *#1*, and define *\thelabel@*, \dots; in this case, for the preliminary construction, defining *\Thelabel@*, \dots, we do use the more general constructions *\claim@@@C*, \dots (page~\ref{atat}); fortunately, these definitions can all be used within *\xdef*'s. Finally, we need a *\futurelet* to see if our *\claim@c\c{...}* is followed by a quoted number *""...""*, which can happen when *\claim@c* is called by a construction created by *\newclaim* or *\shortenclaim*. We have to allow the possibility that a space might intervene between the *\c{...}* and a *""*, so we use *\FNSS@* (section~\Sref{FIX}): \C** \def\claim@c\c#1{\claim@true \begingroup "2 \expandafter\ifx\csname claim@C#1\endcsname\relax \expandafter\newcount@\csname claim@C#1\endcsname \global\csname claim@C#1\endcsname=1 "2 \else \global\advance\csname claim@C#1\endcsname by 1 \fi "2 \def\claimclass@{#1}% "2 {\noexpands@ \xdef\Thelabel@@@{\number\claim@@@C}% \xdefThelabel@\claim@@@N "2 \xdef\Thelabel@@@@{\claim@@@P\Thelabel@\claim@@@Q}}% \xdefThelabel@@\claim@@@S }% \locallabel@ \FNSS@\claim@c@} ** We're not really done with *\claim@c* yet, but we will return to *\claim@c@* in a moment. \section{Starting a \CS{claim\@q}\label{clq}} For our definition of *\claim@q* we use *\Qlabel@* from section~\Sref{maketag} for defining *\thelabel@*, \dots, and we add a *\FNSS@*, since we have to see whether our *\claim@q* is followed by *\c{...}* (possibly after a space): \C** \def\claim@q""#1""{\begingroup {\let\pre=\claim@@@P \let\post=\claim@@@Q \let\style=\claim@@@S \let\numstyle=\claim@@@N \noexpands@ \Qlabel@{#1}}% "8CLAIMQ"8 \locallabel@ \FNSS@\claim@q@} ** Unlike the situations for *\maketag@* 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*, \dots, compare page~\ref{ADEQ}. \section{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 *\csname 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: \C** \def\claim@c@{\ifx\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 *""*: \C** \def\claim@cq""#1""{{\let\pre=\claim@@@P \let\post=\claim@@@Q \let\style=\claim@@@S \let\numstyle=\claim@@@N \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 \C** \def\claim@q@{\ifx\next\c\expandafter\claim@qc \else\expandafter\Claimformat@@\fi} ** (the ``K-method'' again, see section~\Sref{K}). 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 *\c{...}*: \C** \def\claim@qc\c#1{\expandafter \ifx\csname claim@C#1\endcsname\relax \expandafter\newcount@\csname claim@C#1\endcsname \global\csname claim@C#1\endcsname=0 \fi \FNSS@\Claimformat@@} ** \section{\CS{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*. \C** \def\endclaim{\endgroup\claim@false \nopunct@false\nospace@false \let\Claimformat@@=\claimformat@@\medbreak} ** \section{\CS{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~\Sref{K}): \C** \Invalid@\claimclause ** *\newclaim* itself will require a *\futurelet* to see if *\claimclause* comes next: \C** \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\relax ** so we will simply call *\newclaim@@\relax* directly: \C** \def\newclaim@{\ifx\next\claimclause \def\next@\claimclause##1{\newclaim@@{##1}}\else \def\next@{\newclaim@@\relax}\fi\next@} ** Thus, we have reduced everything to the definition of *\newclaim@@*. Several aspects of *\newclaim@@* are included for eventual use by the\linebreak *\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: \C** \def\claimlist@{\\\claim} ** We will also need two new token lists, \C** \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 {\it don't\/} want the *\claimclause* to be inserted, even if it has been specified. For this purpose, we initially \C** \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). \pagelabel{EFFL} \medskip If \<*" *\> denotes an optional space, then *\newclaim* will appear in something of the form \setbox0\hbox{*\newclaim \claimclause {*\*}*\<*" *\>% *\Thm \c{thm}*\<*" *\>*{Theorem}*} $$\overfullrule=0pt\box0$$ so *\newclaim@@* will appear in something of the form \setbox0\hbox{*\newclaim@@ {*\*}*\<*" *\>% *\Thm \c{thm}*\<*" *\>*{Theorem}*} $$\box0\tag"({\bf A})"$$ Our definition of *\newclaim@@* will be of the form ** \def\newclaim@@#1#2#3\c#4#5{ . . . ** In case ({\bf A}), argument *#1* will be \ (which may be empty), argument *#2* will be `*\Thm*', and argument *#3* will be empty. In fact, argument *#3* will {\it always\/} be empty, but by adding the *#3* before the *\c* we make argument *#2* an undelimited argument, and consequently argument *#2* will simply be `*\Thm*' even in the situation where the space occurs, ** \newclaim@@{...}" \Thm\c{thm} ** Similarly argument *#4* will be `*thm*', and argument *#5* will be `*Theorem*' (even if a space precedes `*{Theorem}*', since *#5* is an undelimited argument). The definition of *\newclaim@@* begins ** \def\newclaim@@#1#2#3\c#4#5{\define#2{}% \rightadd@#2\to\claimlist@\rightadd@#2\to\nofrillslist@ ** Illustrating with case ({\bf A}) again, the *\define\Thm{}* is inserted simply to allow *\define* to give an error message if *\Thm* is already defined---for in that case we certainly don't want *\Thm* to be given another meaning by *\newclaim*. Then we add *\Thm* to *\claimlist@*, for use by *\shortenclaim*, as explained above, and to *\nofrillslist@*, since we will want *\nopunct\Thm* to be allowed. Next we have to create default values for *\Thm@P*, *\Thm@Q*, *\Thm@S*, *\Thm@N*, *\Thm@F*, which will simply be the default values for *\claim@P*, \dots: ** \expandafter\def\csname\exstring@#2@P\endcsname{\claim@P} \expandafter\def\csname\exstring@#2@Q\endcsname{\claim@Q} "2 \expandafter\def\csname\exstring@#2@S\endcsname{\claim@S} \expandafter\def\csname\exstring@#2@N\endcsname{\claim@N} "2 \expandafter\def\csname\exstring@#2@F\endcsname{\claim@F} ** Notice that we use *\def*, rather than *\let*, so that when *\newclaim\Thm* is used, *\Thm@P*, \dots\ will be assigned the current values of *\claim@P*, \dots. 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 \setbox0\hbox{\} \setbox1\hbox{\
} ** "box0."box1. ** 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\linebreak *\claim\c{thm}*); if not, we must create it, with *\newcount@* (again, see page~\ref{NWNW}), 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\exstring@#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~\ref{CHARDEFNE}).\pagelabel{CDNE} After all this, we will want to define *\Thm*: ** \def#2{ . . . \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} "8EEE"8 ** This is where *\claim\c{thm}* usually gets us.\pagelabel{bsc} 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} ** In situation ({\bf A}), *\Thm* will thus store the \ in the token list *\claim@i*, the class `*thm*' in *\claim@iv*, and `*Theorem*' in the token list *\claim@v*:\pagelabel{ATE} ** \def#2{ . . . \global\claim@i={#1}\gdef\claim@iv{#4}\global\claim@v={#5} \def\claimtype@{#2}% \def\Claimformat@@{\claimformat@@{#5}}\claim@c\c{#4}}} ** In the next section we will see why we need *\global* assignments. Finally, we want the claim clause, argument *#1*, to be executed, except in the special case where we have *\let\noclaimclause@=T*: ** \def#1{\ifx\noclaimclause@ T\else#1\fi \global\claim@i={#1}\gdef\claim@iv{#4}\global\claim@v={#5} \def\claimtype@{#2}% \def\Claimformat@@{\claimformat@@{#5}}\claim@c\c{#4}}} ** So the full definition of *\newclaim@@* reads: \C** \def\newclaim@@#1#2#3\c#4#5{\define#2{}% \rightadd@#2\to\claimlist@\rightadd@#2\to\nofrillslist@% "2 \expandafter\def\csname\exstring@#2@P\endcsname{\claim@P}% \expandafter\def\csname\exstring@#2@Q\endcsname{\claim@Q}% "2 \expandafter\def\csname\exstring@#2@S\endcsname{\claim@S}% \expandafter\def\csname\exstring@#2@N\endcsname{\claim@N}% "2 \expandafter\def\csname\exstring@#2@F\endcsname{\claim@F}% \expandafter\def\csname end\exstring@#2\endcsname{\endclaim}% "2 \expandafter\ifx\csname claim@C#4\endcsname\relax \expandafter\newcount@\csname claim@C#4\endcsname \global\csname claim@C#4\endcsname=0 \fi "2 \edef\next@{\let \csname\exstring@#2@C\endcsname =\csname claim@C#4\endcsname}% \next@ "2 \def#2{\ifx\noclaimclause@ T\else#1\fi \global\claim@i{#1}\gdef\claim@iv{#4}\global\claim@v{#5}% \def\claimtype@{#2}% \def\Claimformat@@{\claimformat@@{#5}}\claim@c\c{#4}}} ** \small 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* {\it 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 \setbox0\hbox{\} ** \redefine\endThm{\endgroup\claim@false\nopunct@false "box0} ** But special formatting at the beginning of *\Thm* should be handled as in the case of *\Conj* in section~\Sref{MODC}. \endsmall \section{\CS{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\exstring@#2@S\endcsname {\csname\exstring@#1@S\endcsname} . . . ** (The \lamstex\ 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 \setbox0\hbox{\} ** \def\thm{"box0 \def\claimtype@{\thm}% \def\Claimformat@@{\claimformat@@{Theorem}{}}% \claim@c\c{thm}} "8FFF"8 ** where \ is the claim clause for *\Thm*. So we need a way of getting this \, as well as the `*thm*' and `*Theorem*' that actually go with *\Thm*. The strategy for this is to set a box \Litbox0=** \setbox0=\vbox{\Thm""""\relax\endgroup} ** $$\box0 \tag"\style{\bf A}"$$ because the globally defined token list *\claim@i* will then contain our desired \, *\claim@iv* will be defined to be `*thm*', and the token list *\claim@v* will contain `*Theorem*'. We use an empty label *""""* 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 \ 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 \, is not supposed to have expandable tokens in it.) But there is still one little fillip that we need to add: Instead of ({\bf A}), we really want to use ** \setbox0=\vbox{\let\noclaimclause@=T \Thm""""\relax\endgroup} ** To see why, imagine a situation (compare section~\Sref{MODC}), where we have ** \newclaim\Cor\c{cor}{Corollary} \newclaim\claimclause{\Reset\Cor1}\Thm\c{thm}{Theorem} \shortenclaim\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} \shortenclaim\Thm\thm \newclaim\Cor\c{cor}{Corollary} ** then the *\shortenclaim\Thm\thm* will cause us to ** \setbox0=\vbox{\Thm""""\relax\endgroup} ** and if the \ *\Reset\Cor1* were executed, we would get an error message, since *\Cor* hasn't been created yet! So we add the ** \let\noclaimclause@=T ** which prevents the \ from being executed. Summing up, the definition of *\shortenclaim* reads: \C** \def\shortenclaim#1#2{\define#2{}% \ismember@\claimlist@#1% "2 \iftest@ \rightadd@#2\nofrillslist@% "2 \expandafter\def\csname\exstring@#2@S\endcsname {\csname\exstring@#1@S\endcsname}% "2 \expandafter\def\csname\exstring@#2@N\endcsname {\csname\exstring@#1@N\endcsname}% "2 \expandafter\def\csname\exstring@#2@P\endcsname {\csname\exstring@#1@P\endcsname}% "2 \expandafter\def\csname\exstring@#2@Q\endcsname {\csname\exstring@#1@Q\endcsname}% "2 \expandafter\def\csname\exstring@#2@F\endcsname {\csname\exstring@#1@F\endcsname}% "2 \expandafter\def \csname end\exstring@#2\endcsname{\endclaim}% "2 \edef\next@{\let \csname\exstring@#2@C\endcsname =\csname claim\exstring@#1@C\endcsname}% \next@ "2 \setbox0=\vbox{\let\noclaimclause@=T#1""""\relax\endgroup}% "2 \edef#2{\the\claim@i \def\noexpand\claimtype@{\noexpand#2}% \def\noexpand\Claimformat@@ {\noexpand\claimformat@@{\the\claim@v}\relax}% \noexpand\claim@c\noexpand\c{\claim@iv}}% "2 \else \Err@{\string#1 not yet created by \string\newclaim}% \fi} ** { \catcode`\@=11 \def\claimformat@#1#2#3{\medbreak\noindent \classtest@{conj}\iftest@\llap{\cmbf?\hskip5pt}\fi {\smc#1 {\claim@@@F#2} #3\punct@.\addspace@\enspace}% \typetest@\Defn\iftest@\cmtenrm \else\typetest@\defn\iftest@\cmtenrm\else\cmtensl\fi\fi} \def\claim@F{\cmbf} \catcode`\@=\active \newclaim\claimclause{\Reset\Cor1}\Thm\c{thm}{Theorem} \shortenclaim\Thm\thm \newclaim\claimclause{\Reset\Cor1}\Lem\c{thm}{Lemma} \shortenclaim\Lem\lem \newclaim\Cor\c{cor}{Corollary} \shortenclaim\Cor\cor \newclaim\Defn\c{thm}{Definition} \shortenclaim\Defn\defn \newclaim\Conj\c{conj}{Conjecture} \shortenclaim\Conj\conj \newnumstyle\Conj\Alph \section{Customizing \CS{claim}'s\label{MODC}} To assist in printing different sorts of *\claim*'s in different ways, \lamstex\ provides two tests, \C** \def\classtest@#1{\def\next@{#1}% \ifx\next@\claimclass@\test@true\else\test@false\fi} \def\typetest@#1{\def\next@{#1}% \ifx\next@\claimtype@\test@true\else\test@false\fi} ** Thus, for example, *\classtest@{thm}* will set *\iftest@* to be true precisely when *\claimclass@* is `*thm*', and *\typetest@\Thm* will set *\iftest@* to be true precisely when *\claimtype@* is *\Thm*. To see how these are used, let us suppose that we want our Theorems, Lemmas, Corollaries, Definitions and Conjectures to be printed as follows (temporarily switching to Computer Modern fonts): \Reset\Thm6 \lem If $n$ is odd, then $n^2$ is odd; and if $n$ is even, then $n^2$ is even.\pagelabel{SAMP}\endlem \Cor{(Converse)} If $n^2$ is odd, then $n$ is odd; and if $n^2$ is even, then $n$ is even.\endCor \Thm{(Pythagoras)} $\sqrt2$ is irrational.\endThm \defn An integer $x$ is a {\cmtenit perfect square\/} if $x=y^2$ for some integer $y$. \enddefn \conj If $x$ is not a perfect square, then $\sqrt x$ is irrational.\endconj Thus, Theorems, Lemmas, and Definitions are all numbered together, but Corollaries begin at 1 after each Theorem or Lemma. In addition, Definitions are in *\rm* type. Finally, Conjectures are numbered completely independently, as A, B, C, \dots, and they have a {\cmbf?} in the margin. To set things up, we first use ** \newclaim\claimclause{\Reset\Cor1}\Thm\c{thm}{Theorem} \shortenclaim\Thm\thm "slip \newclaim\claimclause{\Reset\Cor1}\Lem\c{thm}{Lemma} \shortenclaim\Lem\lem "slip \newclaim\Cor\c{cor}{Corollary} \shortenclaim\Cor\cor "slip \newclaim\Defn\c{thm}{Definition} \shortenclaim\Defn\defn "slip \newclaim\Conj\c{conj}{Conjecture} \shortenclaim\Conj\conj \newnumstyle\Conj\Alph ** Since *\Thm*, *\Lem* and *\Defn* all have the same claim class `*thm*', they will be numbered together (and the numbering for *\thm*, *\lem*, and *\defn* follow those for *\Thm*, *\Lem*, and *\Defn*, respectively). The *\claimclause*'s in the *\newclaim*'s for *\Thm* and *\Lem* ensure that Corollary numbers start at 1 after each one; these claim clauses carry over to *\thm* and *\lem*. Finally, we just have to redefine *\claimformat@* as follows: ** \catcode`\@=11 "slip \def\claimformat@#1#2#3{\medbreak\noindent@@ \classtest@{conj}\iftest@\llap{\bf?\hskip5pt}\fi "2 {\smc#1 {\claim@@@F#2} #3\punct@{\null.}\addspace@\enspace}% \typetest@\Defn \iftest@\rm \else \typetest@\defn \iftest@\rm \else\sl\fi\fi} "slip \catcode`\@=\active ** Then the output on page~\ref{SAMP} will be produced by ** \lem If $n$ is odd, ... \endlem \Cor {(Converse)} If $n^2$ is odd ... \endCor \Thm{(Pythagoras)} $\sqrt2$ is irrational.\endThm \defn An integer $x$ is a perfect square ... \enddefn \conj If $x$ is not a perfect square, ... \endconj ** } % matches { before previous \section \chapter Heading levels\label{HLS}\endchapter 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. \section{The {\tt.toc} file} In version *1* of \lamstex@, 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.\pagelabel{TICFILE} Corresponding to *\indexfile* (page~\ref{INDEXFILE}), we have \C** \newif\iftoc@ \def\tocfile{\iftoc@\else \alloc@@7\write\chardef\sixt@@n\toc@ "8ZYX"8 \immediate\openout\toc@=\jobname.toc \alloc@@7\write\chardef\sixt@@n\tic@ \immediate\openout\tic@=\jobname.tic \global\toc@true\fi} ** \section{Preliminaries} To begin with, we want to add *\hl* to *\nofrillslist@*: \C** \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~\ref{NOFC}). But *\HL* can be preceded by *\overlong*, so we need to \C** \rightadd@\HL\to\overlonglist@ ** \section{Different levels of \CS{HL}} Just as the *\list* construction used *\listlevel@* to keep track of the *\list* level, we will use *\HLlevel@* to keep track of the *\HL* level. But *\listlevel@* was a counter, whereas *\HLlevel@* will simply be a control sequence that will be defined to have the proper value. \footnote{This has the advantage that in various *\edef*'s, *\csname ... \endcsname*'s, etc., we can use *\HLlevel@* alone instead of *\number\HLlevel@*. On the other hand, it was a little more efficient to have *\listlevel@* be a counter, since at one point we *\advance\listlevel@*.} Analogous to *\list@@C*, \dots, we have \C** \def\HL@@C{\csname HL@C\HLlevel@\endcsname} "2 \def\HL@@P{\csname HL@P\HLlevel@\endcsname} "2 \def\HL@@Q{\csname HL@Q\HLlevel@\endcsname} "2 \def\HL@@S{\csname HL@S\HLlevel@\endcsname} "2 \def\HL@@N{\csname HL@N\HLlevel@\endcsname} "2 \def\HL@@F{\csname HL@F\HLlevel@\endcsname} ** In addition, as with *\claim*, we will have *\HLtype@*, which will be defined to be *\chapter* when we are using *\chapter* instead of *\HL1*, etc. However, *\HL* itself will simply *\let\HLtype@=\relax*. Corresponding to *\claim@@@C*, etc., we define \C** \def\HL@@@C{\csname\exxx@\HLtype@ @C\endcsname} "2 \def\HL@@@P{\csname\exxx@\HLtype@ @P\endcsname} "2 \def\HL@@@Q{\csname\exxx@\HLtype@ @Q\endcsname} "2 \def\HL@@@S{\csname\exxx@\HLtype@ @S\endcsname} "2 \def\HL@@@N{\csname\exxx@\HLtype@ @N\endcsname} ** all of which will only be used when *\HLtype@* is not *\relax*; *\HL@@@F* won't be needed at all. \section{The \CS{HL} construction\label{HLC}} Roughly speaking, *\HL1* will translate to `*\HL@1*' and *\HL2* will translate to `*\HL@2*', \dots, while an error message will be given if the corresponding control sequence `*\HL@*{\it n\/}' does not exist. The default style defines `*\HL@1*' (section~\Sref{CHL}), and it is up to other style files to define any further such constructions. We use quotation marks around *\HL@*\,{\it n\/} as before (see page~\ref{QTS4}). Assuming that *\HL#1* can be used, we will not call `*\HL@#1*' directly, but instead store *#1* in *\HLlevel@* and call *\HL@*, where *\HL@* will then take care of calling `*\HL@*\,{\it n}' where {\it n\/} is the value *\HLlevel@*. We do this so that something like *\chapter* can simply define *\HLlevel@* to be ~*1* and then call *\HL@* directly. Actually, *\HL#1* will call *\FNSS@\HL@*, because we need to see if a quoted *\HL* number *""...""* follows, and we also have to skip over any space between the argument *#1* of *\HL#1* and the next token; moreover, we will define *\HLname@* to be *\HL{#1}*, for use when writing to the *.toc* file (section~\Sref{WTOC}), and we initialize *\HLtype@* to be *\relax*: \C** \def\HL#1{\expandafter \ifx\csname HL@C#1\endcsname\relax \def\next@{\Err@{\string\HL#1 not defined in this style}}% "2 \else \def\next@{\gdef\HLlevel@{#1}\def\HLname@{\HL{#1}}% \let\HLtype@=\relax\FNSS@\HL@}% \fi \next@} ** We use a *\gdef\HLlevel@* just in case *\HL* happens to be used within a group, because the value of *\HLlevel* might be of interest after the *\HL* has been printed (compare section~\Sref{HLLEV}). The action of *\HL@* will depend on whether a *""* follows next, so *\HL@* will essentially be defined as ** \def\HL@{% \def\next@""##1""##2\endHL{...} \def\nextii@##1\endHL{...} \ifx\next""\expandafter\next@\else\expandafter\nextii@\fi} ** Both *\next@* and *\nextii@* will be calling ** \csname HL@\HLlevel@\endcsname##1\endHL ** where things like ** \expandafter\def\csname HL@1\endcsname#1\endHL{...} \expandafter\def\csname HL@2\endcsname#1\endHL{...} ** are the basic data that a style file will provide. \medskip {\bf(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@*, \dots, *\Thelabel@@@@*. The preliminary step ** \let\pre=... \let\post=... ** must be divided into two cases, depending on whether we are using an ordinary *\HL*\, 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@@P \let\post=\HL@@Q \let\style=\HL@@S \let\numstyle=\HL@@N \else \let\pre=\HL@@@P \let\post=\HL@@@Q \let\style=\HL@@@S \let\numstyle=\HL@@@N \fi \Qlabel@{##1} ** Note that this would be much harder to state if we hadn't introduced *\HL@@@P*, \dots, and compare page~\ref{ADEQ}. After defining *\Thelabel@*, \dots, *\Thelabel@@@@*, we will want to store the value of *\Thelabel@@@@* in *\Thepref@*.\pagelabel{STORETP} The reason for this is that after the appropriate \setbox0\hbox{`*\HL*\'} ** "box0 ... \endHL ** construction, we may perform other steps using the value of *\Thelabel@@@@*, and it is possible (though unlikely) that the *\HL..."allowbreak\endHL* construction contains some other construction allowing \'s, which would then create new values for *\Thelabel@@@@*.\pagelabel{PTU} \footnote{*\footnote* is really the only plausible candidate for this, aside from user-constructed counters. (*\tag* might seem like a candidate, except that displayed formulas aren't allowed in headings; actually they can easily be simulated by setting *$\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~\Sref{WTOC}). Normally, we will be using *\Thelabel@@@@@* 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 *\hl1* numbers as `\Ssymbol1', `\Ssymbol2', \dots\ (compare the small print section on page~\ref{NOFC}), but we want the option of including or omitting the \Ssymbol\ in the Contents. If we do decide to print the \Ssymbol\ in the Contents, then we will have a bit of quandary when we are dealing with a ``quoted'' number, like ** \HL1 ""B"" ... \endHL ** In this case, the printed number will appear as `B' rather than `\Ssymbol B', so it should presumably also appear that way in the contents; on the other hand, *""\style B""* would appear as `\Ssymbol B', so should continue to appear that way in the Contents. What this means is that quoted numbers {\it should also appear quoted in the *.toc* file}, and that any occurrence of *\style* in a quoted number {\it 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~\ref{PIDD}.) To handle this, we introduce a new flag \C** \newif\ifquoted@ ** which we will set true right after defining *\entry@*, and after the\linebreak *\Qlabel@{##1}* we will add ** \let\style=\relax\xdef\Qlabel@@@@@{##1} ** 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\hl1{1} \newpre\hl1{\Thepref@.} ** (recall [page~\ref{STORETP}] that *\Thepref@* holds the value of *Thelabel@@@@*), so that in the first *\HL1*, the *\hl1* numbers will be 1.1, 1.2, \dots; in the second *\HL1*, they will be 2.1, 2.2, \dots; etc. As we will see in Chapter~\ref{acces}, a *\newpre* will essentially do an *\edef*, so that the current value of *\Thepref@* will be stored in the pre-material for *\hl1*. \pagelabel{NEWPREDEF} And after that we will use \setbox0\hbox{`*\HL@J1*'} ** \csname HL@J\HLlevel@\endcsname ** to perform ``initializations'' prescribed by the user, via *\Initialize* (section~\Sref{ATEVERY}); as we will see in section~\Sref{EVERY}, *\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*: %In this process we will want any *\newpre*'s that we encounter to have a %{\it global\/} effect, rather than their usual local effect. %\pagelabel{GLNEW} % For this %purpose (compare page~\ref{EFFL}), %we initially %\C** %\let\globalnews@=F %** %and we will arrange (Chapter~\ref{acces}) for % the *\new...* constructions to have a global effect %when we *\let\globalnews@=T*, so that we can use the group ** \let\pref=\Thepref@ \csname HL@I\HLlevel@\endcsname \csname HL@J\HLlevel@\endcsname} \let\pref=\pref@ ** Then we will use ** \HLtoc@ "8WTOCF"8 ** to write to the *.toc* file, if necessary. *\HLtoc@* won't be defined until section~\Sref{WTOC}. 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~\Sref{AFTOC}). Finally, after that we simply want to reset values that may have been set before the *\HL@*: ** \let\aftertoc@=\relax \overlong@false ** \medskip {\bf(2) }% *\nextii@* is exactly analogous, except that for defining *\Thelabel@*, \dots, we will need ** \ifx\HLtype@\relax "2 \global\advance\HL@@C by 1 "2 \xdef\Thelabel@@@{\number\HL@@C}% \xdefThelabel@{\HL@@N}% "2 \xdef\Thelabel@@@@{\HL@@P\Thelabel@\HL@@Q}% \xdefThelabel@@{\HL@@S}% "2 \else \global\advance\HL@@@C by 1 "2 \xdef\Thelabel@@@{\number\HL@@@C}% \xdefThelabel@{\HL@@@N}% "2 \xdef\Thelabel@@@@{\HL@@@P\Thelabel@\HL@@@Q}% \xdefThelabel@@{\HL@@@S}% \fi ** (and, as already mentioned, we set *\ifquoted@* to be false, and do not define *\Qlabel@@@@*). The whole definition of *\HL@* is: \C** \let\aftertoc@=\relax "slip \def\HL@{% \def\next@""##1""##2\endHL{\def\entry@{##2}\quoted@true {\noexpands@ \ifx\HLtype@\relax \let\pre=\HL@@P \let\post=\HL@@Q \let\style=\HL@@S \let\numstyle=\HL@@N \else \let\pre=\HL@@@P \let\post=\HL@@@Q \let\style=\HL@@@S \let\numstyle=\HL@@@N \fi \Qlabel@{##1}\let\style=\relax\xdef\Qlabel@@@@{##1}% \xdef\Thepref@{\Thelabel@@@@}}% "2 \csname HL@\HLlevel@\endcsname##2\endHL "2 \let\pref=\Thepref@ \csname HL@I\HLlevel@\endcsname \csname HL@J\HLlevel@\endcsname \let\pref=\pref@ "2 \HLtoc@ \aftertoc@ "2 \let\aftertoc@=\relax \overlong@false}% "2 \def\nextii@##1\endHL{\def\entry@{##1}\quoted@false {\noexpands@ \ifx\HLtype@\relax \global\advance\HL@@C by 1 \xdef\Thelabel@@@{\number\HL@@C}% \xdefThelabel@{\HL@@N}% \xdef\Thelabel@@@@{\HL@@P\Thelabel@\HL@@Q}% \xdefThelabel@@{\HL@@S}% \else \global\advance\HL@@@C by 1 \xdef\Thelabel@@@{\number\HL@@@C}% \xdefThelabel@{\HL@@@N}% \xdef\Thelabel@@@@{\HL@@@P\Thelabel@\HL@@@Q}% \xdefThelabel@@{\HL@@@S}% \fi \xdef\Thepref@{\Thelabel@@@@}}% \csname HL@\HLlevel@\endcsname##1\endHL "2 \let\pref=\Thepref@ \csname HL@I\HLlevel@\endcsname \csname HL@J\HLlevel@\endcsname \let\pref=\pref@ "2 \HLtoc@ \aftertoc@ "2 \let\aftertoc@=\relax \overlong@false}% \ifx\next""\expandafter\next@\else\expandafter\nextii@\fi} ** In all these definitions, *\endHL* simply functions as syntax, so we want to declare (see section~\Sref{K}) \C** \Invalid@\endHL ** As of yet, no heading level *\HL* has actually been defined. Before considering this, however, we first tend to *\hl*. \section{The \CS{hl} construction} Everything for *\hl* is almost exactly analogous to that for *\HL*: We start with \C** \def\hl@@C{\csname hl@C\hllevel@\endcsname} "2 \def\hl@@P{\csname hl@P\hllevel@\endcsname} "2 \def\hl@@Q{\csname hl@Q\hllevel@\endcsname} "2 \def\hl@@S{\csname hl@S\hllevel@\endcsname} "2 \def\hl@@N{\csname hl@N\hllevel@\endcsname} "2 \def\hl@@F{\csname hl@F\hllevel@\endcsname} ** Then we define \C** \def\hl@@@C{\csname\exxx@\hltype@ @C\endcsname} "2 \def\hl@@@P{\csname\exxx@\hltype@ @P\endcsname} "2 \def\hl@@@Q{\csname\exxx@\hltype@ @Q\endcsname} "2 \def\hl@@@S{\csname\exxx@\hltype@ @S\endcsname} "2 \def\hl@@@N{\csname\exxx@\hltype@ @N\endcsname} ** Similarly, we define \C** \def\hl#1{\expandafter \ifx\csname hl@C#1\endcsname\relax \def\next@{\Err@{\string\hl#1 not defined in this style}}% "2 \else \def\next@{\gdef\hllevel@{#1}\def\hlname@{\hl{#1}}% \let\hltype@=\relax\FNSS@\hl@}% \fi \next@} ** Then we define *\hl@* as follows (see the remarks at the end regarding the *\FNSSP@*'s): \C** \def\hl@{% \def\next@""##1""##2{\def\entry@{##2}\quoted@true {\noexpands@ "2 \ifx\hltype@\relax \let\pre=\hl@@P \let\post=\hl@@Q \let\style=\hl@@S \let\numstyle=\hl@@N "2 \else \let\pre=\hl@@@P \let\post=\hl@@@Q \let\style=\hl@@@S \let\numstyle=\hl@@@N \fi "2 \Qlabel@{##1}\let\style=\relax\xdef\Qlabel@@@@{##1}% \xdef\Thepref@{\Thelabel@@@@}}% "2 \csname hl@\hllevel@\endcsname{##2}}% "2 \let\pref=\Thepref@ \csname hl@I\hllevel@\endcsname \csname hl@J\hllevel@\endcsname \let\pref=\pref@ "2 \hltoc@ \aftertoc@ \let\aftertoc@=\relax \nopunct@false \nospace@false \FNSSP@}% "2 \def\nextii@##1{\def\entry@{##1}\quoted@false {\noexpands@ "2 \ifx\hltype@\relax "2 \global\advance\hl@@C by 1 "2 \xdef\Thelabel@@@{\number\hl@@C}% "2 \xdefThelabel@{\hl@@N}% \xdef\Thelabel@@@@{\hl@@P\Thelabel@\hl@@Q}% "2 \xdefThelabel@@{\hl@@S}% \else \global\advance\hl@@@C by 1 "2 \xdef\Thelabel@@@{\number\hl@@@C}% "2 \xdefThelabel@{\hl@@@N}% "2 \xdef\Thelabel@@@@{\hl@@@P\Thelabel@\hl@@@Q}% \xdefThelabel@@{\hl@@@S}% \fi \xdef\Thepref@{\Thelabel@@@@}}% "2 \csname hl@\hllevel@\endcsname{##1}}% "2 \let\pref=\Thepref@ \csname hl@I\hllevel@\endcsname \csname hl@J\hllevel@\endcsname \let\pref=\pref@ "2 \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*\*{...}* combination. (It wouldn't do any good to add the *\FNSSP@*'s to the definitions of `*\hl@1*', \dots, since other material comes after them in the definition of *\hl@*.) \section{Other elements of heading levels\label{OTHERE}} 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~\ref{NEWWSTUFF}). 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*, \dots, we admit one more candidate, *\...@W*, the ``word'' associated with a construction. This will be complemented by a construction *\newword*, analogous to *\newpre*, \dots, (Chapter~\ref{acces}), 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~\Sref{SBMACS}). 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. \section{Writing long token lists\label{WLTL}} As we saw in section~\Sref{UNMACRO}, 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~\ref{ISLANDS}), which might be quite long. Consequently, we will simply arbitrarily split *\macdef@* at every sixth space \footnote{In version *1* of \lamstex@, 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.} 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. 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@{" #1 #2 #3 #4 #5 #6}\let\next@=\six@\fi \next@} ** and then use \setbox0\hbox{\} ** \six@"box0" " " " " " " " " " " " \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*, \dots, *#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 \ happened to end with a *" * itself). So we need ~6 more *" *'s, to be used up by the next call to *\six@*.) This all fails spectacularly, however, if the \ is empty, or happens to begin with a space! So we will have to be careful about that. Since we are going to need a similar routine to *\write* to the *.tic* file in Chapter~\ref{PI}, the `*\toc@*' in the above definition will be replaced by an argument *#1*, so that we define \C** \def\six@#1#2 #3 #4 #5 #6 #7 {\def\next@{#2}% \ifx\next@\empty \def\next@##1\six@{}% \else \write#1{ #2 #3 #4 #5 #6 #7}\def\next@{\six@#1}% \fi \next@} ** We are going to be applying this when the \ is stored in *\macdef@*. If *\macdef@* happens to be empty (because of an empty heading level), we will do nothing. Otherwise, we will first eliminate any initial space in *\macdef@* with ** \def\next@#1#2\next@{\def\macdef@{#1#2}} \expandafter\next@\macdef@\next@ ** If *\macdef@* originally expands to *" s*$_{\text{1}}$*s*$_{\text{2}}$\dots, then *#1* will be *s*$_{\text 1}$, since \tex\ ignores spaces in looking for undelimited arguments, and *#2* will be *s*$_{\text2}$\dots, so the new *\macdef@* will be the old, with any initial space deleted. Then we will use ** \edef\next@ {\noexpand\six@\toc@\macdef@ "8SEVENTOC"8 \space\space\space\space\space\space \space\space\space\space\space\space\noexpand\six@} \next@ ** The *\edef* not only inserts 12~spaces, but it also expands out *\macdef@* to its current value, so that the resulting series of (delayed) *\write*'s doesn't depend on what value *\macdef@* may have by the time the *\write*'s are done. Finally, we will use ** \let\macdef@=\relax ** to clear up memory space, since *\macdef@* might be quite long. The whole definition is: \C** \def\Sixtoc@{\ifx\macdef@\empty\else \def\next@##1##2\next@{\def\macdef@{##1##2}}% \expandafter\next@\macdef@\next@ \edef\next@ {\noexpand\six@\toc@\macdef@ \space\space\space\space\space\space \space\space\space\space\space\space \noexpand\six@}% \next@\let\macdef@=\relax\fi} ** \small Even if some argument for *\six@* is of the form *{...}*, \tex\ {\it won't\/} remove the braces, since these are now type~*12* characters, not real braces. (In version~*1* of \lamstex@, where this wasn't the case, a much more complicated routine was required.) Similarly, we don't have to worry about braces being removed during the first stage of deleting any initial space. \andsmall Some remarks near the end of page~87 of the \lamstex~Manual are now wrong. Now spaces after control words {\it are\/} counted in this break-up process (and will be inserted even if they weren't typed in the input file). Spaces within curly braces will also count (since these type~*12* braces won't introduce any grouping for the arguments). This has the added advantage that one doesn't have to worry about a long group within a heading. \andsmall If the prospect of short lines in the *.tic* file is too unappealing, a more complicated routine could be used, in which we selected the pieces delimited by spaces one at a time, and stored them until we obtained a sufficiently large aggregate; the ``size'' of a collection *#1* of type~*12* tokens is easily computed by examining the width of *\hbox{\tt#1}*. \endsmall \section{\CS{HLtoc\@} and \CS{hltoc\@}\label{WTOC}} For *\HLtoc@*, we want to write either something like \setbox0\hbox{\} \setbox1\hbox{\} \setbox2\hbox{\} \setbox3\hbox{\} ** \HL {"box0}{"box3}{"box1} The heading, with line breaks after every sixth space. \Page{"box2}{\arabic }{}{} ** or something like \setbox1\hbox{\} \setbox3\hbox{\} ** \chapter {"box3"}{"box1} . . . The heading, with line breaks after every sixth space. \Page{"box2}{\arabic }{}{} ** if we have created *\chapter* as a name for *\HL1*, say, using *\NameHL* (section~\Sref{RHL}). [If the heading is empty, then we will simply have the *\Page...* line follow the *\HL* line.] Here \ is the value of `*\HL@W*{\it n\/}' (section~\Sref{OTHERE}). In the default style `*\HL@W1*' is empty, while for the book style *book.st* *\HL1* ({\it alias\/} *\chapter*) has *\HL@W1* initially defined as *Chapter*. Notice that the \ is treated as a separate argument from the \. So, even if the heading level itself prints something like \medskip \centerline{\bf Chapter 3. \dots{}} \medskip \flushpar the table of contents will be able to combine these elements in different ways, if desired. This whole arrangement is a big change from version~*1* of \lamstex@; in addition to the \, the page number is included, and all the other information appears without extraneous matter that made the *.toc* file harder to read. To handle the special case of quoted numbers, we define \C** \def\QorThelabel@@@@@{\ifquoted@ \noexpand\noexpand\noexpand""\Qlabel@@@@ \noexpand\noexpand\noexpand""\else \Thelabel@@@@\fi} ** so that *\QorThelabel@@@@* will expand in an *\edef* to either \setbox0\hbox{\} \setbox1\hbox{\} ** \noexpand"""box0\noexpand"" ** or to ** "box1 ** Our first *\write* will involve *\HLname@*, which is either *\HL {*\*}* or something like *\chapter*; the \ for the heading level; and *\QorThelabel@@@@*, the actual \ (or *\Qlabel@@@@*). However, this will be a delayed *\write*, and the values of *\HLname@* and *\Thelabel@@@@* or *\Qlabel@@@@* may be completely different by the time the *\write* is executed, so everything has to be expanded out. For *\QorThelabel@@@@* we need to be in a group with *\noexpands@*; moreover, within this group we need to *\let\style=\relax*, in case *\style* appears in *\Qlabel@@@@*. For *\HLname@* we need something like ** \edef\next@{\write\toc@{\noexpand\noexpand \expandafter\noexpand\HLname@}} \next@ ** In this *\edef*, the *\toc@* is not expanded,\pagelabel{TKSNE} since it was created with a *\chardef* (compare page~\ref{CDNE}), the *\noexpand\noexpand* collapses to a single *\noexpand*, and the *\expandafter\noexpand\HLname@* (compare pages~\ref{EXNE} and ~\ref{EXNE2}) inhibits expansion of a control sequence occurring at the beginning of the expansion of *\HLname@* (i.e., either *\HL* or *\chapter*, etc.) Thus, our *\edef* makes *\next@* mean \setbox0\hbox{\<*\HL1* or *\chapter*, etc.\>} ** \write\toc@{\noexpand"copy0} ** so that *\next@* then gives us what we want. The \, stored in `*\HL@W1*', etc., presents more problems, because it may contain control sequences that shouldn't be expanded out in the *\write*. So we will use the *\unmacro\meaning* trick of section~\Sref{WLTL}, within the triple *\expandafter* trick (page~\ref{tEXA}): the code ** \expandafter\expandafter\expandafter\unmacro@ \expandafter\meaning\csname HL@W\HLlevel@\endcsname\unmacro@ ** will make *\macdef* contain the tokens of the \, but with all non-space tokens converted to type~*12*.\pagelabel{XXZZXX} So, altogether, we can use ** \expandafter\expandafter\expandafter\unmacro@ \expandafter\meaning\csname HL@W\HLlevel@\endcsname\unmacro@ {\noexpands@\let\style=\relax \edef\next@{\write\toc@{\noexpand\noexpand\expandafter\noexpand \HLname@{\macdef@}{\QorThelabel@@@@}} \next@} ** Note that, just as we will need to declare *\noexpands@* before a *\shipout*, when the *\write* is actually done (pages~\ref{SUB1} and~\ref{SUB99}), we will also need to declare *\let\style=\relax* before the *\shipout*.\pagelabel{SUB11} Then we use ** \expandafter\unmacro@\meaning\entry@\unmacro@ \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{\number\pageno}{\page@N}% {\page@P}{\page@Q}^^J} ** where the extra blank line at the end is added to make the *.toc* file more readable. \footnote{Blank lines after the *\Page...* line will usually create no problem, since the table of contents will be usually be set as a series of lines each contributed in vertical mode. But it's conceivable that a style file will format things in a way that puts us into horizontal mode, and then it might be important that we not leave horizontal mode after the page number is printed; in such cases, the macros must scan for *\Page#1#2#3#4\par*, to eliminate the blank line. Although this is an added pain, it is unlikely to occur often, so it seems worth while adding the extra readability to the *.toc* file. \endgraf In the case of the index, where an unknown number of *\Page*'s can follow each *\Entry*, we will be careful to eliminate such *\pars*'s (section~ \Sref{BMPRE}).} (During the *\write* we will have *\noexpands@* in effect, so that the numbering control sequence *\page@N* won't be expanded, nor will any font change control sequences in *\page@P* or *\page@Q*.) So our final definition is: \C** \def\HLtoc@{% \iftoc@ "2 \expandafter\expandafter\expandafter\unmacro@ \expandafter\meaning \csname HL@W\HLlevel@\endcsname\unmacro@ "2 {\noexpands@\let\style=\relax \edef\next@{\write\toc@{% \noexpand\noexpand\expandafter\noexpand\HLname@ {\macdef@}{\QorThelabel@@@@@}}}% \next@}% "2 \expandafter\unmacro@\meaning\entry@\unmacro@ "2 \Sixtoc@ "2 \write\toc@{\noexpand\Page{\number\pageno}{\page@N}% {\page@P}{\page@Q}^^J}% \fi} ** \medbreak For *\hltoc@* we want to write something like \setbox0\hbox{\} \setbox1\hbox{\} \setbox2\hbox{\} \setbox3\hbox{\} ** \hl {"box0}{"box3"{"box1} The heading, with line breaks after every sixth space \Page{"box2}{\arabic }{}{} ** or something like \setbox1\hbox{\} \setbox2\hbox{\} \setbox3\hbox{\} ** \section {"box3"}{"box1} . The heading, with line breaks after every sixth space \Page{"box2}{\arabic }{}{} ** In addition, we want *\nopunct* and *\nospace* to appear before the *\hl* or *\section* in the *\write* if they appeared in the input file: \C** \def\hltoc@{% \iftoc@ "2 \expandafter\expandafter\expandafter\unmacro@ \expandafter\meaning \csname hl@W\hllevel@\endcsname\unmacro@ "2 {\noexpands@\let\style=\relax \edef\next@{\write\toc@{% \ifnopunct@\noexpand\noexpand\noexpand\nopunct\fi \ifnospace@\noexpand\noexpand\noexpand\nospace\fi \noexpand\noexpand\expandafter\noexpand\hlname@ {\macdef@}{\QorThelabel@@@@@}}}% \next@}% "2 \expandafter\unmacro@\meaning\entry@\unmacro@ "2 \Sixtoc@ \write\toc@{\noexpand\Page{\number\pageno}{\page@N}% {\page@P}{\page@Q}^^J}% \fi} ** (We didn't add the analogous clause ** \ifoverlong@\noexpand\noexpand\noexpand\overlong\fi ** to the definition of *\HLtoc@*, because *\overlong* will usually be irrelevant to the treatment of the heading level in the Contents; but for some styles this addition might be reasonable.) \small It's \pagelabel{PIDD} conceivable that a style file might need different information in the *.toc* file that we have provided. For example, perhaps the sections 3.1, 3.2, 3.3, \dots of Chapter~3 are simply going be numbered 1, 2, 3, \dots 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@@@}{\Thelabel@@@@} ** instead of simply *{\Thelabel@@@@}*. Then front matter style files (Chapter~\ref{FRONTMATTER}) 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 \lamstex\ 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. \endsmall \section{\CS{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 \tex'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 \C** \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 *\maketoc* is encountered. So we add \C** \def\checkmainfile@{\ifx\mainfile@\undefined "8CHECKMF"8 \Err@{No \noexpand\mainfile specified}\fi} ** (We put these definitions directly into *lamstex.tex* so that front matter style files don't have to worry about them.) (See section~\Sref{SACN} for the use of *\noexpand*.) \section{Creating heading levels\label{CHL}} Although we now have the general mechanism for handling heading levels, no heading levels have actually been defined. The default style makes *\HL1* and *\hl1* be defined, which will indicate the general procedure required. We begin by adding the necessary counters and control sequences. \C** \expandafter\newcount@\csname HL@C1\endcsname \csname HL@C1\endcsname=0 "2 \expandafter\def\csname HL@S1\endcsname#1{#1\null.} "8NULLSTYLE"8 \expandafter\let\csname HL@N1\endcsname=\arabic \expandafter\let\csname HL@P1\endcsname=\empty \expandafter\let\csname HL@Q1\endcsname=\empty \expandafter\def\csname HL@F1\endcsname{\bf} \expandafter\let\csname HL@W1\endcsname=\empty "slip \expandafter\newcount@\csname hl@C1\endcsname \csname hl@C1\endcsname=0 "2 \expandafter\def\csname hl@S1\endcsname#1{#1\/} \expandafter\let\csname hl@N1\endcsname=\arabic \expandafter\let\csname hl@P1\endcsname=\empty \expandafter\let\csname hl@Q1\endcsname=\empty \expandafter\def\csname hl@F1\endcsname{\bf} \expandafter\let\csname hl@W1\endcsname=\empty ** Using *\newcount@* (see page~\ref{NWNW}) 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~\ref{NULLPUNCT}).\pagelabel{QW4} \pagelabel{ANULL} (The proficient \amstex\ or \lamstex\ 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 \.) Note, by the way,\pagelabel{NEWWSTUFF} 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 user normally wouldn't be able to change at all, like the period after an *\hl1* title in the default style (see page~\ref{ABCDE}). \small In version *1* of \lamstex@, I didn't have this principle \pagelabel{NOFC} clearly formulated, and the period after the heading number in *\HL1* was considered a ``frill''. Moreover, the default style used to print a \S\ before the heading number, and this `*\S*' was ``hard-wired'' into the definition of *\HL@1* (except that we *\let\Ssymbol@=\S* and used *\Ssymbol@*, just in case some one decided to redefine *\S*). If we wanted to retain this \S, then it should really be placed within the definition of `*\HL@S1*'. \andsmall! In that case, however, it would also be necessary to add *\Nonexpanding\S* (or *\Nonexpanding\Ssymbol@*). In view of all this, it seemed better just to leave the damn thing out. \endsmall To allow *\HL1* to be defined, we must create `*\HL@1*' with ** \expandafter\def\csname HL@1\endcsname#1\endHL{...} ** Although that's quite a mouthful, such definitions are meant to be supplied only by style file designers, and numerous subtleties are involved in the definitions anyway, so there's no point trying to make this part easier. Roughly speaking, \lamstex's definition of the default style `*\HL@1*' is ** \expandafter\def\csname HL@1\endcsname#1\endHL{\bigbreak {\locallabel@ "2 \vbox{\Let@\tabskip\hss@ \halign to\hsize{\bf\hfil##\hfil\cr "2 \csname HL@W1\endcsname\space {\HL@@F\thelabel@@}" #1\crcr}} \nobreak\medskip} ** where \list \item We put the whole construction in a group with *\locallabel@*, so that a *\label* within the ** \HL1 ... \endHL ** will be given the values relevant to this *\HL1*. \item We set a *\vbox* consisting of centered lines. *\Let@*, from \amstex@, is the device for letting *\\* be the same as *\cr* within this *\vbox*. Normally we would use *\tabskip\hfil* or *\tabskip\hss* to produce the centered lines; *\tabskip\hss@* is used in case *\overlong* precedes the *\HL* (page~\ref{HSS}). \item At the beginning of the argument *#1* we print *\thelabel@@* (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 *\thelabel@@*, since the spacing is not made part of `*\HL@S1*' (compare page~\ref{SPACESEP}). Moreover, before *\thelabel@@* we print the \ for `*\HL@1*' (empty in the default style). \endlist However, there are a few details that we need to change: \list \item The preamble should really contain ** \halign to\hsize{\bf\hfil\ignorespaces##\unskip\hfil\cr "8UNSKIP"8 ** to discard extraneous spaces at the beginning or end of each line of the heading. \item In addition, we need to replace the ** {\HL@@F\thelabel@@} #1 ** by ** {\HL@@F\thelabel@@} \ignorespaces#1 ** to get rid of an extraneous space at the very beginning of the heading. \item Moreover, if *\thelabel@@* is empty (from a *\HL 1 """"*), then the space before the *\ignorespaces* should be eliminated. And if the \ is empty, then the space after it should be eliminated. \item 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*: \endlist \C** \expandafter\def\csname HL@1\endcsname#1\endHL{\bigbreak "8HLONE"8 {\locallabel@ "2 \global\setbox1=\vbox{\Let@\tabskip\hss@ \halign to\hsize{\bf\hfil\ignorespaces##\unskip\hfil\cr "2 \expandafter\ifx\csname HL@W1\endcsname\empty\else \csname HL@W1\endcsname\space\fi {\HL@@F\ifx\thelabel@@\empty\else\thelabel@@\space\fi}% \ignorespaces#1\crcr}% }% \unvbox1 \nobreak\medskip} ** {\bf NOTE: }The *\nobreak* here is absolutely essential---see section ~\Sref{AFTOC}. The definition of *\hl1* for the default style is quite straightforward, using *\punct@* and *\addspace@*, since *\hl* is on *\nofrillslist@*: \C** \expandafter\def\csname hl@1\endcsname#1{\medbreak\noindent@@ "8ABCDE"8 {\locallabel@ \bf{\hl@@F\ifx\thelabel@@\empty\else\thelabel@@\space\fi}% \ignorespaces#1\unskip \punct@{\null.}\addspace@\enspace}} ** See Chapter~\ref{EVPAR} for the use of *\noindent@@*. Notice that here we don't even print the \, even if it has been changed by *\newword*. (Generally speaking, *\HL* heading levels will have words printed as part of them, while *\hl* levels won't. Of course a style file could redefine `*\hl@1*' to include the \, if necessary.) \section{Initializations} In addition to defining `*\HL@1*', we want a definition like ** \expandafter\def\csname HL@I1\endcsname{\Reset\hl1{1}% \newpre\hl1{\pref.}} ** so that these ``initializations'' are always performed after each *\HL1* (though they may be overridden if *\csname HL@J1\endcsname* has been defined by an *\Initialize* [section~\Sref{EVERY}]). 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 ** might be used to get an unnumbered Introduction preceding the other *\HL1*'s. In that case *\pref* would be empty, and we don't want a lonely period preceding the *\hl1* numbers! So instead we use \C** \expandafter\def\csname HL@I1\endcsname{\Reset\hl1{1}% "8IFXP"8 \ifx\pref\empty\newpre\hl1{}\else\newpre\hl1{\pref.}\fi ** No initializations are required at each *\hl1* in the default style, so we simply leave `*\hl@I1*' undefined. \small In the situation on page~\ref{AEEX}, where we used ** \Initialize\hl1{% \Evaluate\HL1\edef\HLvalue{\number\Value} \Evaulate\hl1 \newpre\exno{\HLvalue.\the\Value.}} ** to set the numbering for *\exno*, subtleties about empty heading level numbers were not taken into account. Actually, there's no way that they can be handled at this point, since there's no way of determining, once we get to an *\hl1*, whether or not the *\HL1* before it had an empty heading number. To deal with these possibilities, we could, for example, have *\HL1* store the current value of *\Thelabel@@@@* in another control sequence, say *\HLpref*, in addition to storing it in *\Thepref@*; then *\HLpref* wouldn't change at an *\hl1*, so it would give information about the *\HL1* that comes before the current *\hl1*. If we were designing a style file in which something like *\exno* were a standard feature, then we would probably need to do this. A clever user could always emulate this with ** \Initialize\HL1{\Evaluate\HL1\xdef\HLpref{\number\Value}} "slip \Initialize\hl1{ . . . \ifx\HLpref\empty\else \Evaluate\HL1\edef\HLvalue{\number\Value}\fi . . . } ** (Or a new *\Initialize\HL1* could simply be given before any *\HL1""""* is stated.) \endsmall \section{\CS{aftertoc\@}\label{AFTOC}} Remember that *\HL1* calls *\HL@*, and *\HL@* in turn will then call `*\HL@1*'*...\endHL* followed by ** \HLtoc@ ** for writing to the *.toc* file. \smallskip {\bf IT \,IS \,THEREFORE \,ESSENTIAL\/} \,that no breaks be allowed by any material at the end of the definition of `*\HL@1*'*...\endHL*, to insure that the proper page number will be written; thus, in the definition for the default style (page~\ref{HLONE}), the *\nobreak* before the *\medskip* 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 {\it demand\/} a page break at this point. For example, the style file for the \lamstex~Manual uses *\HL0* for the Part pages, and in the definition of `*\HL@0*', 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 \setbox0\hbox{\} ** \expandafter\def\csname HL@0\endcsname#1\endHL{% "box0 \vfil\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@{\vfil\break\Offset\page2} "8AFTERTOC"8 ** ---then the proper page is written by the *\HLtoc@* command before we increase the page numbering by~1. \sectiong{Order of heading levels\label{HLLEV}} The default style allows an *\hl1* to appear before an *\HL1*, but we could easily disallow this. For example, we could first ** \def\HLlevel@{0} ** and then use ** \expandafter\def\csname hl@1\endcsname{% \ifnum\HLlevel@=0 \Err@{\string\hl1 not allowed before some \string\HL} ** Similarly, if we created *\hl2*, we could ** \def\hllevel@{0} ** and then ** \expandafter\def\csname hl@2\endcsname#1{% \ifnum\hllevel@=0 \Err@{\string\hl2 not allowed before some \string\hl1} . . . } ** For this to work properly, we should also add ** \def\hllevel@{0} ** to our definition of `*\HL@I1*'. Note, by the way, that there's really no necessity for ``higher'' heading levels to have smaller numbers. \footnote{Actually, a heading level doesn't even have to be a number (but it's probably best not to exploit that fact).} \endsmall \section{Naming header levels\label{RHL}} Now we come to the *\NameHL* and *\Namehl* mechanisms, by which, for example, ** \NameHL1\chapter ** makes *\chapter...\endchapter* function like *\HL1...\endHL*, and ** \Namehl1\section ** makes *\section{...}* function like *\hl1{...}*. As the uppercase ~`*N*' suggests, *\NameHL* and *\Namehl* will act globally. \footnote{*\NameHL* and *\Namehl* replace the *\newHL* and *\newhl* constructions from version~*1* of \lamstex.} 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\overlonglist@ ** 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 *\edef* trick (see, for example, page~\ref{ADDCSNAME} and Chapter~\ref{NEWC}, and see pages~\ref{EXNE} and ~\ref{EXNE2} for the use of the `*\expandafter\noexpand*'):\pagelabel{TOMF} ** \edef\next@{\let\csname\exstring@#2@C\endcsname =\expandafter\noexpand\csname HL@C#1\endcsname}\next@ ** \noindent{\bf NOTE: }Since we *\let\chapter@C=*`*\HL@C1*', etc., it is therefore essential that *\NameHL*\,{\it n\/} be used {\it only after\/} `*\HL@C1*', \dots, `*\HL@F1*' have been defined. \pagelabel{NameNOTE} 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: {\litindent=0pt ** \edef\next@{\def\noexpand#2####1\expandafter\noexpand \csname end\exstring@#2\endcsname {\def\noexpand\HLtype@{\noexpand#2} \def\noexpand\HLname@{\noexpand#2} \gdef\noexpand\HLlevel@{#1} \noexpand\FNSS@\noexpand\HL@####1\noexpand\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~\Sref{K}), ** \edef\next@{\noexpand\Invalid@\expandafter\noexpand \csname end\exstring@#2\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\hl1* 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~\ref{acces}, so that, for example, *\newpre\chapter* and *\newpre\HL1* will each change {\it both\/} *\chapter@P* and `*\HL@P1*'. This will be done by means of two *R*eplacement control sequences: \setbox0\hbox{will be defined to have the value *\chapter*} \setbox1\hbox{will be defined to have as value the pair *{HL}{1}*} \setbox2\hbox{*\chapter@R*} \setbox3\hbox to\wd2{`*\HL@R1*'\hfil} ** "box3 "box0 "box2 "box1 ** So we will add ** \expandafter\gdef\csname HL@R#1\endcsname{#2} \expandafter\gdef\csname\exstring@#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~\ref{FRONTMATTER}), it will be essential, of course, that the user has placed the *\tocfile* command {\it 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~\ref{SFPART},\pagelabel{USESFPART} 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. \medskip 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*. \footnote{In this style `*\HL@1*' uses `*\HL@W1*' (section~\Sref{OTHERE}), which is initially defined to be `*Chapter*', but which is then changed to~`*Appendix*' by the *\appendices* command. Similarly, *\appendices* also uses *\Reset\HL1{1}*, to start the numbering of Appendices at~1.} Once *\appendices* has used *\NameHL1\appendix*, we want a previous name for *\HL1*, say *\chapter*, to become undefined, \pagelabel{NHLUD} 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* {\def\,{{\rm,}} ** \...@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~\ref{acces}, this will disallow the corresponding *\Reset*, \dots, constructions. Unfortunately, *\csname...\endcsname* is quite unsuitable for use in \linebreak *\expandafter* constructions, which is just how we will need it, so we will first use the code ** \def\nextiv@{\let\nextiii@=} "8LNIII"8 \expandafter\nextiv@\csname HL@R#1\endcsname ** which 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@ @C\endcsname=\relax . . . \expandafter\let\csname end\exxx@\nextiii@\endcsname=\undefined ** So our whole definition is: \C** \def\NameHL#1#2{\define#2{}% "2 \expandafter\ifx\csname HL@R#1\endcsname\relax \else \def\nextiv@{\let\nextiii@=}% \expandafter\nextiv@\csname HL@R#1\endcsname "2 \expandafter\let\nextiii@\undefined "2 \expandafter\let\csname\exxx@\nextiii@ @C\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @P\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @Q\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @S\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @N\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @F\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @W\endcsname=\relax "2 \expandafter\let\csname end\exxx@\nextiii@\endcsname=\undefined \fi "2 \expandafter\gdef\csname HL@R#1\endcsname{#2}% \expandafter\gdef\csname\exstring@#2@R\endcsname{{HL}{#1}}% "2 \iftoc@ \immediate\write\toc@{\noexpand\NameHL#1\noexpand#2^^J}% \fi "2 \rightadd@#2\to\overlonglist@ "2 "2 \edef\next@{\let\csname\exstring@#2@C\endcsname =\expandafter\noexpand\csname HL@C#1\endcsname}\next@ "8NameHLcounter"8 "2 \edef\next@{\let\csname\exstring@#2@P\endcsname =\expandafter\noexpand\csname HL@P#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@Q\endcsname =\expandafter\noexpand\csname HL@Q#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@S\endcsname =\expandafter\noexpand\csname HL@S#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@N\endcsname =\expandafter\noexpand\csname HL@N#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@F\endcsname =\expandafter\noexpand\csname HL@F#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@W\endcsname =\expandafter\noexpand\csname HL@W#1\endcsname}\next@ "2 \edef\next@{\def\noexpand#2####1\expandafter\noexpand \csname end\exstring@#2\endcsname "2 {\def\noexpand\HLtype@{\noexpand#2}% "2 \def\noexpand\HLname@{\noexpand#2}% "2 \gdef\noexpand\HLlevel@{#1}% "2 \noexpand\FNSS@\noexpand\HL@####1\noexpand\endHL}}% "2 \next@ "2 \edef\next@{\noexpand\Invalid@\expandafter\noexpand \csname end\exstring@#2\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. \C** \def\Namehl#1#2{\define#2{} "2 \expandafter\ifx\csname hl@R#1\endcsname\relax \else \def\nextiv@{\let\nextiii@}% \expandafter\nextiv@\csname hl@R#1\endcsname "2 \expandafter\let\nextiii@=\undefined "2 \expandafter\let\csname\exxx@\nextiii@ @C\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @P\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @Q\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @S\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @N\endcsname=\relax "2 \expandafter\let\csname\exxx@\nextiii@ @F\endcsname=\relax \fi "2 \expandafter\gdef\csname hl@R#1\endcsname{#2}% \expandafter\gdef\csname\exstring@#2@R\endcsname{{hl}{#1}} "2 \iftoc@ \immediate\write\toc@{\noexpand\Namehl#1\noexpand#2^^J}% \fi "2 \rightadd@#2\to\nopunctlist@% "2 \edef\next@{\let\csname\exstring@#2@C\endcsname= \expandafter\noexpand\csname hl@C#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@P\endcsname= \expandafter\noexpand\csname hl@P#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@Q\endcsname= \expandafter\noexpand\csname hl@Q#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@S\endcsname= \expandafter\noexpand\csname hl@S#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@N\endcsname= \expandafter\noexpand\csname hl@N#1\endcsname}\next@ "2 \edef\next@{\let\csname\exstring@#2@F\endcsname= \expandafter\noexpand\csname hl@F#1\endcsname}\next@ "2 \edef\next@{\def\noexpand#2{% "2 \def\noexpand\hltype@{\noexpand#2}% \def\noexpand\hlname@{\noexpand#2}% \gdef\noexpand\hllevel@{#1}% "2 \noexpand\FNSS@\noexpand\hl@}}% \next@} ** \section{\CS{Initialize}\label{EVERY}}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*\ and *\Initialize\hl*\ to be allowed, and also *\Initialize\chapter* if *\chapter* has been created using *\NameHL*. So we will use one routine, *\InitH@*, if *\Initialize* is followed by a header level *\HL* or *\hl*, and another routine, *\InitS@*, if it is followed by a single name like *\chapter*: \C** \def\Initialize{\futurelet\next\Init@} "2 \def\Init@{\ifx\next\HL\let\next@=\InitH@ \else\ifx\next\hl\let\next@=\InitH@ \else\let\next@=\InitS@\fi\fi\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: \C** \def\InitH@#1#2{\expandafter \ifx\csname\exstring@#1@C#2\endcsname\relax "2 \def\next@{\Err@{\noexpand#1level #2 not defined in this style}}% "2 \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 \C** \def\InitC@#1#2{\edef\nextii@{\expandafter\noexpand \csname\csname#1\endcsname#2}} ** (again compare pages~\ref{EXNE} and~ \ref{EXNE2} for the *\expandafter\noexpand*), so that \setbox0\hbox{*\InitC@{HL}{1}*} $$\box0 \tag"\style{\bf A}"$$ makes *\nextii@* mean *\HL1*; the point of this is that we can then use ** \expandafter\InitH@\nextii@ ** Actually, things are not that direct. To get ({\bf A}) we need ** \expandafter\InitC@\chapter@R ** except that `*\chapter@R*' will actually have to be specified as ** \csname\exstring@#1@R\endcsname ** which cannot be used directly in this *\expandafter*. As on page~\ref{LNIII}, we will actually use the combination ** \def\next@{\let\next@=} "8USELNIII"8 \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 \C** \def\InitS@#1#2{\expandafter \ifx\csname\exstring@#1@R\endcsname\relax \Err@{\noexpand#1not 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@}% \fi \next@} ** \chapter Accessing and controlling counters, styles, etc.\label{acces} \endchapter 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*, *\numstyle*, and *\fontstyle*. The definition of *\value* illustrates the basic strategy required: \hskip-.77pt *\value\tag* should make sense, and if we *\NameHL1\chapter*, then *\value\chapter* should make sense; on the other hand, *\value\list* and *value\HL* should make sense only when followed by an appropriate number. These two different cases are easily distinguished, because *\tag@C* 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#1* 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, ** \noexpand\value can't be used with \string#1 ** (see section~ \Sref{SACN} 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 ** exists, giving an error message if it doesn't, and typesetting the value of this counter if it does: \C** \def\value#1{\expandafter \ifx\csname\exstring@#1@C\endcsname\relax \expandafter\ifx\csname\exstring@#1@C1\endcsname\relax \def\next@{\Err@{\noexpand\value can't be used with \string#1}}% \else \def\next@{\value@#1}% \fi \else \def\next@{\number\csname\exstring@#1@C\endcsname\relax}% \fi \next@} "slip \def\value@#1#2{\expandafter \ifx\csname\exstring@#1@C#2\endcsname\relax \def\next@{\Err@{\string\value\string#1 can't be followed by \string#2}}% \else \def\next@{\number\csname\exstring@#1@C#2\endcsname\relax}% \fi \next@} ** {\bf NOTE: }% In order for this to work properly, it is thus essential that any construction having any `*\...@C*{\it\, n\/}' counter should always have at least the counter `*\...@C1*'. In particular, *\HL1* should always be defined if any *\HL* level is defined, and similarly for *\hl*. In the error message for *\value@*, we used *\string\value* since it will generally look better not to have a space after *\value*, and *\string#1" * rather than *\noexpand#1*, since *#1* may not be (and usually won't be) a control sequence. \medskip We introduce the counter *\Value*, which holds the value for *\Evaluate*, \C** \newcount\Value ** 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: \C** \def\pre#1{\expandafter \ifx\csname\exstring@#1@P\endcsname\relax "2 \expandafter\ifx\csname\exstring@#1@P1\endcsname\relax "2 \def\next@{\Err@{\noexpand\pre can't be used with \string#1}}% "2 \else \def\next@{\pre@#1}% \fi "2 \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~\ref{foot}. 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*. \medskip On the other hand, *\fontstyle* has to be handled differently, because we want something like ** \fontstyle\claim{...} ** to expand to ** {\claim@F...} "8FS"8 ** so *\fontstyle#1* must itself be a control sequence with an argument: \C** \def\fontstyle#1{\expandafter \ifx\csname\exstring@#1@F\endcsname\relax "2 \expandafter\ifx\csname\exstring@#1@F1\endcsname\relax "2 \def\next@{\Err@{\noexpand\fontstyle can't be used with \string#1}}% "2 \else "2 \def\next@{\fontstyle@#1}% \fi "2 \else \def\next@##1{{\csname\exstring@#1@F\endcsname##1}}% \fi \next@} "slip \def\fontstyle@#1#2{\expandafter \ifx\csname\exstring@#1@F#2\endcsname\relax \def\next@{\Err@{\string\fontstyle\string#1 can't be followed by \string#2}}% \else \def\next@##1{{\csname\exstring@#1@F#2\endcsname##1}}% \fi \next@} ** \medbreak 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, *\tag@C*, 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 *\pageno=5*; \footnote{Of course, *\Reset\page* should only be used at a reasonable place, e.g., after a construction, like *\chapter*, that has started a new page.} this special case is handled by the boxed code: \C** \def\Reset#1{\expandafter \ifx\csname\exstring@#1@C\endcsname\relax \expandafter\ifx\csname\exstring@#1@C1\endcsname\relax \def\next@{\Err@{\noexpand\Reset can't be used with \string#1}}% "2 \else \def\next@{\Reset@#1}% \fi "2 \else "2 \def\next@##1{\count@=##1\relax "2 "9\ifx#1\page\else\advance\count@ by -1 \fi"9 "2 \global\csname\exstring@#1@C\endcsname=\count@}% \fi \next@} "slip \def\Reset@#1#2{\expandafter \ifx\csname\exstring@#1@C#2\endcsname\relax \def\next@{\Err@{\string\Reset\string#1 can't be followed by \string#2}}% "2 \else \def\next@##1{\count@=##1\relax\advance\count@ by -1 \global\csname\exstring@#1@C#2\endcsname=\count@}% \fi \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~\ref{HLS}). Then *\Reset\chapter* sets the value of the counter\linebreak *\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~\ref{NameHLcounter})\pagelabel{useNameHLcounter} that it basically involves \setbox0\hbox{`*\HL@C1*'} ** \let\chapter@C="box0 ** and this means that *\chapter@C* and `*\HL@C1*' are simply two different names for the {\it same counter\/} (e.g., *\count47*). Consequently, *\Reset\chapter* and *\Reset\HL1* have exactly the same significance, and the same is true of *\Offset*. \medskip This fortunate circumstance will not extend to *\newpre*, which introduces numerous new problems. First of all, *\newpre* is used in a construction like \setbox0\hbox{\} ** \newpre\tag{"box0} ** So *\newpre\tag* should essentially define *\next@* to be ** \def\tag@P ** and then call *\next@*, so that we will obtain \setbox0\hbox{\} ** \def\tag@P{"box0} ** allowing the *\def* to do the work of scanning the *{*\*}*. As a first attempt we might use ** \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 "2 \else \def\next@{\expandafter \def\csname\exstring@#1@P\endcsname}% \fi \next@} ** However, there are two features that need to be added to this definition: \list \item As mentioned on page~\ref{NEWPREDEF}, we really want an *\edef* rather than a *\def*. %\item And, as mentioned on page~\ref{GLNEW}, we want the *\edef* to be %global when *\globalnews@* is *T*. \item If we have used *\NameHL1\chapter*, then, unlike the situation with *\Offset* and *\Reset* discussed above, *\chapter@P* and `*\HL@P1*' are two independent control sequences, and special efforts are required to insure that *\newpre\chapter* and *\newpre\HL1* will each change {\it both\/} *\chapter@P* and `*\HL@P1*'. \endlist \medskip For (1) it would appear that we simply have to replace the ** \expandafter\def\csname\exstring@#1@P\endcsname ** with ** \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 \list\newnumstyle\list1\alph \item We need to supply an *\endgroup* after the *\edef* is completed. \item This *\edef* must therefore be an *\xdef* in order to survive the grouping. \endlist We can attack these two problems at once by saying \Litbox0=** \def\next@{% \def\nextii@{\endgroup \expandafter\let\csname\exstring@#1@P\endcsname =\Next@} \begingroup\noexpands@\afterassignment\nextii@ \xdef\Next@} \next@ ** $$\vcenter{\box0}\tag"({\bf A})"$$ Thus, *\next@* \list\newnumstyle\list1\roman \item first supplies *\begingroup\noexpands@*, \item and then it *\xdef*'s *\Next@* to be the following text; \item after that assignment is completed, it supplies an *\endgroup*, and \item then it (locally) lets *\...@P* be this (globally defined) *\Next@*. \endlist We use *\Next* for this globally assigned scratch token (page~\ref{GNXT}). 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~\Sref{RHL}, 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~\ref{LNIII} of that section, one of the problems associated with this *\...@R...* mechanism was handled with the code ** \def\nextiv@{\let\nextiii@=} \expandafter\nextiv@\csname HL@R1\endcsname ** which makes the ``nameable'' control sequence *\nextiii@* have the same value as `*\HL@R1*'. More generally, we will define \C** \def\getR@#1#2{\def\nextiv@{\let\nextiii@=}% \expandafter\nextiv@\csname\exstring@#1@R#2\endcsname} ** which can be used in two ways. \smallskip \noindent{\bf 1.\enspace}First of all ** \getR@\chapter{} ** will make *\nextiii@* be *\chapter@R*. We will also define \C** \def\letR@#1#2#3{\expandafter \let\csname#1@#3#2\endcsname=\Next@} ** Then the effect of ** \getR@\chapter{} \expandafter\letR@\nextiii@ P ** \setbox1\hbox{\} \setbox0\hbox{\ \ \ \ \ i.e.,\ \ \ \ \ } is ** \letR@"box1P"box0 \letR@{HL}{1}P ** hence \setbox1\hbox{`*\HL@P1*'} ** \let"box1=\Next@ ** \noindent{\bf 2.\enspace}On the other hand, ** \getR@\HL1 ** will make *\nextiii@* be `*\HL@R1*'. We will also define \C** \def\letR@@#1#2{\expandafter \let\csname\exstring@#1@#2\endcsname=\Next@} ** Then the effect of ** \getR@\HL1 \expandafter\letR@@\nextiii@ P ** \setbox0\hbox{\ \ \ \ \ i.e.,\ \ \ \ \ } \setbox1\hbox{\} is ** \letR@@"box1P"box0\letR@@\chapter P ** hence \setbox0\hbox{[*\let* or *\global\let*]} ** \let\chapter@P=\Next@ ** Putting this all together, we can define *\newpre* as follows: \C** \def\newpre#1{\expandafter \ifx\csname\exstring@#1@P\endcsname\relax "2 \expandafter\ifx\csname\exstring@#1@P1\endcsname\relax \def\next@{\Err@{\noexpand\newpre can't be used with \string#1}}% "2 \else \def\next@{\newpre@#1}% \fi "2 \else \def\next@{% \def\nextii@{% \endgroup "2 \expandafter\let\csname\exstring@#1@P\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R\endcsname\relax \else \getR@#1{}\expandafter\letR@\nextiii@ P\fi}% \begingroup\noexpands@\afterassignment\nextii@ \xdef\Next@}% \fi \next@} "slip \def\newpre@#1#2{\expandafter \ifx\csname\exstring@#1@P#2\endcsname\relax "2 \def\next@{\Err@{\string\newpre\string#1 can't be followed by \string#2}}% "2 \else \def\next@{% \def\nextii@{% \endgroup "2 \expandafter\let\csname\exstring@#1@P#2\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R#2\endcsname\relax "2 \else "2 \getR@#1{#2}\expandafter\letR@@\nextiii@ P\fi}% "2 \begingroup\noexpands@\afterassignment\nextii@ \xdef\Next@}% "2 \fi \next@} ** Of course, *\newpost* is strictly analogous, so we won't write out any of the code. The *\newstyle* command is used in slightly more complicated situations like \setbox0\hbox{\}\setbox1\hbox{\} ** \newstyle\tag"box0{"box1} ** 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@S ** and then call *\next@*, so that we will obtain \setbox0\hbox{\}\setbox1\hbox{\} ** \def\tag@S"box0{"box1} ** In this case, we want a *\def*, rather than an *\edef*, and we don't need to enter a group with *\noexpands@*. Aside from these differences, however, we simply copy the code for *\newpre*: \C** \def\newstyle#1{\expandafter \ifx\csname\exstring@#1@S\endcsname\relax \expandafter\ifx\csname\exstring@#1@S1\endcsname\relax \def\next@{\Err@{\noexpand\newstyle can't be used with \string#1}}% "2 \else \def\next@{\newstyle@#1}% \fi "2 \else \def\next@{% \def\nextii@{% \expandafter\let\csname\exstring@#1@S\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R\endcsname\relax \else \getR@#1{}\expandafter\letR@\nextiii@ S\fi}% \afterassignment\nextii@\gdef\Next@}% \fi \next@} "slip \def\newstyle@#1#2{\expandafter \ifx\csname\exstring@#1@S#2\endcsname\relax "2 \def\next@{\Err@{\string\newstyle\string#1 can't be followed by \string#2}}% "2 \else \def\next@{% \def\nextii@{% \expandafter\let\csname\exstring@#1@S#2\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R#2\endcsname\relax "2 \else "2 \getR@#1{#2}\expandafter\letR@@\nextiii@ S\fi}% "2 \afterassignment\nextii@\gdef\Next@}% "2 \fi \next@} ** *\newnumstyle* will be handled a bit differently from *\newstyle* because *\newnumstyle* will usually be used with a single numbering style control sequence, like ** \newnumstyle\tag{\roman} ** and it is natural for the user to think that *\roman* is simply the second argument to *\newnumstyle*, and thus doesn't need the braces (I~ kept making this mistake all the time in version~*1* of \lamstex@, with disastrous consequences). So we will make *\next@* be a control sequence with an argument---this works whether or not the user has added the braces. In this case, instead of having *\def\next@* at the end of our definition of *\next@*, we have it at the beginning: \C** \def\newnumstyle#1{\expandafter \ifx\csname\exstring@#1@N\endcsname\relax "2 \expandafter\ifx\csname\exstring@#1@N1\endcsname\relax \def\next@{\Err@{\noexpand\newnumstyle can't be used with \string#1}}% "2 \else \def\next@{\newnumstyle@#1}% \fi "2 \else \def\next@##1{% \gdef\Next@{##1}% \expandafter\let\csname\exstring@#1@N\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R\endcsname\relax \else \getR@#1{}\expandafter\letR@\nextiii@ N\fi}% \fi \next@} "slip \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}}% "2 \else \def\next@##1{% \gdef\Next@{##1}% \expandafter\let\csname\exstring@#1@N#2\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R#2\endcsname\relax \else \getR@#1{#2}\expandafter\letR@@\nextiii@ N\fi}% \fi \next@} ** \medskip *\newfontstyle* is exactly analogous to *\newnumstyle*, so we won't bother repeating the code. \medskip 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@*. \pagebreak \C** \def\newword#1{\expandafter \ifx\csname\exstring@#1@W\endcsname\relax "2 \expandafter\ifx\csname\exstring@#1@W1\endcsname\relax \def\next@{\Err@{\noexpand\newword can't be used with \string#1}}% "2 \else \def\next@{\newword@#1}% \fi "2 \else \def\next@{% \def\nextii@{% \expandafter\let\csname\exstring@#1@W\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R\endcsname\relax \else \getR@#1{}\expandafter\letR@\nextiii@ W\fi}% \afterassignment\nextii@\gdef\Next@}% \fi \next@} "slip \def\newword@#1#2{\expandafter "2 \ifx\csname\exstring@#1@W#2\endcsname\relax \def\next@{\Err@{\string\newword\noexpand#1can't be followed by \string#2}}% "2 \else \def\next@{% \def\nextii@{% \expandafter\let\csname\exstring@#1@W#2\endcsname =\Next@ "2 \expandafter\ifx\csname\exstring@#1@R#2\endcsname\relax "displaybreak \else \getR@#1{#2}\expandafter\letR@@\nextiii@ W\fi }% "2 \afterassignment\nextii@\gdef\Next@}% \fi \next@} ** \chapter Footnotes\label{foot}\endchapter \section{Preliminaries\label{FNP}}In addition to *\footnote*, \lamstex\ has *\footmark* and *\foottext*, for special situations like the one indicated on page~52 of the \lamstex~Manual. Because of the ways that these three control sequences interact (page~\ref{INA}), we will need a flag \C** \newif\iffn@ ** which will be set true at the beginning of *\footnote* and then false again at the end. Next we declare certain constructions associated with *\footmark*: \C** \newcount\footmark@C \footmark@C=0 \def\footmark@S#1{$^{#1}$} \let\footmark@N=\arabic \def\footmark@F{\rm} ** No definitions were given for `*\footmark@P*' and `*\footmark@Q*' because footnote markers almost never have pre- or post- material in their numbers. Consequently, *\pre\footmark*, *\newpre\footmark*, etc., will give error messages. Of course, a style file could always change this arrangement if it were necessary. With this default definition of *\footmark@S*, the value of *\footmark@F* is actually quite irrelevant, but it might be significant if *\newstyle\footmark* were used. We will also define \C** \def\foottext@S#1{$^{#1}$} \def\foottext@F{\rm} ** This will allow *\newstyle\foottext* and *\newfontstyle\foottext* to change things about the numbers in the *\foottext*; as mentioned on page~54 of the \lamstex~Manual, it is possible to have a different style for printing the marks within the footnote marker and within the footnote itself. On the other 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.) \section{\CS{vfootnote\@}\label{VF}} In *plain* tex@, the *\footnote* macro is defined in terms of *\vfootnote* (footnote in vertical mode), which does the main work of producing an *\insert*. \lamstex\ uses *\vfootnote@* for this purpose, to avoid any possible conflict (*\vfootnote@* will also work rather differently from *\vfootnote*). In \lamstex@, ** \vfootnote@#1{_",_",_} ** will be called when *#1* represents something like the footnote marker, which has already been determined by other \lamstex\ constructions, while `*_",_",_*' is the text that we want to appear at the bottom of the page. A straightforward definition of *\vfootnote@* would be ** \def\vfootnote@#1#2{\insert\footins {\floatingpenalty=20000 \interlinepenalty=\interfootnotelinepenalty \leftskip=0pt \rightskip=0pt \spaceskip=0pt \xspaceskip=0pt \rm \splittopskip=\ht\strutbox \splitmaxdepth=\dp\strutbox \locallabel@\noindent@@{\footmark@F#1} \strut#2\strut}% } ** (using *\noindent@@*, see Chapter~\ref{EVPAR}). The *\locallabel@* defines *\thelabel@*, \dots, in terms of *\Thelabel@*, \dots, which have been set by the constructions that will call *\vfootnote@* (either *\footnote* or *\foottext*); this is for the use of any *\label* in *#2*. And *#1* will be something like *\foottext@S{\thelabel@@}*, which we set at the beginning of an unindented paragraph (in the font *\footmark@F*, if that's relevant). Then the rest of the footnote is typeset in *\rm*. \small 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 *\interfootnotelinepenalty*, 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 *\interfootnotelinepenalty*. *\leftskip* and *\rightskip* must be set to~ *0pt* 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). \andsmall! 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 *\vfootnote@*. \andsmall The *\strut#2\strut* adds a strut to the first and last line of the footnote (compare the footnote on page~\ref{STRUTINSERT}). *\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*, *\ninepoint*, 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 *\ht\strutbox*, but no depth. This will be important for a two-line footnote, whenever *\lineskiplimit* happens to have been chosen to be greater than~*0pt*: 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 *0pt* glue between them because they would then be closer together than *\lineskiplimit*;\pagelabel{LIMITPROB} consequently, additional *\lineskip* glue would intrude. \lamstex\ also replaces the second *\strut* by ** \lower\dp\strutbox\vbox to\dp\strutbox{} ** which has the proper depth, but zero height. (By the way, Appendix E of {\it The \tex book}, page~416, illustrates a more complicated arrangement; the *\strut* for the eight-point footnote has a height of ~*7pt*, but a *\smallskip* ($={}$*\vskip 3pt plus 1pt minus 1pt*) precedes each footnote, so *\splittopskip* is set to the sum, *10pt plus 1pt minus 1pt*.) \andsmall! Aside from being aesthetically unpleasing, struts don't actually give the right results. For example, *plain* \tex@, with *\baselineskip=12pt*, defines a *\strut* to have height ~*8.5pt* and depth~*3.5pt*. If the last line of one footnote actually has depth ~*0pt*, while the first line of the next footnote contains a tall symbol having a height of *9pt*, there should still be *12pt* between the baselines (assuming a reasonably small value of *\lineskiplimit*). But the last line of the first footnote will be artificially increased to ~*3.5pt* by the strut, so the baselines will be separated by a total of $\hbox{*3.5pt*}+\hbox{*9pt*}=\hbox{*12.5pt*}$. Of course, when there are large symbols of this sort, the extra space probably won't be considered too extravagant. \andsmall! A more disquieting disadvantage of struts is the fact that the proper definition of a *\strut* for any particular point size is {\it font-dependent}.\pagelabel{FONTDEP} In the Computer Modern fonts, the parentheses are usually the tallest and deepest characters; in *cmr8*, for example, their height is~ *6pt* and their depth is~*2pt*. Thus, for eight point type and a *\baselineskip* of ~*9pt*, a *\strut* of height~*7pt* and depth~*2pt* is appropriate (compare {\it The \tex book}, page~415). For this manual, which uses a *\baselineskip* of~*10pt* for the *\eightpoint* footnotes, I originally chose a *\strut* of height~*8pt* and depth~*2pt*. But this sometimes gave strange inconsistent line spacing; it turns out that some characters (not parentheses) were deeper than *2pt*, and the dimensions had to be changed to~ *7.5pt* and ~*2.5pt* to work with the Baskerville fonts used here. \endsmall Instead of using the straightforward definition, we will follow *plain* \tex\ and use a more complicated construction, which doesn't consider the group *{_",_",_}* as an argument to *\vfootnote@*, thus allowing category changes within `*_",_",_*'. In *plain* \tex\ this virtuoso performance was provided so that literal mode constructions could appear in footnotes. In version~*1* of \lamstex@, this was needed to allow invisible index entries within a footnote, since such entries involved category changes. That's no longer necessary, but we might as well allow category changes anyway, since *plain* \tex\ already supplies most of the necessary machinery, and it is a nice feature to have. \footnote{It sure made this manual easier!} So the actual definition is more sophisticated, using the ``implicit'' left brace *\bgroup*. Basically, we would like to ** \def\vfootnote@#1{\insert\footins \bgroup . . . "2 \noindent@@{\foottext@F#1}\footstrut \aftergroup\@foot \bgroup \let\next@=} "slip \def\@foot{\lower\dp\strutbox\vbox to\dp\strutbox{}\egroup} ** Then when we have ** \vfootnote@#1{_",_",_} ** the *\let\next@=* is followed by *{*, so that we *\let\next@={*, thereby {\it removing\/} the~ *{*. Consequently, we now have ** \insert\footins \bgroup . . . \noindent@@{\foottext@F#1}\footstrut \bgroup _",_",_} ** with the *}* matching the second *\bgroup*. And after that *}*, \tex\ inserts the *\aftergroup* token, *\@foot*, which gives the *\strut* and the *\egroup* that matches the remaining first *\bgroup*. Notice that the `*{_",_",_}*' ends up staying in a group---the *\bgroup_",_",_}*---which wouldn't happen if we had read in it as an argument.\pagelabel{BFN} As we will see later (page~\ref{UBFN}), this is {\it not\/} irrelevant: it introduces complications, which are most easily dealt with if the *{\foottext@F#1}* is followed by an additional control sequence, `*\modifyfootnote@*' which is initially *\relax*: \C** \let\modifyfootnote@=\relax ** and which the user can change with *\modifyfootnote*, \C** \def\modifyfootnote#1{\def\modifyfootnote@{#1}} ** 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: \C** \def\vfootnote@#1{\insert\footins \bgroup \floatingpenalty=20000 \interlinepenalty=\interfootnotelinepenalty \leftskip=0pt \rightskip=0pt \spaceskip=0pt \xspaceskip=0pt \rm \splittopskip=\ht\strutbox \splitmaxdepth=\dp\strutbox \locallabel@\noindent@@{\foottext@F#1}\modifyfootnote@ \footstrut\futurelet\next\fo@t} ** Here *\fo@t* calls *\f@@t* when a group follows, but *\f@t* otherwise: \C** \def\fo@t{\ifcat\bgroup\noexpand\next\expandafter\f@@t\else \expandafter\f@t\fi} ** (this is a slight redefinition from *plain*, using the K-method). Since *\f@t* 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. \C** \def\f@t#1{#1\@foot} ** *\f@@t* is also slightly changed from *plain* \tex@: \C** \def\f@@t{\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~ *{*. \footnote{Since *\afterassignment* works on single tokens, this is the situation where we {\it must\/} have a single control sequence that is defined to mean *\FNSS@\pretendspace@*.} Finally, *\@foot* will be changed in two ways. First, we change *\strut* to ** \lower\dp\strutbox\vbox to\dp\strutbox{} ** and we add an *\unskip* before this, in case a mistaken space appears before the closing *}*. In addition, as we will see in sections ~\Sref{FT} and ~\Sref{FNS}, \setbox0\hbox{ and calls }% \setbox1\hbox to\wd0{\hfil calls\hfil}% \setbox2\hbox to\wd0{\hfil sets\hfil}% ** \foottext "box1 \vfootnote@ ** while ** \footnote "box2 \fn@true "box0 \footmark \vfootnote@ "8INA"8 ** Note that although a *\footnote* is essentially like a *\footmark*, *\foottext* combination, nevertheless, *\foottext* is never called indirectly, but is used only when it actually appears in the input file, presumably matching a previous *\footmark* that appears directly in the input file. Now *\foottext*, which leaves *\iffn@* false, begins with *\prevanish@*, since it is supposed to be invisible. Consequently, if *\iffn@* is false, we want to end with a *\postvanish@*, but if *\iffn@* is true, we simply want to reset *\iffn@* false: \C** \def\@foot{\unskip \lower\dp\strutbox\vbox to\dp\strutbox{}\egroup \iffn@\expandafter\fn@false\else \expandafter\postvanish@\fi} ** \small! A style file might replace the *\rm* in the definition of *\vfootnote@* by\linebreak *\eightpoint*, for example, so that footnotes would be set in 8~point type with, say, *\baselineskip=10pt*. But a user who tries to change things on the fly, ** \footnote{\baselineskip10pt . . . } ** will be sorely disappointed!\pagelabel{UBFN} As noted on page~\ref{BFN}, this construction produces ** \insert\footins\bgroup . . . "9{"9\baselineskip10pt . . ."9}"9\egroup ** and *. . .* won't be typeset in paragraphs until the *\egroup* is encountered, by which time the value of *\baselineskip* will have been restored to its old value! (This same difficulty occurs in *plain* \tex)@. On the other hand, ** \modifyfootnote{\baselineskip10pt} \footnote{...} ** will have the desired effect, so a user can easily arrange for *\footnote*'s to be treated specially within certain constructions. \endsmall \section{Fancy footnote numbering\label{FFN}}Footnotes differ from all other automatically numbered \lamstex\ constructions because of the possibility of ``fancy footnote numbering'', whereby footnote numbers begin anew on each page. This section explains the basic strategy to be used in that case. We will introduce the flag \C** \newif\ifplainfn@ \plainfn@true \def\fancyfootnotes{\plainfn@false} ** whose default true value indicates that we are using ``plain'' rather than ``fancy'' footnote numbering. When we are using fancy footnote numbering, *\footmark@C* will continue to be incremented by~*1* at each footnote. But we will have a separate counter \C** \newcount\fancyfootmarkcount@ \fancyfootmarkcount@=0 ** in which we store the latest fancy footnote number. We also need a counter in which to store the number of the most recent page on which a footnote appeared: \C** \newcount\lastfnpage@ ** Initially this should not have the value of any page that has appeared. So we will initialize it to *-10000*, presuming that no one will ever start something at that page number: \C** \lastfnpage@=-10000 ** Remember (Chapter~\ref{BD}) that when *\fancyfootnotes* is in force, \lamstex\ will write lines of the form \setbox0\hbox{\$_{\text1}$} \setbox1\hbox{\$_{\text2}$} \setbox2\hbox{\$_{\text3}$} ** F"box0 F"box1 F"box2 . . . ** to the *.lax* file, where \$_{\text1}$ is the page number on which the first footnote occurs, \$_{\text2}$ the number on which the second footnote occurs, etc. And the next time the file is \tex'ed, *\document* will use these lines to define *\fnpages@* to be \setbox0\hbox{\$_{\text1}$} \setbox1\hbox{\$_{\text2}$} \setbox2\hbox{\$_{\text3}$} ** \\"box0\\"box1\\"box2 ... ** Now suppose that we have come to the {\it k}$^{\text{th}}$ footnote. By looking through *\fnpages@*, we can determine the number {\it K\/} of the page on which it occurs (which might not be the same as the current value of *\pageno*). If {\it K\/} is greater than *\lastfnpage@*, the number of the page on which the previous footnote occurs, then the current footnote is the first on the page. In this case, we will set *\fancyfootmarkcount@* to~ *1*, and use this value for the number of the current footnote. Moreover, we will also change *\lastfnpage@* to {\it K}. But if {\it K\/} equals *\lastfnpage@*, so that the previous footnote occurs on this same page, we will just increase *\fancyfootmarkcount@* by 1, and use that value for the number of the current footnote (in this case, we don't have to bother changing *\lastfnpage@*). If *\footmark@C* has the value {\it k}, the following code efficiently sets *\Next@* to the corresponding page number {\it K}, or to *-10000* if there are fewer than {\it k\/} numbers on the list (we use *\Next@* because of the global *\xdef* [see page~\ref{GNXT}]): \setbox0\hbox{\it k} \Litbox0=** {\let\\=\or \xdef\Next@{\ifcase\number\footmark@C\fnpages@ \else -10000 \fi} } ** $$\vcenter{\box0} \tag"\style{\bf A}"\pagelabel{kK}$$ Roughly speaking, the *\xdef* makes *\Next@* mean \setbox0\hbox{\$_{\text1}$} \setbox1\hbox{\$_{\text2}$} \setbox2\hbox{\$_{\text3}$} \setbox3\hbox{\it k} ** \ifcase "box3\or"box0\or"box1\or"box2...\else -10000 \fi ** which immediately picks out either \$_{\text{\it 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 \fi ** 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). \section{\CS{footmark}} In section~\Sref{FNP}, 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 \setbox1\hbox{V$_{\text{1}}$} \setbox2\hbox{V$_{\text{2}}$} \setbox3\hbox{V$_{\text{3}}$} \setbox4\hbox{V$_{\text{4}}$} ** {"box1}{"box2}{"box3}{"box4} ** where V$_{\text{1}}$, \dots, V$_{\text{4}}$ have their usual significance (Chapter~\ref{LBL1} et seq.), because this information will have to be used by some subsequent *\foottext* (a *\label* might appear in the *\foottext* part, and V$_{\text{2}}$ 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, \C** \let\justfootmarklist@=\empty ** In this case it will be more convenient for *\justfootmarklist@* to be a list of the type introduced in {\it The \tex book}, page~378, so we will be using *\rightappend@* (c.f.~section~\Sref{LISTS}) to append to it. The definition of *\footmark* begins with some of the same constructions used by *\footnote* in *plain* to save the space factor (compare page~\ref{=the}), and add the italic correction to the previous letter: ** \let\@sf=\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi ** Notice that *\/* has already been redefined by \amstex\ to include an *\unskip* before the italic correction; so a space before a *\footmark* (and hence, eventually, before a *\footnote*) is ignored. We are going to be using a modified compressed format, ** \def\footmark{\let\@sf=\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi \def\next@{\ifx""\expandafter\nextii@\else \expandafter\footmark@\fi} \def\nextii@""#1""{...} \futurelet\next\next@} ** where we will define *\footmark@* separately (instead of using *\nextiii@*, which we would temporarily define within *\footmark*). We use this procedure simply because *\footmark@* will turn out to be quite involved, and we don't want *\footmark* to have to make such a complicated definition for *\nextiii@* each time it is used. The first attempt for defining *\nextii@* might be ** \def\nextii@""#1""{% {\let\style=\footmark@S \let\numstyle=\footmark@N "2 \footmark@F#1 "2 \noexpands@ "2 \let\style=\foottext@S \Qlabel@{#1} } "2 \iffn@\else "2 {\noexpands@\xdef\Next@{{\Thelabel@}{\Thelabel@@} {\Thelabel@@@}{\Thelabel@@@@}} "2 \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi \@sf\relax} ** Here we use *\Qlabel@* to create *\Thelabel@*, \dots, *\Thelabel@@@@*. If our *\footmark* came from a *\footnote*, which calls the pair *\footmark*, *\vfootnote@* (see page~\ref{INA}) then any *\label*'s within the *\footnote* will actually end in the *\vfootnote@* part of the construction, and these values will then be used by the *\vfootnote@*. However, before using *\Qlabel@*, we first change the meaning of *\style* from *\footmark@S* to *\foottext@S*, so that *\Ref* within a *\footnote{...}* will refer to the style of the numbering that is used within the note itself, rather than to the style used for the footmark. If our *\footmark* was used directly, so that the flag *\iffn@* is false, then the *\iffn@\else...\fi* clause stores the appropriate information. In this case, it is essential that *\Thelabel@@* use the value of *\foottext@S* rather than *\footmark@S*, since *\Thelabel@@* is what we will print at the beginning of the corresponding *\foottext*. And then, finally, we restore the space factor with ** \@sf\relax ** The *\relax* is necessary, because *\@sf* expands out to \setbox0\hbox{\} ** \spacefactor="box0 ** and a digit could follow. Unfortunately, there is problem here, of a type already addressed by \amstex\ for the *amsppt.sty* file: If *\footmark* is invoked within *\text* (as in the example on page~52 of the \lamstex~Manual), we don't want to add things to *\justfootmarklist@* 4~times, even though *\text* sets things 4~times. So \amstex\ has a flag *\iffirstchoice@*, which is usually true, but which is set to false within the second, third, and fourth choices of the *\mathchoice* involved in the definition of *\text*. We will therefore use ** \def\nextii@""#1""{% \iffirstchoice@ "2 {\let\style=\footmark@S \let\numstyle=\footmark@N \footmark@F#1 "2 \noexpands@ \let\style=\foottext@S \Qlabel@{#1} } "2 \iffn@\else {\noexpands@ "2 \xdef\Next@{{\Thelabel@}{\Thelabel@@} {\Thelabel@@@}{\Thelabel@@@@}} } "2 \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi \fi \@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~\Sref{FFN}. Note that if the test ({\bf A}) on page~\ref{kK} 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} "2 \else {\let\\=\or \xdef\Next@{\ifcase\number\footmark@C\fnpages@\else-10000 \fi}} "2 \ifnum\Next@=-10000 \xdef\adjustedfootmark@{\number\footmark@C} "2 \else \ifnum\Next@=\lastfnpage@ \global\advance\fancyfootmarkcount@ by 1 \else \global\fancyfootmarkcount@=1 \global\lastfnpage@=\Next@ \fi \xdef\adjustedfootmark@{\number\fancyfootmarkcount@} \fi \fi ** Then we define *\Thelabel@*, \dots, *\Thelabel@@@@*, in case it will be needed by a succeeding *\vfootnote@*. Since there is no pre- or post- material, *\Thelabel@@@@* will just be the same as *\Thelabel@*: ** {\noexpands@ \xdef\Thelabel@@@{\adjustedfootmark@} \xdefThelabel@\footmark@N \xdef\Thelabel@@@@{\Thelabel@} \xdefThelabel@@\foottext@S } ** Notice that in the last step we used *\foottext@S* instead of *\footmark@S*, for the same reasons as with the definition of *\nextii@*. As before, we then add information to *\justfootmarklist@* unless\linebreak *\iffn@* is true: ** \iffn@\else {\noexpands@ "2 \xdef\Next@{{{\Thelabel@}{\Thelabel@@} {\Thelabel@@@}{\Thelabel@@@@}} "2 \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi ** Finally, if we have fancy footnote numbering, we want to write an appropriate line \setbox0\hbox{\} ** F"box0 ** to the *.lax* file. To do this we will use ** \ifplainfn@\else \edef\next@{\write\laxwrite@{F\noexpand\the\pageno}} \next@ \fi ** In this *\edef*, the *\laxwrite@* is not expanded because it was created with *\newwrite* and thus with *\chardef* (compare page~\ref{CHARDEFNE}), and *plain* \tex's *\pageno* is also not expanded, since it was created with a *\countdef* (compare page~\ref{CDNE}). Consequently, the *\edef* makes *\next@* mean ** \write\laxwrite@{F\the\pageno} ** When this (delayed) write is executed, it will consequently print the proper page number. And, finally, *\footmark@* will end with *\@sf\relax*, just like *\nextii@*. But again, we have to perform most of this definition only when\linebreak *\iffirstchoice@* is true, since we don't want to increase the counter 4~times, etc. Thus, the whole definition of *\footmark* reads: \C** \def\footmark{\let\@sf=\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi "2 \def\next@{\ifx""\next\expandafter\nextii@\else \expandafter\footmark@\fi} "2 \def\nextii@""##1""{% \iffirstchoice {\let\style=\footmark@S \let\numstyle=\footmark@N \footmark@F##1% "2 \noexpands@ \let\style=\foottext@S \Qlabel@{##1}% }% "2 \iffn@\else {\noexpands@ \xdef\Next@{{\Thelabel@}{\Thelabel@@}% {\Thelabel@@@}{\Thelabel@@@@}}% }% \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi \fi \@sf\relax}% \futurelet\next\next@} "slip \def\footmark@{% \iffirstchoice@ \global\advance\footmark@C by 1 "2 \ifplainfn@ \xdef\adjustedfootmark@{\number\footmark@C}% "2 \else {\let\\=\or \xdef\Next@{\ifcase\number\footmark@C\fnpages@ \else-10000 \fi}}% "2 \ifnum\Next@=-10000 \xdef\adjustedfootmark@{\number\footmark@C}% "2 \else \ifnum\Next@=\lastfnpage@ \global\advance\fancyfootmarkcount by 1 "2 \else \global\fancyfootmarkcount@=1 \global\lastfnpage@=\Next@ \fi "2 \xdef\adjustedfootmark@{\number\fancyfootmarkcount@}% \fi \fi "2 {\noexpands@ \xdef\Thelabel@@@{\adjustedfootmark@}% \xdefThelabel@\footmark@N "2 \xdef\Thelabel@@@@{\Thelabel@}% \xdefThelabel@@\foottext@S }% "2 \iffn@\else {\noexpands@\xdef\Next@{{\Thelabel@}{\Thelabel@@}% {\Thelabel@@@}{\Thelabel@@@@}}}% "2 \expandafter\rightappend@\Next@\to\justfootmarklist@ \fi "2 \ifplainfn@ \else \edef\next@{\write\laxwrite@{F\noexpand\the\pageno}}\next@ \fi \fi "2 \footmark@S{\footmark@N{\adjustedfootmark@}}% \@sf\relax} ** \section{\CS{foottext}\label{FT}} The *\foottext* construction has to get its information from *\justfootmarklist@*, since (compare page~\ref{INA}) *\footext*'s should only occur after sufficiently many *\footmark*'s have been used. If *\justfootmarklist@* is \setbox0\hbox{\$_{\text1}$} \setbox1\hbox{\$_{\text2}$} ** \\{"copy0}\\{"copy1}\\... ** and we define ** "hskip-40pt\def\next@\\#1#2\next@{\def\next@{#1}\gdef\justfootmarklist@{#2}} ** then ** \expandafter\next@\justfootmarklist@\next@ ** defines *\next@* to be \box0, while *\justfootmarklist@* is redefined as *\\{"copy1}...*\,. The definition of *\foottext* will begin with *\prevanish@*. Then we will first test whether *\justfootmarklist@* is empty, and if so, we will issue an error message ** There is no \footmark for this \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@*: \C** \def\foottext{\prevanish@ \ifx\justfootmarklist@\empty \Err@{There is no \noexpand\footmark for this \string\foottext}\fi \def\next@\\##1##2\next@{\def\next@{##1}% \gdef\justfootmarklist@{##2}}% \expandafter\next@\justfootmarklist@\next@ \expandafter\foottext@\next@} ** Once again, for the *\noexpand* in the error message, see section ~\Sref{SACN}. *\foottext@* simply uses the next four values for defining *\Thelabel@*, \dots, *\Thelabel@@@@*, and then calls *\vfootnote@* with the value of *\thelabel@@* (the *\locallabel@* part of *\vfootnote@* sets this to the current value of\linebreak *\Thelabel@@*, namely the second value of *\next@*): \C** \def\foottext@#1#2#3#4{{\noexpands@ \xdef\Thelabel@{#1}\xdef\Thelabel@@{#2}% \xdef\Thelabel@@@{#3}\xdef\Thelabel@@@@{#4}}% \vfootnote@{\thelabel@@}} ** 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 \C** \rightadd@\foottext\to\vanishlist@ ** \section{\CS{footnote}\label{FNS}}Finally, the definition of *\footnote* holds no special surprises. It is practically the same as the combination *\footmark*, *\foottext*, except that we use *\vfootnote@* explicitly instead of *\foottext*, so that the flag *\iffn@*, which we now set to be true, will function properly: \C** \def\footnote{\fn@true \let\@sf=\empty \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi \def\next@{\ifx""\next\expandafter\nextii@ \else\expandafter\nextiii@\fi}% \def\nextii@""##1""{\footmark""##1""% \vfootnote@{\let\style=\foottext@S \let\numstyle=\footmark@N##1}}% \def\nextiii@{\footmark \vfootnote@{\foottext@S{\footmark@N{\adjustedfootmark@}}}}% \futurelet\next\next@} **