\part Labels and\\Cross References\endpart \chapter The \CS{label} mechanism\label{LBL1}\endchapter \lamstex's *\label* mechanism---one of its most crucial features---involves several different parts of \lamstex@, and will occupy the next few chapters. The present chapter merely explains the basic strategy, without presenting any explicit code. (Section~\Sref{ATEVERY} also explains about an important new construction that has been added to \lamstex.) \section{Constructions that can be given \<{\rm label}\>'s\label{bl}} For any \lamstex\ construction *\foo* that can be given a \, \lamstex\ uses \setbox0\hbox{for the counter associated with *\foo*}% \setbox1\hbox{for the ``pre'' material associated with *\foo*}% \setbox2\hbox{for the ``post'' material associated with *\foo*}% \setbox3\hbox{for the style associated with *\foo*}% \setbox4\hbox{for the numbering style associated with *\foo*}% \setbox5\hbox{for the font associated with *\foo*}% ** \foo@C "box0 "8PQ"8 \foo@P "box1 \foo@Q "box2 \foo@S "box3 \foo@N "box4 \foo@F "box5 ** So, for example, *\tag* has an associated counter *\tag@C*, and associated control sequences *\tag@P* \dots, *\tag@F*; *\claim* has an associated counter *\claim@C*, and associated control sequences *\claim@P*, \dots, *\claim@F*; etc. The values of the *\...@C* counters can be manipulated directly, or indirectly through *\Reset* and *\Offset*, and the *\...@P*, *\...@Q*, *\...@S*, *\...@N*, and *\...@F* control sequences can be redefined directly, or indirectly using *\newpre*, \dots, *\newfontstyle*. (This is covered in detail in Chapter~\ref{acces}.) \medskip Moreover, every *\tag* in a displayed formula, every *\claim...\endclaim*, etc., locally defines four quantities, *\thelabel@*, \dots, *\thelabel@@@@*, to be used if the construction is ever given a \: $$\vbox{\openup\jot \halign{#\hfil&\ \ #\hfil\cr {\tt\bs thelabel\@}&will be the value of\ \ {\tt\bs ref\lcurly}\{\tt\rcurly}\cr {\tt\bs thelabel\@\@}&will be the value of\ \ {\tt\bs Ref\lcurly}\{\tt\rcurly}\cr {\tt\bs thelabel\@\@\@}&will be the value of\ \ {\tt\bs nref\lcurly}\{\tt\rcurly}\cr {\tt\bs thelabel\@\@\@\@}&will be the value of\ \ {\tt\bs pref\lcurly}\{\tt\rcurly}\cr}} $$ All \lamstex\ constructions that can be given a \ implicitly provide grouping \footnote{*\claim...\endclaim* and all similar \lamstex\ constructions provide grouping; in the case of *\tag* the grouping in question is provided by the display *$$...$$* in which the *\tag* lies.} and outside of the group *\thelabel@@*, \dots, *\thelabel@@@@* are undefined (unless the construction happens to lie within another construction that can be given a \). However, we will initially ** \let\thelabel@=\relax ** Then the simple test ** \ifx\thelabel@\relax "8IFTL"8 ** will be true unless we are in a construction where *\label* is legitimate. \medskip As a (somewhat contrived) example of how this works, suppose that in the third section of some document, *\claim* numbers are being printed as {\bf(3.i)}, {\bf(3.ii)}, {\bf(3.iii)}, \dots, and that before the tenth *\claim* we state ** \Offset\claim0 \newpost\claim{-A} ** so that the number of the tenth *\claim* will be printed as `{\bf(3.ix-A)}'. Then within the tenth *\claim* $$\openup\jot\tabskip\centering \halign to\hsize{\hskip30pt#\hfil\tabskip0pt&\ \ #\ \ \hfil&\ #\hfil \tabskip\centering\cr \llap{the value of\ \ }{\tt\bs claim\@C}&will be&{\tt9}\cr \noalign{\vskip2pt} {\tt\bs claim\@P}&will be&{\tt3.}\cr {\tt\bs claim\@Q}&will be&{\tt-A}\cr {\tt\bs claim\@S\#1}&will be&{\tt(\#1)}\cr {\tt\bs claim\@N}&will be&{\tt\bs roman}\cr {\tt\bs claim\@F}&will be&{\tt\bs bf}\cr \noalign{\bigskip\hbox{and, correspondingly}\bigskip} {\tt\bs thelabel\@}&will be&{\tt\bs roman\lcurly9\rcurly}\cr {\tt\bs thelabel\@\@}&will be&{\tt (3.\bs roman\lcurly9\rcurly-A)}\cr {\tt\bs thelabel\@\@\@}&will be&{\tt 9}\cr {\tt\bs thelabel\@\@\@\@}&will be&{\tt 3.\bs roman\lcurly9\rcurly-A}\cr} $$ The value of the counter for *\claim*, the numbering style, the pre- and post-material, and the style for *\claim* are all involved in the values of *\thelabel@*, \dots, *\thelabel@@@@*; see section~\Sref{QF} regarding the font style. \section{Restrictions} The first concrete example of defining *\thelabel@*, \dots, *\thelabel@@@@* occurs in Chapter~\ref{DF}. For the moment, we simply want to note that these control sequences will essentially be created using *\edef*'s, to insure that they will contain the current values of the counter, numbering style, etc. Moreover, they will often occur in *\xdefs*'s and *\write*'s (see page~\ref{GGGG}). This means that \setbox0\hbox{*\...@P*}% \setbox1\hbox{*\...@Q*}% \setbox2\hbox{*\...@S*}% \setbox3\hbox{*\...@N*}% \setbox4\hbox{*\xdef*'s}% \setbox5\hbox{*\write*'s}% $$ \pagelabel{necc} \boxed{\vbox{\halign{\hfil#\hfil\cr Any control sequences appearing in\cr \box0, \ \ \box1, \ \ \box2, \ \ or \ \ \box3\cr must be ones that can appear in \box4 \ and \box5.\cr}}}$$ Actually, we will use *\noexpands@* (Chapter~\ref{noexpands}) to inhibit expansion during the *\edef*'s, *\xdef*'s,\pagelabel{plex} and *\write*'s (pages~\ref{A1}, \ref{A2}, et al.), so the proper strategy is to allow only control sequences for which *\noexpands@* prevents expansion. \medskip We've already noted (page~\ref{IC}) that *\let\/=\relax* was added to the token list *\noexpandtoks@* because *\/* often appears in *\...@S* definitions; and *\let\rm=\relax*, \dots\ were added because font change control sequences often appear also---see, for example, pages~\ref{CCC} and ~\ref{tagit}. Similarly, page~35 of the \lamstex~Manual indicates that if a new font selection command *\TimesRoman* is ever going to be used in defining the style for anything that can be labelled, then *\Nonexpanding\TimesRoman* ought to be added, and if a new numbering command *\Babylonain* is ever going to be used to number anything that can be labelled, then we should add *\Nonexpanding\Babylonian* to the file. \footnote{The \lamstex~Manual also indicates that the style file for that manual (and for this manual, as well) includes *\Nonexpanding\FC*, because the ``font complement'' *\FC* command occurs in *\footmark@S* and *\foottext@S*.} \section{Consequences of these restrictions} Since constructions like *\newpre* simply define various *\...@P* control sequences, the restrictions of the previous section also mean that in constructions like ** \newpre\tag{...} ** {\it any control sequences in `*...*' must be ones for which *\noexpands@* prevents expansion}. And this means that some of the things stated, and implied, in the \lamstex~Manual are false. While the illustrations of *\newpost* given for *\tag* and the illustrations of *\newstyle* and *\newnumstyle* given in connection with *\list* were quite legitimate, the small print on page~77 gives the example ** \newpre\exno{\value\HL1.\value\hl1.} ** for numbering a user-created construction. But this example is completely wrong! Things like *\value* can't be used for *\newpre*. Instead, we need something like\pagelabel{FNEPG} \footnote{To\label{FNEP} be on the safe side, we might prefer *\Evaluatepref\HL1 \edef\HLvalue{\Pref}*, \dots, in case *""...""* has been used to quote a heading level, but *\Evaluate* will illustrate the point well enough.} \Litbox0=** \Evaluate\HL1 \edef\HLvalue{\number\Value} \Evaluate\hl1 \newpre\exno{\HLvalue.\number\Value.} ** $$\vcenter{\box0}\tag"\style{\bf A}"\pagelabel{EXNO}$$ And the situation is even more complicated, because we need to restate this after every *\hl1*. \section{\CS{Initialize}\label{ATEVERY}} To handle such situations, \lamstex\ now has the construction *\Initialize* (the details of which are described in sections ~\Sref{HLC} and ~\Sref{EVERY}). If you type \Litbox0=** \Initialize\hl1{\Evaluate\HL1 "8AEEX"8 \edef\HLvalue{\number\Value}% \Evaulate\hl1 \newpre\exno{\HLvalue.\number\Value.}} ** $$\vcenter{\box0}\tag"\style{\bf B}"$$ then the set of commands ({\bf A}) will be executed each time an *\hl1* occurs. Similarly, ** \Initialize\HL1{\newpre\hl1{}} ** would make the pre-material for *\hl1* be empty even for the default style, which normally makes the pre-material for *\hl1* be `*1.*' in the first *\HL1*, and `*2.*' in the second, etc. If *\chapter* and *\section* have been introduced as names for *\HL1* and *\hl1* (see Chapter~\ref{HLS} for details), then we can substitute *\chapter* for *\HL1* and/or *\section* for *\hl1* in the *\Initialize* command, e.g., ** \Initialize\chapter{\newpre\section{}} ** [Different *\Initialize* commands don't accumulate, so if you later want to add *\newpre\hl2{}*, then you must use ** \Initialize\HL1{\newpre\hl1{}\newpre\hl2{}} ** This shouldn't be much of a problem, since such commands are rather special, and would probably go near the beginning of a document; moreover, if they did accumulate, it would quite dicey to {\it cancel\/} any such command.] As an extra bonus, within the *\Initialize* construction, *\pref* may be used with a special significance. For example, in something like ** \Initialize\hl1{\newpre\exno{\pref.}} ** the `*\pref*' will give the value that *\pref* would have for a \ in the *\hl1* that has just been executed. Consequently, in the default style this will have the same effect as ({\bf B}). \footnote{More precisely, it will have the same effect as if we had used *\Evaluatepref*, as suggested in footnote~\ref{FNEP} on page~\ref{FNEPG}.} \section{The question of fonts\label{QF}} Note that the font for *\claim* is not recorded anywhere in *\thelabel@*, \dots, *\thelabel@@@@*---it is relevant only when the *\claim* number is actually printed. Thus, as we'll see in Chapter \ref{acces}, *\Ref{*\*}* will not print `{\bf(3.ix-A)}', but simply `(3.ix-A)' [or `{\it(3.ix-A)\/}' if we are using italic type, etc.]. But we can get \hbox{`{\bf(3.ix-A)}'} by typing *\fontstyle\claim{\Ref{*\*}}*, which expands out (page~\ref{FS}) to \setbox0\hbox{\}% ** {\claim@F\Ref{"box0}} ** This seems like the optimal arrangement, giving the option of using the same font or not. Note, \pagelabel{SGG} by the way, that to print *\claim* numbers as ({\bf3.i}), ({\bf3.ii}), ({\bf3.iii}), \dots, with bold numbers and letters, but with {\it \hbox{roman}\/} parentheses, we would define *\claim@S* (either directly, or indirectly through *\newstyle*), to be ** \def\claim@S#1{{\rm(}#1\/{\rm)}} "8CCC"8 ** and *\fontstyle\claim{\Ref{*\*}}* will then give the claim number printed in exactly this way. (The *\/* is useful in case *\claim@F* is ever chosen to be a slanted font.)\pagelabel{ic2} \section{Storing \<{\rm label}\>'s} Every time a valid *\label{*\*}* or *\pagelabel* appears, so that \ can be given associated values *\ref{*\*}*, \dots, \lamstex\ has to record this information in two places: \list \item The information must be kept internally, in a new control sequence that we will consider in a moment. \item The information must also be written to the auxiliary *.lax* file. \footnote{In version *1* of \lamstex@, the auxiliary file had the extension *.aux*; however, this has been changed to *.lax* (``\lamstex\ auxiliary file''), not only to avoid conflict with *.aux* files produced by \latex@, but also because \lamstex\ can now write *.aux* files also (Chapter~\ref{bibtex}); these have the structure of \latex\ auxiliary files, but contain only entries relevant to \bibtex@, so that \bibtex\ can be used with \lamstex\ files also. In conformity with this change, the old *\readaux* has been changed to *\readlax* (section~\Sref{rl}).} \endlist The reason for writing to the auxiliary file, of course, is so that the information from that auxiliary file can be read in again the next time the document is \tex'ed, thus allowing for forward references. It will be important to distinguish information read in from the auxiliary file from information created on the current run, and also to distinguish labels created by *\label* from those created by *\pagelabel*. \medskip The basic datum that we will be recording in the *.lax* file will be a term of the form \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} ** @"box0~"box1~"box2~"box3~"box4~"box5 ** where $$\align%at2 \hbox{V}_{\text1}&=%\hbox{value of {\tt\bs thelabel\@}}&&= \hbox{value of {\tt\bs ref\lcurly}\{\tt\rcurly}}\\ \hbox{V}_{\text2}&=%\hbox{value of {\tt\bs thelabel\@\@}}&&= \hbox{value of {\tt\bs Ref\lcurly}\{\tt\rcurly}}\\ \hbox{V}_{\text3}&=%\hbox{value of {\tt\bs thelabel\@\@\@}}&&= \hbox{value of {\tt\bs nref\lcurly}\{\tt\rcurly}}\\ \hbox{V}_{\text4}&=%\hbox{value of {\tt\bs thelabel\@\@\@\@}}&&= \hbox{value of {\tt\bs pref\lcurly}\{\tt\rcurly}} %\endalignat \endalign $$ and the \ is $$ \align \hbox{\tt0}&\hbox{\ \ if \ was created by a {\tt\bs label} on the current run}\\ \hbox{\tt1}&\hbox{\ \ if \ was created by a {\tt\bs label} on the previous run}\\ \hbox{\tt2}&\hbox{\ \ if \ was created by a {\tt\bs pagelabel} on the current run}\\ \hbox{\tt3}&\hbox{\ \ if \ was created by a {\tt\bs pagelabel} on the previous run}\endalign$$ Each *\label{*\*}* will create a new control sequence `*\*\*@L*' with the value \newbox\boxx \newbox\boxxi \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} \setbox6\hbox{\$'$}\setbox7\hbox{V$_{\text1}'$}\setbox8 \hbox{V$_{\text2}'$}\setbox9\hbox{V$_{\text3}'$}\setbox\boxx\hbox{V$_{\text4}'$}% \setbox\boxxi\hbox{\$'$} ** "box1~"box2~"box3~"box4~"box5 ** (we use quotes around *\*\*@L* as on pages~\ref{QTS1} and~ \ref{QTS2}),\pagelabel{QTS3} and it will also write \newbox\boxx \newbox\boxxi \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} \setbox6\hbox{\$'$}\setbox7\hbox{V$_{\text1}'$}\setbox8 \hbox{V$_{\text2}'$}\setbox9\hbox{V$_{\text3}'$}\setbox\boxx\hbox{V$_{\text4}'$}% \setbox\boxxi\hbox{\$'$} ** @"box0~"box1~"box2~"box3~"box4~"box5 ** to the *.lax* file. *@* and *~* are simply two conveniently chosen tokens that should not appear within any \. Actually, the *@* and *~* appearing in the definition of `*\*\*@L*' and in the *.lax* file will {\it not\/} be active characters, but will have category code~ *11* (so that normally they won't even appear in the input file). For~*@* this is easy to arrange (indeed it would be quite difficult to avoid), since all our definitions are going to be made while *@* has category code~*11*; for~*~* we will simply declare *\catcode`\~=11* at the beginning of our definitions, and return to *\catcode`\~=\active* at the end.\pagelabel{sl} Because these *~*'s are not active, we do not have to worry about their being expanded in any *\xdef*'s or *\write*'s, which will turn out to be quite a convenience. When we begin our document, with the *\document* command, if the *.lax* file already exists (from a previous run), it will be read in, line by line, and each line \newbox\boxx \newbox\boxxi \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} ** @"copy0~"copy1~"copy2~"copy3~"copy4~"copy5 ** will be used to define `*\*\*@L*' to have the value ** "copy1~"copy2~"copy3~"copy4~"copy5 ** Thus, whenever a *.lax* file already exists, we will start with all the information obtained on the previous run. Of course, we will have to make sure that *~* has category code~*11* while reading in the lines of the *.lax* file so that it will have that category code when it is used in defining the corresponding control sequence (compare the remark on page~\ref{wcodes}).\pagelabel{wc2} \section{\CS{ref} and its relatives} It should be pretty obvious how *\ref#1*, *\Ref#1*, and other cross-referencing commands will work: The test ** \expandafter\ifx\csname#1@L\endcsname\relax ** is true precisely when *#1* has not yet been used as a \. If the test is true, we simply give an error or warning message. Otherwise, the value of *\csname#1@L\endcsname* will be \setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5=\hbox{\}% ** "box1~"box2~"box3~"box4~"box5 ** *\ref* will return V$_{\text1}$, *\Ref* will return V$_{\text2}$, etc. The really interesting question is how we are going to keep the *\label* and *\pagelabel* information updated. \section{{\tt\bs label}\label{label}} Whenever we encounter a *\label{*\*}*, we will first check that we are in a construction that allows \'s, using the test (page~\ref{IFTL}) ** \ifx\thelabel@\relax "8IFTL2"8 ** If the result if true, so that we are in a construction not allowing a \, we will simply give an error message. Otherwise, we will use the test ** \expandafter\ifx\csname#1@L\endcsname\relax ** which is true if and only if *#1* has not already been used as a \. If *#1* has not already been used as \, we will use \setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\}% ** \expandafter\xdef\csname#1@L\endcsname{"copy1~"copy2~"copy3~"copy4~0}"8GGGG"8 ** the *0* at the end indicating that \ comes from a *\label* added on the current run. In addition, we will ** \immediate\write\laxwrite@{@#1~"copy1~"copy2~"copy3~"copy4~1} ** with a *1* at the end. When this line of the *.lax* file is read by *\document* on the next run, `*\*\*@L*' will then be defined so that its value has a~*1* at the end, indicating that it represents ``previous'' information. On the other hand, if \ {\it has\/} already been used, we need to examine the whole sequence \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} ** @"box0~...~...~...~...~"box5 ** and determine the value of the \. If this value is *0* or *2*, then \ has already been used on the current run, and we will just give an error message saying that \ has already been used.\pagelabel{1or2} But if the value is *1* or *3*, then the information for \ was compiled during the previous run. Since we want to allow the previous value to be changed, we will change the definition of `*\*\*@L*' so that the sequence \setbox0\hbox{\} \setbox5\hbox{\<*1* or *3*\>} ** ...~...~...~...~"box5 ** that currently appears in the definition is replaced by the appropriate \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} ** "box1~"box2~"box3~"box4~0 ** the *0* once again indicating that \ now comes from a *\label* created on the current run.\pagelabel{1or3} And, once again, we will write appropriate information to the *.lax* file, but with *1* replacing *0*. \section{\CS{pagelabel}} The *\pagelabel* construction works rather differently. First of all, we don't use the ** \ifx\thelabel@\relax ** test, because *\pagelabel*'s are allowed anywhere. So we simply start with the test ** \expandafter\ifx\csname#1@L\endcsname\relax ** If this test is false, then then \ has never been used, and now we define `*\*\*@L*' to be\pagelabel{HH} \setbox0\hbox{\}\setbox1\hbox{V$_{\text1}$}\setbox2 \hbox{V$_{\text2}$}\setbox3\hbox{V$_{\text3}$}\setbox4\hbox{V$_{\text4}$}% \setbox5\hbox{\} ** "box1~"box2~"box3~"box4~2 ** where the *2* at the end indicates that \ comes from a *\pagelabel* added on the current run, and where \setbox4\hbox{value of *\page@N{\number\page@C}*}% \setbox5\hbox{value of *\page@S{\page@P\page@N{\number\page@C}\page@Q}*}% \setbox6\hbox{value of *\number\page@C*}% \setbox7\hbox{value of *\page@P\page@N{\number\page@C}\page@Q*}% $$ \align \hbox{V}_{\text1}&=\copy4\\ \hbox{V}_{\text2}&=\copy5\\ \hbox{V}_{\text3}&=\copy6\\ \hbox{V}_{\text4}&=\copy7\endalign$$ As in the case of *\label*, we also want to write appropriate information to the *.lax* file, except that the *2* at the end should be replaced by *3*, so that when this line is read by *\document* in the next run, `*\*\*@L*' will be defined with a~ *3* at the end, so that it will appear as ``previous'' information. {\it But now there is a big difference:\/} for *\label* we will use an *\immediate\write*, but for *\pagelabel* we will use an ordinary *\write*. That is because only a (delayed) *\write* is certain to give the proper value of *\page@C*---the information that we have recorded in *\*\*@L* may actually be incorrect, because the value of *\page@C* may not be the number of the page on which the *\pagelabel* eventually appears. And this means, of course, that only *\pagelabel*'s read in from the {\it previous\/} run can be assured of being correct. \medbreak The other case, when \ has already been used, also requires changes. As before, we must examine the value \setbox0\hbox{\} \setbox5\hbox{\} ** ...~...~...~...~"box5 ** of *\*\*@L* and determine the value of the \. If this value is *0* or *2*, then \ has already been used on the current run, and we will just give an error message saying that \ has already been used. On the other hand, if the value is *1* or *3*, then the information for \ was compiled during the previous run. Now a *1* indicates that in the previous run \ was used for a *\label*, rather than a *\pagelabel*---presumably because the user has now decided to use \ for a *\pagelabel* that was used for a *\label* on the previous run. In this case, we will simply replace the definition of `*\*\*@L*' with the appropriate information for this new \, replacing the *1* with a *2*.\pagelabel{HH2} We will also write corresponding new information to the *.lax* file, changing the final *1* to a *3*, however, so that when it is read in again on the next run, it will be recognized as information coming from a previous *\pagelabel*. On the other hand, a *3* indicates that in the previous run \ was used for a *\pagelabel*. In this case, as indicated above, this previously obtained information is more likely to be the correct one. Consequently, we will {\it not\/} change the definition of `*\*\*@L*'. But we will still write this appropriate new information (using a delayed *\write*) to the *.lax* file, keeping the final *3*, so that it will appear once again as ``previous'' information on the next run. \small The label mechanism in version~*2* of \lamstex\ is entirely different, and much more efficient than, the one used in version~*1* of \lamstex@, which was designed using a \tex\ that allowed 3,000 control sequence names. Since \lamstex\ itself uses up about 2,700 names, not counting additional control sequences introduced by style files, it seemed imprudent at that time to use a labelling method that introduces a new control sequence name for each \. But with that old mechanism, main memory was usually exhausted after only about~40 or~50 \'s had been created (necessitating the stratagems explained in section~4.8 of the \lamstex~Manual), so this excessive wariness was clearly counterproductive. Moreover, more generous \tex s, allowing at least 3,500 control sequence names, are now quite common (and there's always *tinylams.tex* for the truly parsimonious). \endsmall \chapter Beginning the document\label{BD} \endchapter \section{Preliminaries\label{BDP}} Since we have to read an existing *.lax* file at the beginning of the document, and then write to a new *.lax* file during the document, we first declare \C** \newread\laxread@ "8lax"8 \newwrite\laxwrite@ ** \lamstex\ makes use of a special sort of list, initially defined to be empty, \C** \let\fnpages@=\empty ** which is used for fancy footnote numbering. As we will see in Chapter~\ref{foot}, when *\fancyfootnotes* is in effect, each *\footnote* will cause \lamstex\ to write a special line to the *.lax* file: If the first footnote occurs on page~ 7, say, then ** F7 ** will be written to the *.lax* file. If the second and third footnotes occur on pages~ 12 and~14, then the lines ** F12 ** and ** F14 ** will each be written (sometime later on). These lines are always written with a (delayed) *\write*, and the corresponding information is {\it not\/} recorded internally. On the other hand, when we read in an existing *.lax* file, any such *F*\ lines will be incorporated into *\fnpages@*, which will end up looking like ** \\7\\12\\14 . . . ** (As we will see in section~\Sref{FFN}, we will be able to extract information from *\fnpages@* in an extremely efficient way.) For this purpose, we will be using \C** \def\Finit@#1#2\Finit@{\let\nextii@=#1\def\nextiii@{#2}} ** so that *\Finit@...\Finit@* will *\let\nextii@* be the first token in `*...*' and define *\nextiii@* to be the remainder. (Since *\Finit@* will always be applied to a line we read in from the *.lax* file, *\nextii@* will always be either *F* or *@*.) At this point, *lamstex.tex* changes *~* to a letter, and introduces the routine *\getparts@*: \C** \catcode`\~=11 "slip \def\getparts@ @#1~#2~#3~#4~#5~#6{\def\nextiv@{#1}% \def\nextiii@{#2~#3~#4~#5~}\count@=#6\relax} ** Thus, when applied to something of the form \setbox0\hbox{\} \setbox1\hbox{V$_{\text1}$*~*V$_{\text2}$*~*V$_{\text3}$*~*V$_{\text4}$*~*} \setbox2\hbox{\} ** @"box0~"copy1"box2 ** *\getparts@* stores \ in *\nextiv@* and \box1\ in *\nextiii@*, and sets *\count@* to the value of \. \section{\CS{document}} As in \amstex@, *\document* first defines *\fontlist@* to be empty. It then opens the file *\jobname.lax* for reading. It processes the contents of this file one line at a time, reading each line into *\next@*. This is done with a *\loop*, where we *\repeat* until *\ifeof* detects the end of the file (see section~\Sref{LOOP}). First we will see if *\next@* is a special line starting with ~*F* by using the test ** \expandafter\Finit@\next@\Finit@ \ifx\nextii@ F ** If this test is true, then *\next@* is `*F*\', and *\nextiii@* has been defined to be the \. We want to add `*\\*\' to *\fnpages@*, ** \expandafter\rightadd@\nextiii@\to\fnpages@ ** If the test is false, so that *\next@* is not one of the special lines for fancy footnote numbering, then it will be of the form \setbox0\hbox{\} \setbox1\hbox{V$_{\text1}$*~*V$_{\text2}$*~*V$_{\text3}$*~*V$_{\text4}$*~*} \setbox2\hbox{\} ** "copy0~"copy1"copy2 ** and we want to make the appropriate definition \setbox5\hbox{`}\setbox6\hbox{'} ** \def","box5\"copy0@L"box6",{"copy1"copy2} ** To do this we use ** \expandafter\getparts@\next@ ** and then ** \edef\next@{\gdef\csname\nextiv@ @L\endcsname "8ADDCSNAME"8 {\nextiii@\number\count@} \next@ ** Here the *\edef* makes *\next@* mean \setbox3\hbox{\}% ** "9\gdef"9","9\"copy3"relax@L"9{"9"copy1"relax"9"copy2} ** The control sequence `*\*\copy0*@L*' is not expanded further because it has been made equal to *\relax*. As noted on page~\ref{necc}, any control sequences appearing in *\next@* should be ones whose expansion is inhibited by *\noexpands@*; so \copy1\ will not be expanded further, because we will be doing all this within a group with *\noexpands@*. \pagelabel{A1} In addition, as we mentioned on page~\ref{wc2}, we will want to make *@* and *~* have category code~*11* within this group. Finally, we will set ** \endlinechar=-1 ** within this group, so that *\next@* will not contribute a blank space at the end because of the \CR\ at the end of the line. There is one further detail that we have to worry about. Many files, especially files that have been written by \tex\ itself, have a \CR\ at the end. In this case, the last *\next@* before the end of the file will be empty (if we hadn't set *\endlinechar=-1* it would be *\par*). Consequently, ** \expandafter\Finit@\next@\Finit@ ** and ** \expandafter\getparts@\next@ ** would give error messages. So, before any of our tests, we will first make sure that *\next@* isn't empty. After having read *\jobname.lax*, and thus obtaining all the information form the last run of the file, we re-open the file, to record information produced with this run: \C** \def\document{\let\fontlist@=\empty \immediate\openin\laxread@=\jobname.lax\relax "2 {\endlinechar=-1 \noexpands@ \catcode`\@=11 \catcode`\~=11 "2 \loop \ifeof\laxread@ \else \read\laxread@ to\next@ "2 \ifx\next@\empty "2 \else \expandafter\Finit@\next@\Finit@ "2 \ifx\nextii@ F% \expandafter\rightadd@\nextiii@\to\fnpages@ "2 \else \expandafter\getparts@\next@ \edef\next@{\gdef\csname\nextiv@ @L\endcsname {\nextiii@\number\count@}}% \next@ \fi \fi \repeat}% \immediate\closein\laxread@ \immediate\openout\laxwrite@=\jobname.lax\relax} ** \chapter Labels\label{LBL2}\endchapter \section{\CS{label}} We begin by setting \C** \let\thelabel@=\relax ** (see pages~\ref{IFTL} and~\ref{IFTL2}). Since the combination ** \thelabel@ ~\thelabel@@ ~\thelabel@@@ ~\thelabel@@@@ ~ ** occurs several times in our constructions, it will save time and space to introduce an abbreviation for it: \C** \def\thelabels@{\thelabel@ ~\thelabel@@ ~\thelabel@@@ ~\thelabel@@@@ ~} ** The definition of *\label#1* begins with *\prevanish@*, since *\label*'s are supposed to be invisible, and then gives an error message if *\thelabel@* is *\relax*, so that we are not in a construction that allows *\label*'s. Otherwise we first use the test ** \expandafter\ifx\csname#1@L\endcsname\relax ** which is true precisely when *#1* has not already been used as a \. In this case, we simply use ** \expandafter\xdef\csname#1@L\endcsname{\thelabels@0} \immediate\write\laxwrite@{@#1~\thelabels@1} ** to define `*\#1@L*' and to write to the *.lax* file. Of course, this must be done within a group with *\noexpands@*.\pagelabel{A2} If *#1* has already been used as a \, then we need to look at the \ of `*\#1@L*'. To do this we use ** \edef\next@{@~\csname#1@L\endcsname} \expandafter\getparts@\next@ ** so that *\count@* will have the value of \. We need the *\edef\next@* so that *\next@* will contain the actual value that the control sequence *\csname#1@L\endcsname* expands out to; naturally, we also need to perform this step in a group with *\noexpands@*. If, as a result of our test, *\count@* is even, we issue an error message that label *#1* has already been used. Otherwise, we simply use ** \expandafter\xdef\csname#1@L\endcsname{\thelabels@0} \immediate\write\laxwrite@{@#1~\thelabels@1} ** to define the control sequence and write to the *.lax* file: \C** \def\label#1{\prevanish@ \ifx\thelabel@\relax \Err@{There's nothing here to be labelled}% "2 \else {\noexpands@ "2 \expandafter\ifx\csname#1@L\endcsname\relax \expandafter\xdef\csname#1@L\endcsname{\thelabels@0}% \immediate\write\laxwrite@{@#1~\thelabels@1}% "2 \else \edef\next@{@~\csname#1@L\endcsname}% \expandafter\getparts@\next@ "2 \ifodd\count@ \expandafter\xdef\csname#1@L\endcsname{\thelabels@0}% \immediate\write\laxwrite@{@#1~\thelabels@1}% "2 \else \Err@{Label #1 already used}% \fi \fi }% \fi \postvanish@} ** For simplicity, we used a single group to enclose all the constructions that require a *\noexpands@*. Finally, having defined *\label* we now \C** \rightadd@\label\to\vanishlist@ ** \section{\CS{pagelabel}} There are several differences between the definition of *\pagelabel* and that of *\label*. \Pitem First of all, we don't have to check the value of *\thelabel@*, since *\pagelabel* is allowed anywhere. \pitem\label{EN} Instead of *\thelabel@*, \dots, *\thelabel@@@@*, which are defined by constructions that can be given a \, we use the values we want for a page label. Again, it will save time and space to introduce an abbreviation: \C** \def\thepages@{\page@N{\number\page@C}~% \page@S{\page@P\page@N{\number\page@C}\page@Q}~% \number\page@C ~\page@P\page@N{\number\page@C}\page@Q ~} ** (As with *\thelabels@*, we will be using *\thepages@* within a group where we have stated *\noexpands@*.) \pitem Instead of an *\immediate\write\laxwrite@*, we must use a (delayed) *\write\laxwrite@*. This is necessary to be sure of getting the proper value of *\page@C* into the *.lax* file. \smallskip When we encounter a *\pagelabel#1*, we again first use the test ** \expandafter\ifx\csname#1@L\endcsname\relax ** which is true if *#1* has not already been used as a \; in this case, we simply use ** \expandafter\def\csname#1@L\endcsname{\thepages@2} \write\laxwrite@{@#1~\thepages@3} ** If the test is not true, we again need to look at the type indicator with ** \edef\next@{@~\csname#1@L\endcsname} \expandafter\getparts@\next@ ** If this test sets *\count@* to be even, we issue an error message. But if *\count@* is odd we always ** \write\laxwrite@{@#1~\thepages@@3} ** moreover, we also ** \expandafter\xdef\csname#1@L\endcsname{\thelabels@2} ** if *\count@* is *1* (but not if it is *3*): \C** \def\pagelabel#1{\prevanish@ \expandafter\ifx\csname#1@L\endcsname\relax "2 {\noexpands@ \expandafter\xdef\csname#1@L\endcsname{\thepages@2}}% \write\laxwrite@{@#1~\thepages@3}% "2 \else "2 {\noexpands@ \edef\next@{@~\csname#1@L\endcsname}% \expandafter\getparts@\next@ "2 \ifodd\count@ \ifnum\count@=1 \expandafter\xdef\csname#1@L\endcsname{\thelabels@2}% \fi \write\laxwrite@{@#1~\thepages@3}% "2 \else \Err@{Label #1 already used}% \fi }% \fi \postvanish@} ** For simplicity, we have again used a single group for all constructions that require the *\noexpands@*. The *\write* happens to appear in this group, but as before (page~\ref{SUB1}), that is irrelevant, since the *\write* only happens during a *\shipout*.\pagelabel{SUB99} Finally, we add *\pagelabel* to *\vanishlist@*: \C** \rightadd@\pagelabel\to\vanishlist@ ** Page~39 of the \lamstex~Manual mentions that for a counter, say\linebreak `*\somecounter*', we want to allow such things as ** \pagelabel{thispage\number\somecounter} ** In version ~*1* of \lamstex@, special manipulations were required for this, but now both *\label* and *\pagelabel* automatically allow this, \pagelabel{EVNR} because in both cases the argument *#1* is expanded out in all parts of the definition. \chapter Cross-Referencing\label{xref}\endchapter \section{Preliminaries} We need a flag *\ifreferr@* to tell whether we want error messages or merely warning messages when a \ *#1* for a *\ref* isn't found: \C** \newif\ifreferr@ \referr@true \def\RefErrors{\global\referr@true} \def\RefWarnings{\global\referr@false} ** And we want to define a routine that prints either the desired error message or the desired warning message. For \tex~ version *2*, the best we can do is the following, where *\W@* from \amstex\ stands for `*\immediate\write16 *': ** \ifreferr@\Err@{No \noexpand\label found for #1}\else \W@{Warning: No \noexpand\label found for #1.}\fi} ** (As before, compare section~\Sref{SACN} for the use of *\noexpand*.) But in \tex~version *3*, we can mimic an error message more closely by printing the line number after the warning, using *\inputlineno*: ** \W@{Warning: No \noexpand\label found for #1.} \W@{l.\number\inputlineno\space ... #1} ** (We have to settle for `*...*' since we can't actually capture the contents of the input line.) It looks even better to print something like ** l.3 ... \ref{#1} ** when a \ for *\ref* isn't found, and ** l.3 ... \Ref{#1} ** when a \ for *\Ref* isn't found, etc. So we will actually be creating a control sequence with two arguments, the first corresponding to the *\ref* or *\Ref*, and the second to the \, so that we will print ** \W@{Warning: No \noexpand\label found for #2.} \W@{l.\number\inputlineno\space ... \string#1{#2}} ** Since we can't be sure when people will be switching to version~*3*, it seems best to use different code for the two versions. We can check for the version of \tex\ with \setbox0\hbox{(here *0* is `zero', not `oh')} ** \setbox0=\hbox{\global\count@=`^^30} "box0 ** In \tex~version *3*, *\count@* will then have the value *48*, but in \tex~version~*2*, it will have the value *115* (and *\box0* will also contain the character *0*). Instead of running this test each time we have to print a warning, we will simply let `*\versionthree@*' be undefined in version~*2* and *\relax* in version~*3*: \C** \setbox0=\hbox{\global\count@=`^^30} \ifnum\count@=48 \let\versionthree@=\relax\fi ** Then we can use a message of the form ** \ifreferr@\Err@{No \noexpand\label found for #2}\else \W@{Warning: No \noexpand\label found for #2.}% \ifx\versionthree@\relax \W@{l.\number\inputlineno\space ... \string#1{#2}}\fi \fi ** (The *\global\count@* assignment here doesn't really contradict the policy of section~\Sref{LANDG} because this *\global* assignment is made just once, at the top level, not within a macro.) \small The simpler looking test ** \setbox0=\hbox{\global\count@=`^^00} ** has all sorts of insidious complications, because in version~*3* of \tex@, *^^00* stands for the {\ninerm ASCII} *NUL*, which is usually an {\it ignored\/} character in \tex\,! Since *^^30* is the code for the number *0*, it is unlikely to be special. \endsmall \section{\CS{ref} and its relatives\label{refED}} For *\ref#1* we simply have to use the test ** \expandafter\ifx\csname#1@L\endcsname\relax ** to check whether *#1* is a label, and then pick out the relevant portion of the value of *\csname#1@L\endcsname*. With this in mind, we might first define *\nolabel@* by ** \def\nolabel@#1#2{\expandafter\ifx\csname#2@L\endcsname\relax \ifreferr@\Err@{No \noexpand\label found for #2}\else \W@{Warning: No \noexpand\label found for #2.}% \ifx\versionthree@\relax \W@{l.\number\inputlineno\space ... \string#1{#2}}\fi \fi \else} ** so that *\nolabel@#1#2* would give an error or warning message if *#2* hasn't been used as a label, and otherwise do whatever follows. However, it will be a little more convenient to define *\nolabel@#1#2#3*, with an extra argument,~ *#3*, that is often given the value *\relax*: \C** \def\nolabel@#1#2#3{% \expandafter\ifx\csname#2@L\endcsname\relax \ifreferr@\Err@{No \noexpand\label found for #2}\else \W@{Warning: No \noexpand\label found for #2.}% \ifx\versionthree@\relax \W@{l.\number\inputlineno\space ... \string#1{#2}}\fi \fi #3\else} ** We also want a routine that sets a scratch token to the actual value of the control sequence *\csname#1@L\endcsname*; because this will have to be defined within a group, we use the scratch token *\Next@*, reserved for *\global* assignments (page~\ref{GNXT}): \C** \def\csL@#1{{\noexpands@\xdef\Next@{\csname#1@L\endcsname}}} ** Now *\ref#1* should print an error or warning message if *#1* is not a \, ** \def\ref#1{\nolabel@\ref{#1}\relax . . . ** Otherwise, it should print everything up to the first *~* in the value of the control sequence *\csname#1@L\endcsname*. If we define ** \def\nextii@#1~#2\nextii@{#1} ** and also use ** \csL@{#1} ** to set *\Next@* to the value of *\csname#1@L\endcsname*, then we just have to use ** \expandafter\nextii@\Next@\nextii@ ** So the definition of *\ref* is \C** \def\ref#1{\nolabel@\ref{#1}\relax "8DEFREF2"8 \def\nextii@##1~##2\nextii@{##1}% \csL@{#1}\expandafter\nextii@\Next@\nextii@\fi} ** Similarly for \C** \def\Ref#1{\nolabel@\Ref{#1}\relax \def\nextii@##1~##2~##3\nextii@{##2}% \csL@{#1}\expandafter\nextii@\Next@\nextii@\fi} ** and \C** \def\nref#1{\nolabel@\nref{#1}\relax \def\nextii@##1~##2~##3~##4\nextii@{##3}% \csL@{#1}\expandafter\nextii@\Next@\nextii@\fi} ** and \C** \def\pref#1{\nolabel@\pref{#1}\relax \def\nextii@##1~##2~##3~##4~##5\nextii@{##4}% \csL@{#1}\expandafter\nextii@\Next@\nextii@\fi} ** For later purposes, we will \C** \let\pref@=\pref ** so that *\pref@* may be used to reinstate the usual meaning of *\pref* if it has been redefined. The definition of *\Evaluatenref* is somewhat different---we use the generality built into *\nolabel@* to \hbox{*\gdef\Nref{-10000 }*} when *#1* isn't a label: \C** \def\Evaluatenref#1{% \nolabel@\Evaluatenref{#1}{\gdef\Nref{-10000 }}% \def\nextii@##1~##2~##3~##4~\nextii@{\def\nextii@{##3}}% \csL@{#1}\expandafter\nextii@\Next@\nextii@ \xdef\Nref{\nextii@}\fi} ** *\Evaluatepref* is analogous: \C** \def\Evaluatepref#1{% \nolabel@\Evaluatepref{#1}{\global\let\Pref=\empty}% \def\nextii@##1~##2~##3~##4~##5\nextii@{\def\nextii@{##4}}% \csL@{#1}\expandafter\nextii@\Next@\nextii@ \xdef\Pref{\nextii@}\fi} ** Note that the \ is expanded out in both *\nolabel@* and *\csL@*. Consequently (compare page~\ref{EVNR}), *\Evaluatenref* and *\Evaluatepref* can have arguments containing *\number\somecounter* for a counter `*\somecounter*'; in fact, even *\ref*, *\Ref*, *\pref* and *\nref* can contain such arguments. \small Applications of *\Evaluatenref* and *\Evaluatepref* are given on pages~ 38@--39 of the \lamstex~Manual. `*\Evaluateref*' and `*\EvaluateRef*' haven't been provided, on the grounds that in similar situations one would be able to determine the value of *\ref* from that of *\nref*, and the value of *\Ref* from that of *\pref*. \endsmall \chapter Reading auxiliary files\label{RAF}\endchapter Although *\readlax* is similar to *\document*, there are a few significant differences. \section{\CS{readlax}\label{rl}} *\readlax#1* first opens the file *#1.lax* for reading, giving a conspicuous message if the file isn't found, i.e., if the test *\ifeof* is true at the beginning. (Note that *\document* {\it doesn't\/} give a message if *\jobname.lax* isn't found.) Like *\document*, it then processes the contents of this file one line at a time, except that it will read the line into the control sequence *\nextv@*. Again, this is done with a *\loop* that repeats until *\ifeof* detects the end of the file. As with *\document*, we want to ignore the case where *\nextv@* is empty. Now, however, we also want to ignore the lines beginning with *F*, because information about the numbering of footnotes from another file would conflict with information gathered for the current file. So the definition of *\readlax#1* begins ** \def\readlax#1{\immediate\openin\laxread@=#1.lax\relax \ifeof\laxread@\W@{}\W@{File #1.lax not found.}\W@{}\fi "2 {\endlinechar=-1 \noexpands@ \catcode`\@=11 \catcode`\~=11 \loop \ifeof\laxread@ \else \read\laxread@ to\nextv@ \ifx\nextv@\empty "2 \else \expandafter\Finit@\nextv@\Finit@ \ifx\nextii@ F% \else ** When a suitable line *\nextv@* has been found, we use ** \expandafter\getparts@\nextv@ ** to stores the \ part of *\nextv@* in *\nextiii@*, the value of the \ in the counter *\count@*, and the rest of *\nextv@*, except for the initial *~*, in *\nextiii@*.\pagelabel{OMITSQ} Then we have to use the test ** \expandafter\ifx\csname\nextiv@ @L\endcsname\relax ** to see if the \ part of *\nextv@* has already been used, because this represents a conflicting use of \, so that we need to issue an error message (remember that *\readlax* can be used at any time, possibly after some \'s have already been made). If this test is true, so that the \ does not appear, we will define `*\*\*@L*' to be the remainder of *\nextv@*, {\it except that we will change the\/} \ to~*0* if it is~*1* and to~*2* if it is~*3*. For this we can use ** \edef\next@{\gdef\csname\nextiv@ @L\endcsname {\nextiii@\ifnum\count@=1 0\else 2\fi}} \next@ ** (within a group with *\noexpands@*). As a consequence of this arrangement, any \ from the auxiliary file that we read in with *\readlax* will count as a ``current'' label, so that if *\label{*\*}* occurs later in the file we will get an error message, rather than changing the data for this \. That seems like the reasonable arrangement, since we use *\readlax* to get information from what is presumably a different part of the same document, and the same *\label{*\*}* shouldn't appear in two different parts of the document (at least, not if we intend to combine the labels in the two parts with *\readlax*). Our whole definition is \C** \def\readlax#1{\immediate\openin\laxread@=#1.lax\relax \ifeof\laxread@\W@{}\W@{File #1.lax not found.}\W@{}\fi "2 {\endlinechar=-1 \noexpands@ \catcode`\@=11 \catcode`\~=11 "2 \loop \ifeof\laxread@ \else "2 \read\laxread@ to\nextv@ \ifx\nextv@\empty "2 \else \expandafter\Finit@\nextv@\Finit@ \ifx\nextii@ F% "2 \else \expandafter\getparts@\nextv@ \expandafter\ifx\csname\nextiv@ @L\endcsname\relax "2 \edef\next@{\gdef\csname\nextiv@ @L\endcsname {\nextiii@\ifnum\count@=1 0\else 2\fi}}% \next@ "2 \else \Err@{Label \nextiv@\space in #1.lax already used}% \fi \fi \fi \repeat}% \immediate\closein\laxread@} ** At this point we are finished with all definitions that involve *~* with category code~*11*: \C** \catcode`\~=\active ** \section{Style files\label{STYF}} Control sequences to read in style files are simple: \C** \def\docstyle#1{\input #1.st\relax} \def\predocstyle#1{\input #1.stf\relax} \def\postdocstyle#1{\input #1.stb\relax} **