From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- macros/lamstex/doc/wiz4.tex | 4802 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4802 insertions(+) create mode 100644 macros/lamstex/doc/wiz4.tex (limited to 'macros/lamstex/doc/wiz4.tex') diff --git a/macros/lamstex/doc/wiz4.tex b/macros/lamstex/doc/wiz4.tex new file mode 100644 index 0000000000..6e14c3e759 --- /dev/null +++ b/macros/lamstex/doc/wiz4.tex @@ -0,0 +1,4802 @@ +\part Miscellaneous\\Constructions\endpart + + + + +\chapter Literal mode\endchapter + +The basic mechanism for literal mode is really not all that complicated. +However, the final \lamstex\ definitions are complicated indeed, because +of +\bullist +\item special features that we want to incorporate; +\item subtle possibilities for bugs; +\item the desire for generality. +\endbullist + + +In order to temporarily eliminate the third complicating factor, we will +first consider what is needed to define the particular version of literal +mode in which *"1* is the delimiter and *""* is used to serve as the +escape character in literal mode. + + +\section{In-line literal mode\label{ILLM}} +The basic idea of in-line literal mode, with *"1* as the delimiter +and *""* as the escape character, is to +** +\def\lit"1{\begingroup\litcodes@\litdefs@\tt\lit@} +"slip +\def\lit@#1"1{#1\endgroup} +** +where *\litdefs@* is the abbreviation +** +"hskip-50pt\def\litdefs@{\let\0=\empty\def\1{\char42 }\def\ {\char32 }\def\""{\char34 }} +** +and +*\litcodes@* changes all the category codes, +** +\def\litcodes@{\catcode`\\=12 + \catcode`\{=12 \catcode`\}=12 + \catcode`\$=12 \catcode`\&=12 + \catcode`\#=12 + \catcode`\^=12 \catcode`\_=12 + \catcode`\@=12 \catcode`\~=12 + \catcode`\%=12 \catcode`\""=0 } +** +so that these new category codes are in force before *\lit@* reads in its +argument. + + +The first line of this definition +says that *\* will be an ordinary character once +*\litcodes@* appears. + The next two lines make +ordinary characters out of the characters with category codes ~*1*, *2*, *3* +and~ *4*. Category~*5* (end of line) isn't changed for in-line-literal mode, +so the next line just handles the character *#* with category code ~*6*, and +the next line handles category codes~*7* and~*8*. We don't bother with +category~*9* (ignored character) and category~*10*~ (space) +will be attended to in a +moment. Categories~*11* and ~*12* (letter and other character) need no +special treatment. The next line handles category~*13* (active); the final +line handles category ~*14* (comment character), leaving + category~*15* (invalid) + alone, and then finally makes *""* the escape character. + +Then *\lit"1..."1* will print out `*...*', with each of the +tokens *\*, *{*, *}*, *$*, *&*, *#*, *^*, *_*, +*@*, *~*, *%* being printed in the *\tt* font. +Moreover, within the *\lit"1..."1* region, *""0* will stand for *\empty*, +*""1* will stand for character~*42* on the *\tt* font, which is +the *"1* symbol, `*"" *' will stand for +character~*32*, which is the *" * symbol, and +*""""* will stand for character~*34* on the *\tt* font, +which is the *""* symbol. + + However, we also +want spaces to act specially. +*plain* \tex's +*\obeyspaces* makes spaces active, and defines each active space to +give one space in the output. + But we will want a different definition for literal mode. +If we first use +** +{\obeyspaces +\gdef\defspace@{\def {\hskip.5emminus.15em}}} +** +so that *\defspace@* makes the active space give spacing suitable for +literal mode, +then we can simply add +** +\obeyspaces\defspace@ +** +to the end of the definition of +*\litcodes@*. + +Actually, we will use +** +{\obeyspaces +\gdef\defspace@{\def {\allowbreak\hskip.5emminus.15em}}} +** +Then a line break can occur between +spaces. For example, \hbox{*\lit"1A B"1*}, +with four\vadjust{\nobreak} + spaces between the letters, could split after the second, +giving +`*A *\null\linebreak +*B*'; two spaces remain at the end of the first line, although all +subsequent spaces disappear before the second letter. +Note that *\allowbreak* is not only shorter than *\penalty0*, but much +preferable in this case, since we cannot afford to leave a space after +the~*0*, so would have to add *\relax* to be on the safe side. + +\small I made this choice so +that the first line could at least indicate that more than one space was +involved, but it looked too weird to have spaces at the beginning of +the next line. If that more literal sort of literal mode is preferred, +it is only necessary to define the active space to mean +** +\allowbreak\hbox to.5em{}\hskip0emminus.15em +** +In practice, one would presumably be printing *" *'s if the number of spaces +needs to be emphasized. +\endsmall + + + +The *\allowbreak* at the beginning of the definition of +a space in literal mode does introduce one slight complication: we should +** +\def\lit"1{\leavevmode\begingroup . . .} +** +---otherwise a `*\lit"1 *' at the beginning of a paragraph will +contribute an *\allowbreak* in {\it vertical\/} mode, possibly overruling +a *\nobreak* that occurs before it. + + +Moreover, the definition of *\lit@* should be changed to +** +\def\lit@#1"1{#1\endgroup\null} +** +so that a *\lit"1..."1* construction ending with a space won't have this +space deleted by any succeeding *\unskip*. \pagelabel{LITN} + +Making spaces active means that we don't have to say *\frenchspacing*, +since now there aren't any spaces after punctuation. However, as {\it The +\tex book\/} points out (page~381), there's another slight problem, because +the *\tt* font has the ligatures *?"0`* and *!"0`*, which print +as {\tt?`} and {\tt!`} respectively (sigh). So we +must +** +{\catcode`\`=\active\gdef`{\relax\lq}} +** +and then use +** +\catcode`\`=\active\obeyspaces\defspace@ +** +at the end of the +definition of *\litcodes@*. + +Finally, we want to set the *\hyphenchar* of the *\tentt* font +(selected by *\tt*) to ~*-1*, so that hyphenation won't be allowed: +** +\def\lit"1{\leavevmode\begingroup\litcodes@\litdefs@ + \tt\hyphenchar\tentt=-1 \lit@} +** + + + +\small +If the possibility of hyphenation is preferred, this last clause +can simply be omitted. +Or one could add +** +\def\-{\discretionary{\char45 }{}{}} +** +to the *\litdefs@*, so that *""-* could be used for a discretionary hyphen. + +\andsmall + In the \lamstex~Manual, *\tt* means *\tentt* +for the usual 10~point text, but *\ninett* in 9~point type (used for +these ``small print'' sections), and *\eighttt* in 8~point (used for the +footnotes). The style file for the manual simply sets the +*\hyphenchar* of all three to ~*-1* at the beginning, but +a more complicated scheme could be used. +For example, we could have +*\tenpoint* define *\pointsize@* to be~*t*, and *\ninepoint* define +*\pointsize@* to be~*n*, and *\eightpoint* define +*\pointsize@* to be ~*e*. And then we could replace the clause +** +\hyphenchar\tentt=-1 +** +with +** +\if\pointsize@ t\hyphenchar\tentt=-1 \else + \if\pointsize@ n\hyphenchar\ninett=-1 \else + \hyphenchar\eighttt=-1 \fi\fi +** + +(As a matter of fact, the style file for the Manual does make use of + *\pointsize@*, + for defining the \lamstex\ logo, since the $\Cal A$, $\Cal M$, and +$\Cal S$ need to be selected from different fonts for different sizes.) +\endsmall + + +\section{Displayed literal mode} +For ``displayed'' literal mode, we are going to use *\obeylines* to +make *^^M* active, but we +will need a new definition of the active *^^M*. It will be convenient +to use +** +{\obeylines\gdef\letM@{\let^^M=\CtrlM@}} +** +where *\CtrlM@* will be defined in a moment, so that + *\letM@* will make *^^M* have the meaning of *\CtrlM@* once +*\obeylines* +has appeared. + +We can begin defining *\Lit"1* by: +** +\def\Lit"1{\bigskip\begingroup + \litcodes@\obeylines\letM@\tt\Lit@} +** +We don't need to disable hyphenation, since we are going to be setting +each line as a separate *\hbox* (and therefore the shrink in the +definition of the active space will also be irrelevant). For reasons +to be discussed in section~\Sref{WARY}, *\litdefs@* hasn't been included yet. + +*\Lit@* will begin setting an *\hbox*, so we first declare +** +\newbox\litbox@ +** +and then +** +\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@} +** + +Thus, the *\Lit@* will start setting *\box\litbox@* to be whatever +is on the current line, with the literal codes in effect, as well as +the temporary definitions from *\litdefs@*. + When we get to the end of the line, we will +encounter +a *^^M*, which will have the meaning of *\CtrlM@*, which we can +define by +** +\def\CtrlM@{\egroup "8CTRLM"8 + \box\litbox@ + \Lit@} +** +so that the *^^M* will simply cause the *\hbox* containing the line +to be added to the vertical list, and then start setting another +*\box\litbox@*. + +In order to have the closing *"1* end the literal display, the simplest +method +is to make the *"1* {\it active\/} during the display and have it defined by +** +\def"1{\egroup\endgroup\bigskip} "8DEFSTAR3"8 +** +The *\egroup* ends the *\box\litbox@* + that started being set at the beginning of +the line containing the *"1*, but instead of adding this (presumably +empty) box to the vertical list, we simply supply the *\endgroup* that +matches the *\begingroup* contributed by *\Lit"1*. + +In order to do this, we need to do something like +** +{\catcode`\"1=\active + \gdef\defstar@{\def"1{\egroup\endgroup\bigskip}} "8defstar"8 +} +** +so that *\defstar@* will define *"1* properly once it is active, and then +** +\def\Lit"1{\bigskip\begingroup + \litcodes@ + \catcode`\"1=\active\defstar@ + \obeylines\letM@\tt\Lit@} +** + + +The only slight problem with our definition is that the very first line +of a +** +\Lit"1 + . . . + . . . +"1 +** +contributes an empty box. To take care of this, and for later purposes +(sections~\Sref{PPB} and ~\Sref{LPB}), we will declare a counter +** +\newcount\litlines@ +** +which *\Lit"1* will set to~*0*, and then we will have +*\CtrlM@* (page~\ref{CTRLM}) simply increase *\litlines@* by~*1* if it +is~*0*, but add *\box\litbox@* if *\litlines@* is not~*0*.\pagelabel{LCNT} + +\section{Notes for the wary\label{WARY}} +Although we still have many features to add, +there are already some important point to be made + about our definitions. + +First of all, +*\Lit"1* ends up processing only one line at a time. Consequently, +there is no limit on the number of lines before the ending *"1*. + +Second, we were careful to arrange that *\litdefs@* +will be in force only within each individual *\box\litbox@*. + + {\bfit And this is +extremely important:\/} After any particular *\box\litbox@* has been placed on +the main vertical list, \tex\ may decide to exercise the *\output* routine, +possibly long before the *\endgroup* supplied by the final *"1*. +If we had put *\litdefs@* right into the definition of +*\Lit"1*, then *\litdefs@* would be in effect when the +*\output* routine is invoked, +which could lead to havoc. For example, suppose that in the book style +we have typed +** +\chapter The \LamSTeX\ Co\""op\endchapter +** +so that even-numbered pages will use +** +The \LamSTeX\ Co\""op +** +in the running heads. Then if this running head happened to be + typeset while the literal +mode definitions are in force, we would end up with +\medskip +\centerline{\cmtenrm \def\LamSTeX{L\kern-.4em\raise.3ex + \hbox{$\ssize\Cal A$}\kern-.25em + \lower.4ex\hbox{\eightsy M}\kern-.1em{$\Cal S$}-\TeX} +The \lamstex\char32 Co\char34 op} +\medskip +\noindent since the `{\cmtenrm\char32 }' symbol is +*\char32* in the Computer Modern fonts, while *\char34* is +{\cmtenrm\char34 }. +Similarly, the user should be able to define *\0* and *\1*, +and have them used in running heads, without worrying about them +changing definitions if the output routine is invoked in the middle of +literal mode. + + +\section{Prohibiting page breaks\label{PPB}} +Normally, we want to prohibit breaks between lines of displayed literal +material, so we also want to add a penalty after *\box\litbox@*. +We will declare a new counter +** +\newcount\interlitpenalty@ +\interlitpenalty@=10000 +** +and we will have *\CtrlM@* (page~\ref{CTRLM}) +add *\penalty\interlitpenalty@* before the current +*\box\litbox@* except for the very first box +(other +constructions, see section~\Sref{LPB}, can insert other penalties, or +give different values to *\interlitpenalty@*). + The following definition +takes care of this, together with the fact that we also +don't want the empty box +from the first line (page~\ref{LCNT}): +** +\def\CtrlM@{\egroup + \ifcase\litlines@ + \advance\litlines@ by 1 + \or + \box\litbox@ \advance\litlines@ by 1 + \else + \penalty\interlitpenalty@\box\litbox@ + \fi + \Lit@ +** +Notice that with this arrangement, + *\penalty\litpenalty@* ends up being added after each *\box\litbox@*, +{\it except\/} +the last box,\pagelabel{nolastpen} + so that a page break can occur at the *\bigskip* supplied by +the closing *"1* (page~\ref{DEFSTAR3}); an explicit *\penalty* could be added +before the *\bigskip* if we wanted to discourage or encourage a page +break at that point. + + +\section{Indentation} +We usually want +displayed literal constructions to be indented by a certain amount. So +we declare a new dimension +** +\newdimen\litindent +** +with the default value +** +\litindent=20pt +** +and we add *\hskip\litindent* at the beginning of each box: +** +\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@\hskip\litindent} +** + + +\section{{\ninerm TAB}'s}Proper interpretation of the {\ninerm TAB} +character (*^^I*) + is another +feature that we want to add. +We will use +** +{\catcode`\^^I=\active\gdef\letTAB@{\let^^I=\TAB@}} +** +so that *\letTAB@* will make an active *^^I* mean *\TAB@*, which we +will define in a moment, and then we will add +** +\catcode`\^^I=\active\letTAB@ +** +to the definition of *\Lit"1*, before the *\obeylines*. + +For *\TAB@*, we want, +first of all, to allow for variances in the spacing for {\ninerm TAB}'s. +So +we will create a new counter, with the default value ~*8*, +** +\newcount\littab@ +\littab@=8 +** +as well as the construction *\littab*, to change the value, +** +\def\littab#1{\littab@=#1\relax} +** + +Every time that we encounter a *^^I* while we +*\setbox\litbox@*, we want to supply an *\egroup*, so that *\box\litbox@* +will be complete, add extra space at the end of + *\box\litbox@* so that it has the requisite +width (namely the next multiple of *\littab@* +times the width of *\hbox{\tt0}*), and then include all this at the beginning +of another +** +\setbox\litbox@=\hbox\bgroup\litdefs@ +** + {\it The~ \tex book}, page~391, gives +a simple way to find the required extra space: + If *\dimen@* is the width of our box, +and *\dimen@ii* is *\littab@* times the width of *\hbox{\tt0}*, then + to see how many times +*\dimen@* fits within *\dimen@ii*, we can simply +** +\divide\dimen@ii by \dimen@ +\multiply\dimen@ii by \dimen@ +** +Here *\dimen@* will be converted to its equivalent in scaled points (i.e., +*1pt* will become~*65536*). At the end, *\dimen@ii* will be the largest +multiple of *\dimen@* that is + $\le$ ~*\dimen@ii*, +so we will just have to increase *\dimen@* by *\littab@* times the +width of *\hbox{\tt0}* to move to the next tab. +\footnote{Although \tex\ indicates dimensions with decimal points, internally +all dimensions are expressed in terms of scaled points. Consequently, these +calculations will not have any rounding errors.} + We have to remember, +however, that all our boxes begin with an extra *\litindent* amount of +space: +** +\def\TAB@{\egroup + \dimen@=\wd\litbox@ + \advance\dimen@ by -\litindent +"2 + \setbox0=\hbox{\tt0}% +"2 + \dimen@ii=\littab@\wd0 + \divide\dimen@ by \dimen@ii + \multiply\dimen@ by \dimen@ii +"2 + \advance\dimen@ by \littab@\wd0 + \advance\dimen@ by \litindent + \setbox\litbox@=\hbox\bgroup\litdefs@\hbox to\dimen@ + {\unhbox\litbox@\hfil}} +** + +\section{Widow control\label{WC}} +In order to provide control over widow lines before literal +displays, we will make + literal displays behave very much like displayed formulas. +We first use +** +\def\Lit"1{\ifhmode + $$\abovedisplayskip=\bigskipamount + \abovedisplayshortskip=\bigskipamount + \belowdisplayskip=0pt \belowdisplayshortskip=0pt + \postdisplaypenalty=10000 + $$\vskip-\baselineskip\else\bigskip\fi + \begingroup . . . +** +to produce an empty displayed formula right above the displayed literal +mode +material. The settings for *\abovedisplayskip* and for +the `*short*' version ensure that a *\bigskip* will precede this +formula. The settings for *\belowdisplay* and for the `*short*' version +ensure that there is no extra space between this empty displayed formula +and the displayed literal mode material. The +*\vskip-\baselinekip* deletes the extra space that this empty +formula contributes. +Finally, the empty display and the display +literal mode material are kept +on the same page by the *\postdisplaypenalty*. + + Consequently, +\tex's page breaking decisions before *\Lit"1* material, will be the +same as before displayed formulas. + +If we are already in vertical mode, we just add the *\bigskip* (we don't +want to add an empty formula in that case, since *$$...$$* in vertical +mode actually produces an extra blank line [{\it The \tex book}, page~316]). + +\small As mentioned on page~85 of the \lamstex~Manual, changing the values of +*\abovedisplayskip*, etc., in this definition will change the amount of +space before a literal display. One could even add a clause +** +\predisplaypenalty=... +** +changing *\predisplaypenalty* from its default value of ~*10000*, + to allow, or encourage, page breaks before a literal display +(if this done, then +a *\penalty* of that amount should be added before the *\bigskip* in the +*\else* clause above). + However, the last line +on page~85 is just wrong: changing *\displaywidowpenalty* within the formula +won't affect anything. +\endsmall + + +As with displayed formulas (compare section~\Sref{pretend1}), +special care is required in the +definition of *"1* made by *\defstar@* (page~\ref{DEFSTAR3}), in case +an invisible construction follows. Basically we need to augment +the definition to +** +\egroup\endgroup\bigskip +\vskip-\parskip +\noindent@@\futurelet\next\pretendspace@ +** +to start a *\noindent*'ed paragraph, and take care of the fact that +an invisible construction may follow (compare +page~\ref{ADDFNP}). But now we have an extra complication: we must +skip over the space following the *"1* before adding the *\noindent@@*, so +that our *\noindent*'ed paragraph doesn't begin with an extra space. +So we really need +** +\egroup\endgroup\bigskip +\vskip-\parskip +\def\next@{\noindent@@\futurelet\next\pretendspace@} +\FNSS@\next@ +** + +\small! As in the case of a displayed formula (page~\ref{WARNPAR}), +users must be warned against adding ``invisible'' constructions +at the end of a literal display that ends a paragraph. + +\andsmall The treatment of the end of display literal mode has been changed +from version~*1* of \lamstex@, where a displayed formula was added at the end +also (with undesirable side effects). +\endsmall + + +\section{Page breaks\label{LPB}} +Within a literal display we want *\displaybreak* to force a page break +when it appears on a line by itself; similarly *\allowdisplaybreak* should +allow a page break, and *\allowdisplaybreaks* should allow a page break +at that line and all succeeding lines. + + +Within the definition of *\Lit"1* we will add +** +\def\displaybreak{\egroup\break\litlines@=0 \Lit@} +** +The first *\egroup* ends the *\box\litbox@* that + was being set at the beginning +of the line containing the +** +""displaybreak +** +The *^^M* at the end of this line is still there, and will end an empty +*\box\litbox@* started by the *\Lit@*. Since we have set *\litlines@=0*, +however, this box will not appear on the vertical list, nor will a penalty +appear before the next *\box\litbox@*. + +Thus, +\setbox0\hbox{\}% +\setbox1\hbox{\}% +** +"box0 +""displaybreak +"box1 +** +will produce +\setbox0\hbox{\} +\setbox1\hbox{*\null* box} +\setbox6\hbox{*\vskip -\baselineskip *} % 15 spaces +\setbox1\hbox to \wd6{\unhbox1 \hfil} +\setbox2\hbox{empty box created by *\Lit@*} +\setbox3\hbox{appropriate *\baselineskip* glue for next box} +\setbox4\hbox{put in by the definition} +\setbox5\hbox{\} +** +"box0 +\penalty -10000 +"box3 +"box5 +** +The +appropriate *\baselineskip* glue will disappear +after the page break at the *\penalty-10000*, +so the next page will start with the second line +(preceded by suitable *\topskip* glue). + +\medbreak + +Similarly, we will define +** +\def\allowdisplaybreak{\egroup\allowbreak\litlines@=0 \Lit@} +** +Then +\setbox0\hbox{\} +\setbox1\hbox{\} +** +"box0 +""allowdisplaybreak +"box1 +** +will produce +\setbox0\hbox{\} +\setbox1\hbox{*\null* box} +\setbox6\hbox{*\vskip -\baselineskip *} % 15 spaces +\setbox1\hbox to \wd6{\unhbox1 \hfil} +\setbox2\hbox{empty box created by *\Lit@*} +\setbox3\hbox{appropriate *\baselineskip* glue for next box} +\setbox4\hbox{put in by the definition} +\setbox5\hbox{\} +** +"box0 +\penalty 0 +"box3 +"box5 +** + +Finally, we will define +** +\def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty=0 \litlines@=0 \Lit@} +** +In this case, +\setbox0\hbox{\} +\setbox1\hbox{\} +** +"box0 +""allowdisplaybreaks +"box1 +** +produces +\setbox0\hbox{\} +\setbox1\hbox{*\null* box} +\setbox2\hbox{empty box created by *\Lit@*} +\setbox3\hbox{appropriate *\baselineskip* glue for next box} +\setbox4\hbox{put in by the definition} +\setbox5\hbox{\} +** +"box0 +\penalty 0 +"box3 +"box5 +\penalty 0 + . . . +** +with a *\penalty0* after all succeeding lines of the literal display, + except the very last (see page~\ref{nolastpen}). + + +\small This manual contains numerous page references to material in +a literal display. But + a *\pagelabel* right before or right + after the literal display couldn't be counted upon to give the proper page +number, especially since many displays were allowed to +split across pages. So the style file contains the definition +** +\def\8#1\8{\pagelabel{#1}} +** +Then on page~\ref{NameHLcounter} I could type +\litindent=-20pt +** +\rightadd@#2\to\overlonglist@ + \edef\next@{\global\let\csname\exstring@#2@C\endcsname + =\expandafter\noexpand\csname HL@C#1\endcsname}\next@ ""8NameHLcounter""8 +** +so that *\ref{NameHLcounter}* could be used on page~\ref{useNameHLcounter} + to refer to the page containing +this line.\restorelitindent +\endsmall + + +\section{\CS{Litbox}\label{CSLITBOX}}For the construction +** +\Litbox#1="1 + . . . +"1 +** +we can first use +** +{\catcode`\"1=\active + \gdef\defboxstar@{\def"1{\egroup\egroup\endgroup}} +} +** +so that *\defboxstar@* defines *"1* once *"1* is active, in a +different manner than *\defstar@* did (adding an extra *\egroup*, and +omitting the remaining material). +Then we want a definition like +** +\def\Litbox#1="1{\begingroup\defboxstar@ + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\global\setbox#1=\vbox\bgroup + \litindent=0pt \litlines@=0 \Lit@} +** +The *\litindent=0pt* eliminates extra space at the beginning of each\linebreak +*\box\litbox@*. All these boxes are simply stacked inside the *\vbox*, +and then the closing *"1* supplies an *\egroup* to end the (empty) +*\box\litbox@* already begun, another *\egroup* to end the *\vbox*, and a +final *\endgroup* to match the *\begingroup*. + +We might as well also add in +the definition of *\allowdisplaybreak* and +*\allowdisplaybreaks*, + in case +the created box is later *\unvbox*'ed. + +But there is a slight problem with our whole scheme, + because we don't want the + assignment *\setbox#1* to be global +when *#1* is even (section~\Sref{LANDG}). + To get around +this, we will declare a new box +** +\newbox\Litbox@ +** +and +*\global\setbox\Litbox@*, and then after the *\endgroup* supplied by the +concluding *"1* we will *\setbox#1\box\Litbox@* for even~*#1*, but +add a *\global* for odd~*#1*: +** +\def\Litbox#1="1{\begingroup + \ifodd#1\relax\aftergroup\global\fi + \aftergroup\setbox\aftergroup#1% + \aftergroup\box\aftergroup\Litbox@ + \defboxstar@ + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\global\setbox\Litbox@=\vbox\bgroup + \litindent=0pt \litlines@=0 \Lit@} +** +The various *\aftergroup* tokens---*\global* (if *#1* is odd), +*\setbox*, *#1*, *\box*, and +*\Litbox@*---are +saved up and performed after the final *\egroup* provided by the final *"1*; +in other words, *\setbox#1\box\Litbox@* is performed after *\box\Litbox@* has +been (*\global*'ly) set. + + +\section{The general definition} +Now that we have all the pieces, let's try to put them together, and +allow for greater generality. + +We begin with things that don't depend on the particular choice of the +literal delimiter or backslash. + +\C** +\newdimen\litindent +\litindent=20pt +\newbox\litbox@ +\newbox\Litbox@ +\newcount\interlitpenalty@ +\interlitpenalty@=10000 +\newcount\litlines@ +"slip +{\obeyspaces\gdef\defspace@{% + \def {\allowbreak\hskip.5emminus.15em\relax}}} +"slip +{\obeylines\gdef\letM@{\let^^M=\CtrlM@}} +"slip +{\catcode`\`=\active\gdef`{\relax\lq}} +"slip +\def\CtrlM@{\egroup + \ifcase\litlines@ + \advance\litlines@ by 1 + \or + \box\litbox@ \advance\litlines@ by 1 + \else + \penalty\interlitpenalty@ \box\litbox@ + \fi + \Lit@} +"slip +\def\Lit@{\setbox\litbox@=\hbox\bgroup\litdefs@ + \hskip\litindent} +"slip +\newcount\littab@ +\littab@=8 +\def\littab#1{\littab@=#1\relax} +"slip +{\catcode`\^^I=\active\gdef\letTAB@{\let^^I=\TAB@}} +"slip +\def\TAB@{\egroup + \dimen@=\wd\litbox@ + \advance\dimen@ by -\litindent + \setbox0=\hbox{\tt0}% + \dimen@ii=\littab@\wd0 + \divide\dimen@ by \dimen@ii + \multiply\dimen@ by \dimen@ii + \advance\dimen@ by \littab@\wd0 + \advance\dimen@ by \litindent + \setbox\litbox@=\hbox\bgroup\litdefs@ + \hbox to\dimen@{\unhbox\litbox@\hfil}} +** + +We want to +allow the possibility that no literal backslash has been chosen. For this +purpose, we will first +** +\let\litbs@=\relax +** +and then have *\litdelimiter#1* redefine *\litbs@*, so that we can +insert *\litbs@* within our definitions whether or not a literal backslash +has been chosen. + +*\litdelimiter#1* +must define *\litbs@* so that it +first sets the category code of *#1* to ~*0* +For this we can use +** +\edef\litbs@{\catcode`\string#1=0 ... +** +In this *\edef*, the only thing that gets expanded is the *\string#1*. Since +this gives us a character *C* of type~*12*, +** +\catcode`C=0 +** +without the usual *\* after the *`* is quite legitimate; that's fortunate, +since +** +\catcode`\#1=0 +** +would be totally misinterpreted as +\setbox0\hbox{(*35* is the category code of *#*)} +** +\catcode 351=0 "box0 +** + +\pagebreak + +When we say *\litdelimiter""* we also want *\litbs@* to save away the +definition +** +\def\""{\char`\string""} +** +in *\litbs@@*, +and similarly for any other +argument that may be +used with\linebreak *\litdelimiter*. Here we will need our +old *\expandafter\noexpand* trick (pages~\ref{EXNE} and~\ref{EXNE2}): +\C** +\let\litbs@=\relax +\let\litbs@@=\relax +"slip +\def\litbackslash#1{% + \edef\litbs@{% + \catcode`\string#1=0 + \def\noexpand\litbs@@{\def\expandafter\noexpand + \csname\string#1\endcsname{\char`\string#1}}}% + }% +** + +*\litcodes* can now be defined by +\C** +\def\litcodes@{\catcode`\\=12 + \catcode`\{=12 \catcode`\}=12 + \catcode`\$=12 \catcode`\&=12 + \catcode`\#=12 + \catcode`\^=12 \catcode`\_=12 + \catcode`\@=12 \catcode`\~=12 \catcode`\""=12 + \catcode`\;=12 \catcode`\:=12 + \catcode`\!=12 \catcode`\?=12 + \catcode`\%=12 + \litbs@\catcode`\`=\active\obeyspaces\defspace@} +** +Notice that we need the *\catcode`\""=12* since *""* is normally active in +\lamstex@. The *\litbs@* is placed after all the other *\catcode*'s, since +it may effect a further category code change (e.g., the category +code of *""* may then be changed to~*0*). + +\pagebreak + +The extra *\catcode*'s for *;* and *:* and *!* and *?* are inserted +just in case any of these have been made active for French styles (compare +~\Sref{ALF}). + +\medskip + +Now comes a tricky part. *\litdelimiter#1* will define *\Lit#1*, and +part of this definition will be to make *#1* active and then properly +define it. So we want a construction, *\activate@#1*, which will +define *#1* properly when it is active. But putting +** +\def#1{...} +** +in our definition won't work, since the *#1* will be read in before *#1* +actually is active! So we will resort to the *\lowercase* trick. We first +use +** +\lccode`\~=`#1 +** +to make the *\lccode* of the {\it active\/} character~ *~* be~ *#1* (only an +ordinary character is allowed for the literal delimiter, so the *`#1* is +fine). This means that when ~*~* appears within a *\lowercase* it will be +turned into an {\it active\/}~*#1*. + +So then we can do something like +** +\lowercase{% + \gdef\defdelimiter@{\def~{...}} +} +** +so that *\defdelimiter@* will define our delimiter~ *#1* properly once it is +active. We will need a similar, but different, + definition for the redefinition of~*#1* for +*\Litbox*, so we will let *\activate@* have two arguments---the first, +which will always be either *0* or *1*, determining which value the +global scratch token *\Next@* (see page~\ref{GNXT}) +will be given: +\C** +\def\activate@#1#2{{\lccode`\~=`#2% + \lowercase{% +"2 + \if0#1% +"2 + \gdef\Next@{\def~{\egroup\endgroup + \bigskip\vskip-\parskip +"2 + \def\next@{\noindent@@\futurelet\next\pretendspace@}% + \FNSS@\next@}}% +"2 + \else + \gdef\Next@{\def~{\egroup\egroup\endgroup}}% + \fi + }% +}} +** + +Another thing *\litdelimiter#1* will do is to set *\litdelim@* to be +the character code for ~*#1*: +** +\edef\litdelim@{\char`#1} +** +since this will be used by *\litdefs@*: +\C** +\def\litdefs@{\let\0=\empty\def\1{\litdelim@}% + \def\ {\char32 }\litbs@@} +** +Remember that *\litbs@@* is either *\relax* or the proper definition of *\""* +if *\litdelimiter""* has been used, etc. + +Finally, *\litdelimiter#1* then defines *\lit#1*, *\Lit#1* and +the construction +*\Litbox##1=#1*. +The definitions are just those in the previous sections, except that +*\Lit#1* will use +** +\catcode`#1=\active \activate@0#1\Next@ +** +to get the literal delimiter ~*#1* active, and give it the proper definition, +while *\Litbox##1=#1* will use +** +\catcode`#1=\active \activate@1#1\Next@ +** +to get the proper definition for that case: +\C** +\def\litdelimiter#1{% + \edef\litdelim@{\char`#1}% +"2 + \def\lit#1{\leavevmode\begingroup\litcodes@\litdefs@ + \tt\hyphenchar\tentt=-1 \lit@}% + \def\lit@##1#1{##1\endgroup\null}% +"2 + \def\Lit#1{\ifhmode$$abovedisplayskip=\bigskipamount + \abovedisplayshortskip=\bigskipamount + \belowdisplayskip=0pt \belowdisplayshortskip=0pt + \postdisplaypenalty=1000 + $$\vskip-\baselineskip\else\bigskip\fi +"2 + \begingroup\litlines@=0 + \catcode`#1=\active \activate@0#1\Next@ +"2 + \def\displaybreak{\egroup\break\litlines@=0 \Lit@}% +"2 + \def\allowdisplaybreak{\egroup\allowbreak\litlines@=0 + \Lit@}% +"2 + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@} +"2 + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\Lit@}% +"2 + \def\Litbox##1=#1{\begingroup + \ifodd##1\relax\aftergroup\global\fi + \aftegroup\setbox\aftergroup##1\aftergroup\box + \aftergroup\Litbox@ + \def\allowdisplaybreak{\egroup\allowbreak + \litlines@=0 \Lit@}% +"2 + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@}% + \catcode`#1=\active \activate@1#1\Next@ +"2 + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\global\setbox\Litbox@ + =\vbox\bgroup\litindent=0pt \litlines@=0 \Lit@}% + } +** + + + + + +\sectiong{Nicer syntax\label{NICERSYN}} +Long before I wrote literal mode for \lamstex@, I had +my own literal mode, based upon making *"1* permanently active, with +** +"1 ... "1 +** +giving in-line literal mode, and +** +"1"1 + . . . + . . . +"1"1 +** +giving displayed literal mode. Thus, *"1* worked quite analogously to *$*, +except that it gave literal mode instead of math mode. + +Based on the constructions of +the previous section, we might +implement this approach as follows: +\setbox0\hbox{\} +\setbox1\hbox{\} +** +\catcode`\"1=\active +\def"1{\futurelet\next\star@} +\def\star@{\ifx\next"1\expandafter\star@@\else + \expandafter\star@@@\fi} +\def\star@@@{"copy0} +\def\star@@"1{"copy1} +** +except that *\star@@* should then (temporarily) redefine *"1* as +** +\def"1"1{\egroup\endgroup ... } +** + +Actually, there is a subtle bug here:\pagelabel{SUBTLEBUG} + The *\futurelet\next* causes +\tex\ to read the token after the *"1*, and since this has been done +{\it before\/} the *\litcodes@*, this next token will have the wrong +category code permanently imprinted on it. +Consequently, we have to start with +** +\catcode`\"1=\active +\def"1{\begingroup\litcodes@\futurelet\next\star@} +** +to get things right. + + +Also, the syntax for *\Litbox* should be changed correspondingly, to +\setbox0\hbox{\it n} +** +\Litbox"box0="1"1 + . . . +"1"1 +** + + + +\medskip + +I found this arrangement so much more pleasant than the *\lit* and *\Lit* +syntax (even after I had abbreviated *\lit* to *\l* and *\Lit* to +*\L*) than I have used it throughout this manual. + +\medskip + +Making *"1* active does necessitate some small changes in other parts of +\lamstex@. First of all, I changed the *plain* definition of *\ast* to +** +\def\ast{\string"1} +** +so that *\ast* just gives the category~*12* *"1*, and can thus +be used both in text +and in math mode (giving the symbol \ast\ in text, but $\ast$ in math). + +Then I had to examine all the places where *"1* already appears in +*lamstex.tex*. +\list\item +Its appearance in the definition of *\fnsymbol* requires +no change, since the *"1* appearing there is a type~*12*~*"1*. +\item +However, the definition of *\starparts@* needs to be restated, after +*"1* has been made active, + because it uses a +*"1* as part of the syntax for the subsidiary control sequence *\next@*. +\item +Similarly, the definition of *\starparts@@* uses *"1* as part of its syntax, +so it needs to be restated. +\item +And the same was true of *\iabbrev*. Moreover, in this case, + the *"1* in the replacement text +needs to be replaced with *\noexpand"1*. +\endlist + +There are also a few definitions for mathematics where *"1* appears. +\list\item +The first is in the definition of *\keybin@* +(section~\Sref{ALF}). Since *\ast* would now be used instead of *"1* in a +math formula, in the definition of *\keybin@* +the +** +\ifx\next"1 +** +clause needs to be replaced with +** +\ifx\next\ast +** +\item +It also appears in *\boldkey*. Although *\boldkey* is meant to be used +with symbols on the keyboard, rather than control sequences, it would probably +be reasonable to +change the clause +** +\ifx#1"1\mathcharii@203 \else +** +to +** +\ifx#1\ast\mathcharii@203 \else +** +and agree that *\boldkey* can also be used with *\ast*. +\endlist + +\medskip + +\litindent=0pt + +I would have loved to use this nicer syntax no matter what delimiter the user +chooses, but it seemed utterly hopeless to arrange this. Nevertheless, +to encourage people, here +in its entirety is the additional code that makes + *"1* and *""* the +literal delimiter and escape character with this nicer syntax. With almost +no modifications, + it should function for other pairs, although one must then look +carefully through all the \lamstex\ macros to see what modifications may be +needed because of the fact that another character has been made active. +It is doubly easier than the code of the previous section, + not only because +we are dealing with a specific choice of literal delimiter and backslash, but +also because the literal delimiter is active to begin with. Nevertheless, +the subtle bug mentioned on page~\ref{SUBTLEBUG} introduces the possibility +for an even yet more subtle bug, so there is an additional detail that +is discussed at length starting on page~\ref{DISCUSSB}. + + +** +\catcode`\"1=\active + +"2 +\def\ast{\string"1} % can be used both in text and in math + +"2 +\def\iabbrev"1#1#2{\ifindexing@\toks@{#2}% + \immediate\write\ndx@ + {\noexpand\abbrev\noexpand"1\noexpand#1{\the\toks@}}\fi} + +"2 +\def"1{\begingroup\litcodes@\futurelet\next\star@} + +"2 +\def\litcodes@{\catcode`\\=12 + \catcode`\{=12 \catcode`\}=12 + \catcode`\$=12 \catcode`\&=12 + \catcode`\#=12 + \catcode`\^=12 \catcode`\_=12 + \catcode`\@=12 \catcode`\~=12 + \catcode`\%=12 + \catcode`\`=\active \catcode`\""=0 \obeyspaces\defspace@} + +"2 +\def\star@{\ifx\next"1\expandafter\star@@\else\expandafter\star@@@\fi} + +"2 +%%% Code for "1..."1 + +\def\star@@@{\leavevmode\litdefs@\tt\hyphenchar\tentt=-1 \star@@@@}% + +"2 +\def\star@@@@#1"1{#1\endgroup} + +"2 +\def\litdefs@{\let\0=\empty\def\1{\char42 }\def\""{\char34 }\def\ {\char32 }} + +"2 +%%% Code for "1"1 ... "1"1 + +\def\newstar@{\def"1"1{\egroup\endgroup + \bigskip\vskip-\parskip +"2 + \def\next@{\noindent@@\futurelet\next\pretendspace@}% + \FNSS@\next@}} + +"2 +\def\star@@"1{"9\endgroup"9\ifhmode$$\abovedisplayskip=\bigskipamount + \abovedisplayshortskip=\bigskipamount + \belowdisplayskip=0pt \belowdisplayshortskip=0pt + \postdisplaypenalty=10000 + $$\vskip-\baselineskip\else\bigskip\fi + "9\begingroup\litcodes@"9 + \litlines@=0 + \newstar@ + \def\displaybreak{\egroup\break\litlines@=0 \Lit@}% + \def\allowdisplaybreak{\egroup\allowbreak\litlines@=0 \Lit@}% + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@}% + \tt\catcode`\^^I=\active\letTAB@\obeylines\letM@\Lit@} + +"2 +\def\boxstar@{\def"1"1{\egroup\egroup\endgroup}} + +"2 +\def\Litbox#1="1"1{\begingroup + \ifodd#1\relax\aftergroup\global\fi + \aftergroup\setbox + \aftergroup#1\aftergroup\box\aftergroup\Litbox@ + \boxstar@ + \def\allowdisplaybreak{\egroup\allowbreak\litlines@=0 \Lit@}% + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@}% + \tt\litcodes@\catcode`\^^I=\active\letTAB@\obeylines\letM@% + \global\setbox\Litbox@=\vbox\bgroup\litindent=0pt \litlines@=0 \Lit@} + +\catcode`\@=\active +** + +\newpage + +\andsmall! +The boxed \pagelabel{DISCUSSB} +additions to the definition of *\star@@* are needed because of +a strange \tex\ ``feature''. + +Suppose we type +** +\hangafter-2 \hangindent=20pt +Here are several ... +lines of text. +\vskip1in +Here are several ... +lines of text. + +Here are several ... +lines of text. +** +Then the first paragraph, implicitly ended by the *\vskip1in*, + will have hanging indentation of 20~points for the first two lines +(like these small print notes), +while the next two paragraphs will be treated normally. But now suppose +we type +** +\hangafter-2 \hangindent=20pt +Here are several ... +lines of text. +{\vskip1in} +Here are several ... +lines of text. + +Here are several ... +lines of text. +** +Then the second paragraph will also having hanging indentation for the +first two lines!! + Reason: +The *\vskip1in*, implicitly ending the first paragraph, + causes \tex\ to restore *\hangafter* and +*\hangindent* to their default values, +as with any other locally defined \tex\ parameters. +\footnote{{\it The \tex book}, page~103, + states that ``\tex\ automatically restores +[the values of *\hangindent* and *\hangafter*] at the end of every paragraph, +and (by local definitions) whenever it enters internal vertical mode. For +example, hanging indentation that might be present outside of a *\vbox* +construction won't occur inside that vbox, unless you ask for it inside.'' +I would take that to mean that the restoration of values is done globally +at other times (i.e., when ending a paragraph), but apparently that is not +the case.} + So, after the *}* that follows the +*\vskip1in*, the values of *\hangafter* and +*\hangindent* {\it are still\/}~*-2* and ~*20pt*, respectively!! + + + +\andsmall! +If our definition of *\star@@* didn't have the *\endgroup* before the +** +\ifhmode$$ . . . $$ +\vskip-\baselineskip\else\bigskip\fi +** +then something like +** +\hangafter-2 \hangindent=20pt +Here are several ... +lines of text. +"1"1 + . . . +"1"1 +** +would entail a *\vskip* within a group, and thus give rise to this problem: +text following the closing *"1"1*, which is really a new paragraph, would +continue to have the same hanging indentation. +Once we are safely past that *\vskip*, we reinsert the +** +\begingroup\litcodes@ +** +that we initially had. + +\andsmallsmall As if that weren't confusing enough, it has to be admitted that +this extra code really isn't needed, after all, because *\newstar@* +defines *"1"1* in terms of *\noindent@@*, so that the closing *"1"1* +essentially contributes a +** +\endgroup +\bigskip\vskip-\parskip +\noindent@@ +** +and thus essentially +** +\endgroup +\bigskip\vskip-\parskip +\par +\noindent@ +** +Now the *\par* causes the values of *\hangafter* and *\hangindent* to be +restored to their default values, outside the group ended by the *\endgroup* +(but *\noindent@* alone doesn't end a paragraph---it merely starts an +unindented paragraph in vertical mode, and has no effect in horizontal mode). + + But there's obviously no point tempting +fate by relying on *\noindent@@* always being used instead of *\noindent@*. + +\endsmall + +\restorelitindent + +\chapterg Literal mode in heading levels\endchapterg +As mentioned in Chapter~\ref{foot}, our definitions +allow literal mode to work within +*\footnote*'s. +It might seem that it should be just as easy to allow literal mode +constructions within heading levels, but here the situation is much +more complex. + +Remember that something like +** +\hl1{Extra \lit"1}"1 errors} +** +must not only typeset `Extra *}* errors', it must also send +** +Extra \lit"1}"1 errors +** +off to the *.toc* file, and it's not very clear how we are going to get +these tokens, with unbalanced braces, stored inside a control sequence! +\footnote{If we are willing to process the argument a +token at a time, appropriately changing category codes each time we hit +a *\lit* token, then it can be done (although we might have problems if the +user has substituted some other control sequence for *\lit*). But it wouldn't +be pleasant: since +we can't put individual, unbalanced, braces into a token list, each time we +hit a (non-literal-mode) *{* we would have to record this fact, and then +add the *{* back in + when the matching *}* is discovered, i.e., we would practically +have to rewrite \tex's scanner in \tex\ macros.} +Moreover, a *\footnote*, no matter how formatted, usually involves an +*\insert\footins{...}*, so a style file designer who wants to change the +appearance of a *\footnote* probably won't to have +to worry about the trickery involved in allowing category changes. But it +seems much less reasonable to commit heading levels to something like +** +\global\setbox1=\vbox{...} +** +since heading levels for other style files might have to be handled quite +differently. + + +Of course, in the great majority of cases, even when literal mode is used, +it won't be needed in +header levels. And +even when literal mode material does occur in header levels, usually only +small snatches are needed, which can be handled quite easily with special +definitions. For example, for this manual, where + control sequences appear quite often in heading levels, I defined +** +\def\CS#1{{\tt\char'134 #1}} +** +so that the next section could be typed as +** +\section{Literal mode in \CS{HL} and \CS{hl}} +** +With a few definitions for the backslash~ *\* and the curly braces +*{* and *}*, virtually any literal mode material can be included in +heading levels. + +For this reason, +*lamstex.tex* does not directly +address the problem of literal mode in heading levels. + However, there is a subsidiary file, +*lithl.tex*, which adds new definitions that allow literal mode to be +incorporated, albeit somewhat +indirectly, within heading levels. + +\section{Literal mode in \CS{HL} and \CS{hl}} +If the file *lithl.tex* is *\input*, + before a *\litdelimiter* and *\litbackslash* +are declared, then *\lit"1..."1* will generally +act as before, but two special extensions +will be introduced: +\list +\item On the one hand, we can type +\setbox0\hbox{\it n\,} +** +\lit","box0"1..."1 +** +for $\hbox{\it n}=\hbox{*0*}, \dots, \hbox{*9*}$. This will not typeset +*...* in literal mode, but simply store the corresponding literal mode +tokens in a special storage space, one for each of *0*, \dots, *9*. +\item On the other hand, the combination +\setbox0\hbox{\it n} +** +\lit","box0 +** +(where the next symbol is {\it not\/} a *"1*) will simply give a copy of +whatever is stored in storage space {\it n}. +\endlist + +So, for example, the current section could be typed as +** +\lit0"1\HL"1 +\lit1"1\hl"1 +\section{Literal mode in \lit0 and \lit1} +** + + +*lithl.tex* creates new boxes +** +\expandafter\newbox\csname lit@0\endcsname +\expandafter\newbox\csname lit@1\endcsname + . . . +** +for the storage locations, and makes +*\lit* a control sequence with an argument, +** +\lit#1 +** +If *"1* is going to be the literal delimiter, then when the argument +*#1* is *"1* +we use *\lit@@@*, which is essentially the old *\lit"1*, but if *#1* +is not *"1* (and thus presumably one of *0*, \dots, *9*), we set +** +\count@=#1 +** +and then use +** +\futurelet\next\lit@@ +** + +The *\futurelet* is needed + to see whether the next character is a *"1* or not. +If it isn't (so that we have something like `*\lit0 and*'), then +we simply use +** +\unhcopy\csname lit@\number\count@\endcsname\null +** +(the *\null* is added for the same reason that is was added to the +original definition of *\lit@* [page~\ref{LITN}]). +But if we now have a *"1*, so that we are in the case +\setbox0\hbox{\,\it n\,} +** +\lit"box0"1..."1 +** +we use the routine *\lit@@@@*. + +We might define *\lit@@@@* by +** +\def\lit@@@@"1{\prevanish@\begingroup + \litcodes@\litdefs@\lit@@@@@} +"slip +\def\lit@@@@@#1"1{\toks@={#1} + \global\expandafter\setbox + \csname lit@\number\count@\endcsname + =\hbox{\tt\the\toks@} + \endgroup\postvanish@} +** +with +*\prevanish@* and *\postvanish@* added to + make constructions like *\lit*\,{\it n\,}*"1..."1* + invisible, just in case they get used in a paragraph. + +With such definitions, +** +\lit0"1\HL"1 +\lit1"1\hl"11 +\section{Literal mode in \lit0 and \lit1} +** +will indeed produce the current section title. On the other hand, if +we are making a *.toc* file, then this section will simply appear as +\Evaluate\chapter\edef\chap{\number\Value} +\Evaluate\section\edef\sec{\number\Value} +** +\section{"chap."sec} + {Literal mode in \lit0 and \lit1} +** +so we will also want to have +** +\lit0"1\HL"1 +\lit1"1\hl"1 +** +written to the *.toc* file first. + +This might seem fairly straightforward (after all the trickery to which we've +become accustomed), +** +\def\lit@@@@@#1"1{\toks@={#1} + \iftoc@ + \edef\next@{\write\toc@{\noexpand\noexpand + \noexpand\lit\number\count@"1\the\toks@"1}\next@ + \fi + . . . +** +but, alas, it can fail in a subtle way. + + Suppose that we wanted a +heading like +\bigskip +\hbox to\hsize{\hfil{\bf1.\enspace}Comparing *\" * and *\space*\hfil} +\medskip +\noindent and therefore typed +** +\lit0"1\"" "1 +\lit1"1\space"1 +\HL1 Comparing \lit0 and \lit1\endHL +** +Then the first line would cause the *.toc* file to contain +** +\lit0 "1\\ "1 +** +Reason: When we have dutifully established *\litcodes@* and *\litdefs@* before +exercising *\lit@@@@@*, +the token list *\toks@* contains two tokens: the first token is a +type~*12*~*\*, and the second token is `control-space', i.e., the control +sequence whose name is `\hbox{*"" *}' when + *""* is the escape character, and `\hbox{*\ *}' when +*\* is the escape character, etc. When \tex\ goes to print that control +sequence in the *.toc* file, it will simply print it as `\hbox{*\ *}'. + To put it another way, the tokens `\hbox{*\\ *}' that get written +really consist of a +type~*12*~*\* followed by a type~*0*~*\* followed by a space, but once the +tokens are written, the category codes become irrelevant. + +To get around this problem, we use the following byzantine strategy. After +using *\litcodes@* to change the category codes, we add +** +\catcode`\""=12 +** +so that *""* is just an ordinary character. Then *\toks@* will be just the +ones that we want to write + to the *.toc* file. The problem, of course, is that +they are no longer the tokens that we want to put + in the *\hbox*: we really have +to read in the *"1..."1* material once again, this time {\it without\/} +making the special change for *""*. Although we cannot get \tex\ to back~ +up and read the argument again, +nevertheless we can reread the argument, by first {\it writing\/} the +token list *\toks@* to a temporary file, and then reading it in again with +the proper codes! +** +\newwrite\tempwrite@ +\newread\tempread@ +"slip +\def\lit@@@@"1{\prevanish@\begingroup\litcodes@ + \catcode`\""=12 \lit@@@@@} +"slip +\def\lit@@@@@@#1"1{% + \toks@={#1}% +"2 + \iftoc + \edef\next@{\write\toc@{\noexpand\noexpand + \noexpand\lit\number\count@"1\the\toks@"1}\next@ + \fi +"2 + \immediate\openout\tempwrite@=\jobname.tmp + \immediate\write\tempwrite@{\the\toks@} + \immediate\closeout\tempwrite@ +"2 + \catcode`\""=0 \litdefs@ +"2 + \immediate\openin\tempread@=\jobname.tmp + \read\tempread@ to \next@ + \immediate\closein\tempread@ +"2 + \global\expandafter + \setbox\csname lit@\number\count@\endcsname + =\hbox{\tt\next@} +"2 + \endgroup + \postvanish@} +** + +Unfortunately, that doesn't quite work either, because +there is no way that *\next@* can reflect the exact number of spaces that +occurred at the end of the *"1..."1* sequence that we wrote + to *\tempwrite*, since +spaces at the end of a line are always stripped off by \tex\ as it reads. +So yet another fillip has to be added: We will always add a *"1* +at the end of the sequence (this *"1* can't occur within the sequence, +although *""1* can appear to indicate this character), and then +we will strip off the *"1* and everything following (presumably just +the space inserted by the *^^M* at the end of the line) from *\next@*: +** +\def\lit@@@@@#1"1{% + \toks@={#1}% + \iftoc + \edef\next@{\write\toc@{\noexpand\noexpand + \noexpand\lit\number\count@"1\the\toks@"1}\next@ + \fi +"2 + \immediate\openout\tempwrite@=\jobname.tmp + \immediate\write\tempwrite@{\the\toks@"9"1"9}% + \immediate\closeout\tempwrite@ +"2 + \catcode`\""=0 \litdefs@ + \immediate\openin\tempread@=\jobname.tmp + \read\tempread@ to \next@ + \immediate\closein\tempread@ +"2 + "9\def\nextii@##1"1##2\nextii@{\def\next@{##1}}"9% + "9\expandafter\nextii@\next@\nextii@"9 +"2 +"2 + \global\expandafter + \setbox\csname lit@\number\count@\endcsname + =\hbox{\tt\next@} +"2 + \endgroup + \postvanish@} +** + + + +\section{The general definitions\label{GENDEFS}} +The previous section indicated definitions to be used when *"1* is the +literal delimiter, and *""* is the literal backslash. Now we will give the +code in general. + +The file *lithl.tex* begins, like *lamstex.tex* itself, with +\CC** +\catcode`\@=11 +** +As illustrated here, +we will always +use double horizontal lines for code that is in subsidiary files, rather +than in *lamstex.tex* itself. + + +Since we are going to use *\new...* constructions we then declare +(compare page~\ref{NEWALLOC}) +\CC** +\let\alloc@=\alloc@@ +** + +First we declare new boxes, +\CC** +\expandafter\newbox\csname lit@0\endcsname + . . . +\expandafter\newbox\csname lit@9\endcsname +** +and the input and output streams for the *.tmp* file, +\CC** +\newwrite\tempwrite@ +\newread\tempread@ +** + +Since we are going to be changing the category code of the literal backslash, +if it has been chosen, *\litbackslash* will have to store extra information +that allows us to do this. We declare a counter, initially with value~*-1*, +\CC** +\newcount\litbackslashno@ +\litbackslashno@=-1 +** +and we change the definition of *\litbackslash#1* so that it sets +the value of\linebreak +*\litbackslashno@* to the character code of~*#1*: +\CC** +\def\litbackslash#1{% + \edef\next@{\litbackslashno@=`\string#1}\next@ + \edef\litbs@{% + \catcode`\string#1=0 + \def\noexpand\litbs@@{\def\expandafter\noexpand + \csname\string#1\endcsname{\char`\string#1}}}} +** + +Then we add the necessary definitions of *\lit@* et~al\. to the definition of +*\litdelimiter*, with the category code of character *\litbackslashno@* +changed back to~*0* if *\litbackslashno@* isn't~*-1* (if it is, we haven't +declared an escape character for literal mode, so we don't have to worry +about things like *\"" *): +\CC** +\def\litdelimiter#1{% + \edef\litdelim@{\char`#1}% +"2 + \def\lit##1{\ifx##1#1\let\next@=\lit@\else + \count@=##1\relax\def\next@{\futurelet\next@\lit@@}\fi + \next@}% +"2 + \def\lit@{\leavevmode\begingroup\litcodes@\litdefs@ + \tt\hyphenchar\tentt=-1 \lit@@@}% +"2 + \def\lit@@@##1#1{##1\endgroup\null}% + \def\lit@@{\ifx\next#1\let\next@=\lit@@@@\else + \def\next@{\unhcopy\csname lit@\number\count@\endcsname + \null}\fi + \next@}% +"2 + \def\lit@@@@#1{\prevanish@ + \begingroup\litcodes@\ifnum\litbackslashno@=-1 \else + \catcode\litbackslashno@=12 \fi\lit@@@@@}% +"2 + \def\lit@@@@@##1#1{\toks@={##1}% + \iftoc@ + \edef\next@{\write\toc@{\noexpand\noexpand + \noexpand\lit\number\count@#1\the\toks@#1}}\next@ + \fi +"2 + \ifnum\litbackslashno@=-1 \def\next@{\the\toks@}\else + \immediate\openout\tempwrite@=\jobname.tmp + \immediate\write\tempwrite@{\the\toks@#1}% + \immediate\closeout\tempwrite@ +"2 + \catcode\litbackslashno@=0 \litdefs@ + \immediate\openin\tempread@=\jobname.tmp + \read\tempread@ to\next@ + \immediate\closein\tempread@ +"2 + \def\nextiii@####1#1####2\nextiii@{\def\next@{####1}}% + \expandafter\nextiii@\next@\nextiii@ + \fi +"2 + \global\expandafter + \setbox\csname lit@\number\count@\endcsname + =\hbox{\tt\next@}% + \endgroup\postvanish@}% +"2 + \def\Lit#1{$\ifhmode$\abovedisplayskip=\bigskipamount + \abovedisplayshortskip=\bigskipamount + \belowdisplayskip=0pt \belowdisplayshortskip=0pt + \postdisplaypenalty=1000 + $$\vskip-\baselineskip\else\bigskip\fi +"2 + \begingroup\litlines@=0 + \catcode`#1=\active \activate@0#1\Next@ +"2 + \def\displaybreak{\egroup\break\litlines@=0 + \Lit@}% +"2 + \def\allowdisplaybreak{\egroup\allowbreak + \litlines@=0 \Lit@}% +"2 + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@} +"2 + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\Lit@}% +"2 + \def\Litbox##1=#1{\begingroup + \ifodd##1\relax\aftergroup\global\fi + \aftergroup\setbox + \aftergroup##1\aftergroup\box\aftergroup\Litbox@ + \def\allowdisplaybreak{\egroup\allowbreak + \litlines@=0 \Lit@}% +"2 + \def\allowdisplaybreaks{\egroup\allowbreak + \interlitpenalty@=0 \litlines@=0 \Lit@}% + \catcode`#1=\active \activate@1#1\Next@ +"2 + \litcodes@\tt\catcode`\^^I=\active\letTAB@ + \obeylines\letM@\global\setbox\Litbox@=\vbox% + \bgroup\litindent=0pt \litlines@=0 \Lit@}% +} +** +Finally, we reassign *\alloc@* its original definition from *plain* \tex@, +and make *@* active again: +\CC** +\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne + \ch@ck#1#4#2\allocationnumber=\count1#1 + \global#3#5=\allocationnumber + \wlog{\string#5=\string#2\the\allocationnumber}} +\catcode`\@=\active +** + +\setbox0\hbox{\,\it n\,} +\small +If the alternate syntax of section~\Sref{NICERSYN} is used, something +different would be needed. For example, we might create *\SL* and *\UL* +(store literal mode material and use literal mode material), so +that *\SL"box0"1..."1* +stores the material in location {\it n}, while +\setbox0\hbox{\,\it n}% +*\UL"box0* +uses it. With a little work, we could even arrange for +\setbox0\hbox{\,\it n}% +*"1"box0..."1* +to work like *\SL*\,{\it n}*"1..."1*, so that only *\UL* would be needed. +(For the case of literal mode material that happened to begin with a digit, +like +*0...*, +we would then have to use +*"1""00..."1* +to print it.) +\endsmall + + + + +\chapter Title, author, etc., in the default style\endchapter +There is, happily, not much interesting about *\title*, +*\author*, *\affil*, and *\date* in the default style, except that, +for the sake of economy, we carefully arrange to avoid introducing any flags +to tell us which of these constructions have been used. + + +We allow the possibility of an empty title, so we declare +\C** +\newbox\titlebox@ +\setbox\titlebox@=\vbox{} +* +and we +\C** +\righadd@\title\to\overlonglist@ +** +since we want *\overlong\title* to work. Then +*\title"allowbreak..."allowbreak\endtitle* will just set +*\box\titlebox@*. This box won't actually be printed until the *\maketitle* +appears; the main purpose of this sort of arrangement is to allow +*\title*, +*\author*, *\affil*, and *\date* to occur in any order before the +*\maketitle*, so that the user doesn't need to know in which order these +various elements have to be specified. + +The *\title...\endtitle* instructions for setting *\box\titlebox@* are +similar to those used for setting the *\vbox* in `*\HL@1*' (page~\ref{HLONE}), +except that we might as well follow other \amstex\ constructions and + allow *\title* and *\endtitle* to +function separately, instead of having *\endtitle* be part of the syntax for +*\title*: +\footnote{There was really no point doing that for *\HL...\endHL*, +since something like *\chapter"allowbreak..."allowbreak\endchapter* would +have to be defined in terms of *\HL...\endHL* anyway.} +\C** +\def\title{\begingroup\Let@ + \global\setbox\titlebox@=\vbox\bgroup\tabskip\hss@ + \halign to\hsize\bgroup + \bf\hfil\ignorespaces##\unskip\hil\cr} +"slip +\def\endtitle{\crcr\egroup\egroup\endgroup + \overlong@false} +** + +Although *\maketitle* is going to print *\box\titlebox@* even if it is empty +(the idea is to leave some space for a hand-written title, or perhaps a title +with some weird special symbols, etc.), no author information is going to be +printed unless *\author"allowbreak..."allowbreak\endauthor* explicitly +appears. + +The definition of *\author* is exactly analogous to the definition of +*\title*, +\C** +\newbox\authorbox@ +\rightadd@\author\to\overlonglist@ +\def\author{\begingroup\Let@ + \global\setbox\authorbox@=\vbox\bgroup\tabskip\hss@ + \halign to\hsize\bgroup + \rm\hfil\ignorespaces##\unskip\hfil\cr} +\def\endauthor{\crcr\egroup\egroup\endgroup + \overlong@false} +** +except that initially *\box\authorbox@* will be void; thus, *\maketitle* + will be able +to use the test *\ifvoid\authorbox@* to tell whether *\author* has been +used. *\rm* was added just in case some other font has already been selected, +for some weird reason. + +And *\affil* is exactly analogous: +\C** +\newbox\affilbox@ +\def\affil{\begingroup\Let@ + \global\setbox\affilbox@=\vbox\bgroup\tabskip\hss@ + \halign to\hsize\bgroup + \rm\hfil\ignorespaces##\unskip\hfil\cr}% +\def\endaffil{\crcr\egroup\egroup\endgroup + \overlong@false} +** + +*\date* is a little different, since we don't create a box. Instead, +we define *\date@*, initially set equal to *\relax*: +\C** +\let\date@=\relax +\def\date#1{\gdef\date@{\ignorespaces#1\unskip}} +** +We add the appropriate *\ignorespaces* and +*\unskip* at this stage, since that is +much easier than trying to insert them into +an already defined *\date@* later on. + +The definition of *\today* is taken right from {\it The \tex book} (page~406): +\C** +\def\today{\ifcase\month\or January\or February\or + March\or April\or May\or June\or July\or August\or + September\or October\or November\or December\fi + \space\number\day, \number\year} +** + +And then, finally, *\maketitle* simply puts everything together. +We use +** +\hrule \height0pt \vskip-\topskip +** +to get to the very top of the page, and then +** +\vskip24pt plus12pt minus12pt +\unvbox\titlebox@ +** +to put (stretchable) space before the (possibly empty) title. Then +we add some more space and the author(s), but only if there are some, +** +\ifvoid\authorbox@\else + \vskip12pt plus6pt minus3pt\unvbox\authorbox@ \fi +** + +The affiliation and date are handled similarly, except that the date +is put inside a *\centerline* (with *\rm* explicitly stated). + And then, finally, some extra space is added +before the first material of the document proper: +\C** +\def\maketitle{\hrule \height0pt \vskip-\topskip + \vskip24pt plus12pt minus12pt + \unvbox\titlebox@ + \ifvoid\authorbox@ \else + \vskip12pt plus6pt minus3pt \unvbox\authorbox@ \fi + \ifvoid\affilbox@ \else + \vskip10pt plus5pt minus2pt \unvbox\affilbox@ \fi + \ifx\date@\relax\else + \vskip6pt plus2pt minus1pt \centerline{\rm\date@} \fi + \vskip18pt plus12pt minus6pt} +** + + + + +\chapter The bibliography\label{MAKEBIB}\endchapter +\lamstex's bibliography constructions, an extension of those +originally used in *amsppt.sty*, +are really quite adequate for most bibliography requirements. They show that + various ``fields'' of +information, allowed to appear in any order, can be put together properly by +\tex\ itself, without resorting to an external program like \bibtex@. +Moreover, as explained on page~98 of the +\lamstex~Manual, the bibliographic entries can be labelled, and thus cited +within the text using *\ref*, so that the proper number for a bibliographic +entry is printed automatically (after enough passes). + +Of course, + \bibtex\ also allows bibliographic entries to be selected from + a data base and sorted in any of numerous desired ways. + Moreover, the \bibtex\ approach has the advantage that the final +result (the *.bbl* file) consists of standard (well, almost +standard) \tex\ code, and is thus easily edited and modified. By contrast, it + may be quite +difficult to coerce \lamstex's bibliography macros into performing as +desired, and many special sorts of \tex\ trickery had to be built into the +macros for this purpose. (With either approach, careful proofreading of the +bibliography---rarely attempted by the authors, alas---is +advisable, to check that +special situations have been handled correctly. + +Since many people have already made extensive data bases for \bibtex@, +which they presumably don't want to go to waste, + \lamstex\ now provides an interface with \bibtex@, as explained +in the next chapter. +(Of course, it would be nice if there were a L{\eightrm IB}\kern-1pt + \tex\ program, +working like \bibtex@, but producing a *.bbl* file with \lamstex\ code +instead of \latex\ code.) + +Others may prefer using \lamstex's bibliography macros, however, +especially since they provide features missing from \bibtex@. I have added +all features that the AMS has added to +*amsppt.sty* (though often with modified syntax), + not to mention a few more of my own. All in all, this was a +rather harrowing experience---I now understand the perils of creeping +featureism. I ended up deferring the bibliography macros to the very +end, rightly dreading all the details that would be involved. On the other +hand, when I finally came to writing this chapter, it turned out that +the description of the macros, and the strategy behind them, went rather +smoothly. + +Most important of all, from the point of view of the user or style file +designer, once \lamstex's hidden macros have taken + care of all the messy details, +the final process of printing the information from all the fields, in the +proper order, and with proper punctuation and spacing, is fairly +straightforward, and thus easily modified if some other sort of arrangement +is needed. + + +\section{\CS{cite}} +The *amsppt.sty* has a *\cite* construction, which simply prints its +argument within brackets. When we are interfacing with \bibtex@, +*\cite* will work essentially the same as in \latex@, but we will first give a +default definition. We will still allow *\cite* to producing something like +[Knuth1984, page~123], but the syntax for indicating the additional +information `page~123' will be changed, to +** +\cite(page~123){Knuth1984} +** +This is close to \latex's +** +\cite[page~123]{...} +** +syntax for optional arguments; however the use of the brackets has been +avoided because they represent letters on Scandinavian keyboards. Of course, +any *)*'s in the additional text must be hidden in braces, +\setbox0\hbox{[\bf\dots{} \rm, section 1(a)]} +** +\cite({section 1(a)}){...} "box0 +** + + +There's nothing very surprising about the definition of *\cite*, + which uses standard +techniques: +\C** +\def\cite{% + \def\nextii@(##1)##2{{\rm[}{##2}, {##1\/}{\rm]}}% + \def\nextiii@##1{{\rm[}{##1\/}{\rm]}}% + \def\next@{\ifx\next(\expandafter\nextii@\else + \expandafter\nextiii@\fi}% + \futurelet\next\next@} +** + +\small Note that we always specify *\rm* [ and ]. We put *##1* and *##2* +inside braces, in case a font change instruction is added. (When we +are interfacing with \bibtex@, a font change instruction will only be +allowed in the optional argument *#1* (see page~\ref{OPARGCITE}). +\endsmall + +\catcode`\@=11 +\newif\ifaltcrop@ +\def\topbibcrop@{\hbox{\smash{\dimen@\hsize\ifaltcrop@ + \advance\dimen@13pt\else\advance\dimen@8pt\fi + \hbox to\dimen@{\vrule \height0pt depth5pt width.4pt + \hskip-.4pt\vrule \height.4pt depth0pt width5pt \hfil + \vrule \height.4pt depth0pt width5pt \hskip-.4pt + \vrule \height0pt depth5pt width.4pt}}}} +\def\botbibcrop@{\hbox{\smash{\dimen@\hsize\ifaltcrop@ + \advance\dimen@13pt\else\advance\dimen@8pt\fi + \hbox to\dimen@{\vrule \height5pt depth0pt width.4pt + \hskip-.4pt\vrule \height.4pt depth0pt width5pt\hfil + \vrule \height.4pt depth0pt width5pt \hskip-.4pt + \vrule \height5pt depth0pt width.4pt}}}} +\def\bibcrop@#1{\vbox{\topbibcrop@\vbox{\vskip5pt + \hbox{\ifaltcrop@\hskip5pt\fi + #1\hskip3pt}\vskip3pt}\vskip-\baselineskip\botbibcrop@}} +\def\showbib#1\endbib{\medskip\setbox0\vbox{% + \sfcode`\.=\@m\def\nopunct{\nopunct@true}% + \def\nospace{\nospace@true}% + \def\nakerns@{\null\kern\m@ne sp\kern\@ne sp}% + \def\lkerns@{\null\kern-\tw@ sp\kern\tw@ sp}% + \def\nkerns@{\null\kern-\thr@@ sp\kern\thr@@ sp}\bib#1\endbib}% + \centerline{\bibcrop@{\box0}\ifaltcrop@\hskip5pt\fi}% + \medskip\altcrop@false} +\def\altshowbib{\altcrop@true\showbib} +\catcode`\@=\active + + + +\section{Features of \lamstex's bibliography macros} +The original *amsppt.sty* command *\Refs* is called +** +\makebib +** +in \lamstex@, and this *\makebib* now requires a matching +** +\endmakebib +** +at the end of the entries. With the +** +\makebib + . . . +\endmakebib +** +region, +the general *amsppt.sty* syntax +** +\ref ... \endref +** +has been changed to +** +\bib ... \endbib +** +since *\ref* already has another use in \lamstex@. + +Within *\bib...\endbib* we can use the fields +** +\no \key +\by \bysame +\paper \jour \vol \issue \yr \toappear +\pg \pp +\book \inbook \publ \publaddr +\paperinfo \bookinfo \finalinfo +** +which correspond to those +from the original *amsppt.sty*, with *\pg* and *\pp* replacing *\page* and +*\pages*, since *\page* has another use in \lamstex. + +Some changes have been made in conformity with changes by the AMS@: +\bullist +\item +*\key* now automatically adds brackets, and sets its field in *\bf*. +Thus, *\key C1* gives `[{\bf C1}]', which was previously + typed as *\key \bf C1*. +\item +*\inbook* normally +prints only the book title, not preceded by `in~' [which many people don't +like very much], although, as discussed below, this can be changed. +\item +*\issue* now prints `no. ' before its field, + though I think that's very bad (*\issue* was originally designed +for something like `Special commemorative issue'). +\item +The AMS has also changed\pagelabel{USEFINFO} +*\finalinfo*, so that it is preceded by a comma, rather than a period after +all the previous information. I think that's even worse, and have +kept the old arrangement (see page~\ref{FINFO} for further discussion of this +particular point.) +\endbullist + +As in the AMS's new *amsppt.sty*, there is no longer a *\manyby* to indicate +the start of a sequence of *\bysame*'s. The first reference is simply +typed as *\by*, with *\bysame* used for the subsequent ones. In addition, +*\bysame* now prints a horizontal rule of fixed width, rather than one that +varies with the width of the first instance. (This makes the macros +considerably easier to write, but it's what journals always use anyway, so +there's no point apologizing for the shortcut.) + +*\moreref* has been changed to *\morebib*. As before, something like +** +\bib \no 2 \by L. Auslander +\paper On the Euler characteristic of + compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\paper \rm II +\jour Bull. Amer. Math. Soc. \vol67 \yr1961 \pp 405--406 +\endbib +** +will produce +\showbib +\no 2 +\by L. Auslander +\paper On the Euler characteristic of + compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\paper \rm II +\jour Bull. Amer. Math. Soc. \vol67 \yr1961 \pp 405--406 +\endbib + + +If part II of this paper had appeared in the same journal, but in a different +volume, +** +\bib \no 2 \by L. Auslander +\paper On the Euler characteristic of + compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\paper \rm II +\vol36 \yr1961 \pp 13--15 +\endbib +** +the output would look like +\showbib +\no 2 +\by L. Auslander +\paper On the Euler characteristic of compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\paper \rm II +\vol36 \yr1961 \pp 13--15 +\endbib + + +\noindent*\morebib* remembers that there was a *\jour* before, so it prints +the *\vol*, *\yr*, and *\pp* fields for the second title even though no +*\jour* is given for that title. + +By the way, this example +illustrates one of those +innumerable circumstances where a completely automated system won't give the +optimal results: journal volume numbers in the default style +happen to be printed without commas following the preceding field, which +looks just fine for the {\bf35} following\linebreak + `Comment. Math. Helv.', but not so fine +after the shortened title `II'; in this case we would probably want to change +the input to +** +\paper \rm II, "8COMNO"8 +** +(see also page~\ref{UCOMNO}). + +\medbreak + +This ``remembering'' feature of *\morebib* +is generally quite convenient, but it doesn't +give the desired results in certain other situations. For example, +** +\bib +\no 3 \by Stefan Banach +\paper Sur la d\'ecomposition des ensembles de points + en parties respectivement congruents +\jour Fund. Math. \vol 6 \yr 1925 \pp 244--277 +\morebib +\book \OE uvres +\publ \'Editions Scientifiques de Pologne +\publaddr Warzaw \yr 1967 +\endbib +** +will produce +\showbib +\no 3 \by Stefan Banach +\paper Sur la d\'ecomposition des ensembles de points en parties +respectivement congruents +\jour Fund. Math. \vol 6 \yr 1925 \pp 244--277 +\morebib +\book \OE uvres +\publ \'Editions Scientifiques de Pologne +\publaddr Warzaw \yr 1967 +\endbib +\noindent Here the 1967 got printed first, as if it were the *\yr* for a +*\jour*, because *\morebib* remembered that a *\jour* appeared before. + + +So there is now *\anotherbib*, which clears out such information. If we use +*\anotherbib* instead of *\morebib* we will get the desired result: +\showbib +\no 3\by Stefan Banach +\paper Sur la d\'ecomposition des ensembles de points en parties +respectivement congruents +\jour Fund. Math. \vol 6 \yr 1925 \pp 244--277 +\anotherbib +\book \OE uvres +\publ \'Editions Scientifiques de Pologne +\publaddr Warzaw \yr 1967 +\endbib + + +By the way, the AMS does not seem to have retained this ``remembering'' +feature for *\morebib*. At any rate, the + \amstex~Version 2.0 User's Guide gives an example +like +** +\bib \no 7 +\by P. D. Lax and C. D. Levermore +\paper The small dispersion limit for the KdV equation.~\rm I +\jour Comm. Pure Appl. Math. \vol 36 \yr1983 +\pp 253--290 +\morebib\paper \rm II +\jour Comm. Pure Appl. Math. +\vol 36 \yr 1983 \pp 571--594 +\morebib\paper \rm III +\jour Comm. Pure Appl. Math. +\vol 36 \yr 1983 \pp 809--829 +\endbib +** +to produce +\showbib \no7 +\by P. D. Lax and C. D. Levermore +\paper The small dispersion limit for the KdV equation.~\rm I +\jour Comm. Pure Appl. Math. \vol 36 \yr1983 +\pp 253--290 +\morebib\paper \rm II +\jour Comm. Pure Appl. Math. +\vol 36 \yr 1983 \pp 571--594 +\morebib\paper \rm III +\jour Comm. Pure Appl. Math. +\vol 36 \yr 1983 \pp 809--829 +\endbib +\noindent which is an obvious example of overkill. The listing +\showbib \no 7 +\by P. D. Lax and C. D. Levermore +\paper The small dispersion limit for the KdV equation.~\rm I +\jour Comm. Pure Appl. Math. \vol 36 \yr1983 +\pp 253--290 +\morebib\paper \rm II +\pp 571--594 +\morebib\paper \rm III +\pp 809--829 +\endbib +\noindent would have been preferable by far. + +\bigskip + +There are now four new fields, as added by the AMS@: +\bullist +\item +*\ed* and *\eds* are for one editor, or several editors, respectively, of a +book; the first adds ``ed\.'' after the editor's name, while the +second adds ``eds''; all the information is enclosed in parentheses. +\item + *\lang*, for the original language of a translation, prints its +information, enclosed in parentheses, + at the very end, after the final punctuation for the *\bib* +entry. I have followed the AMS macros in this +regard---*\lang* basically becomes *\finalinfo*---although I don't think +that's +the optimal solution. +\item + *\transl* is for translation information, +preceding the *\jour* or *\book* to which it pertains; thus, an entry with +*\transl* may well have more than one *\jour* or *\book*---in essence, +*\transl* functions something like *\anotherbib*. +\endbullist +\medskip + +\noindent As examples, +** +\bib\no9 \by S. Kripke "8Kripke"8 +\paper Semantical analysis of intuitionistic logic \rm I +\inbook Formal Systems and Recursive Functions +\eds J. Corssely and M. A. E. Dummett +\publ North-Holland \yr1965 \pp92--130 +\endbib +** +produces +\showbib +\no9 \by S. Kripke +\paper Semantical analysis of intuitionistic logic \rm I +\inbook Formal Systems and Recursive Functions +\eds J. Corssely and M. A. E. Dummett +\publ North-Holland \yr1965 \pp92--130 +\endbib +and +** +\bib\no6 \by O. A. Ladyzhenskaya +\book Mathematical problems in the dynamics of a viscous +incompressible fluid \bookinfo 2nd rev. aug. ed. +\publ ``Nauka'' \publaddr Moscow \yr 1970 +\lang Russian +\transl English transl. of 1st ed. +\book The mathematical theory of viscous + incompressible flow +\publ Gordon and Breach \publaddr New York +\yr 1963; rev. 1969 +\endbib +** +produces +\showbib +\no6 \by O. A. Ladyzhenskaya +\book Mathematical problems in the dynamics of a viscous +incompressible fluid \bookinfo 2nd rev. aug. ed. +\publ ``Nauka'' \publaddr Moscow \yr 1970 +\lang Russian +\transl English transl. of 1st ed. +\book The mathematical theory of viscous + incompressible flow +\publ Gordon and Breach \publaddr New York +\yr 1963; rev. 1969 +\endbib + + + +As you can see from these examples, +the default style, in conformity with the AMS's changes, + now prints both paper titles and book titles in italics, +except for book titles produced by *\inbook*. +However, there are new AMS constructions +** +\bookinquotes +\paperinquotes +** +which +have also been added in \lamstex@. Typing +** +\bookinquotes +** +after *\makebib* +will cause all the book entries to be placed in quotes (and in roman type), + and similarly for *\paperinquotes*. + + +\medskip + +*\paperinquotes* and *\bookinquotes* can be used together, but +I personally feel that +one, and only one, of +these commands should always be used, + to distinguish between papers and books. The necessity for +this is well illustrated by +one of the AMS's examples in the User's Guide: +\showbib +\no 4 \by V. I. Arnol$'$d, A. N. Varchenko, and S. M. Guse\u\i n-Zade +\book Singularities of differentiable maps.~\rm I +\publ ``Nauka'' \publaddr Moscow \yr 1982 +\lang Russian +\endbib +\noindent +Until I looked at the input, +** +\bib \no 4 \by V. I. Arnol$'$d, A. N. Varchenko, + and S. M. Guse\u\i n-Zade +\book Singularities of differentiable maps.~\rm I +\publ ``Nauka'' \publaddr Moscow \yr 1982 +\lang Russian +\endbib +** +I didn't know this was a book! (Normally a book would have something +like `Volume~1' in its title.) + +\medskip + +The Kripke example on page~\ref{Kripke} appears on +page~ 263 of the second edition of {\it The Joy of \tex}, but with +** +\inbook in Formal Systems and Recursive Functions +** +to explicitly add `in~' before the book title. Unfortunately, that won't +work very well if *\bookinquotes* has been specified! Instead, I have added +** +\ininbook +** +to add `in~' before all book titles specified by +*\inbook*; if *\bookinquotes* has also +been specified, the quotes will go only +around the book title itself. + +\medskip + +The AMS has extended the use of (the old) *\nofrills* within the +bibliography: *\nofrills* after a field suppresses the punctuation that would +normally occur. The above mentioned example was actually given as +** +\bib +\no9 \by S. Kripke +\paper\nofrills Semantical analysis of + intuitionistic logic \rm I; +\inbook in Formal Systems and Recursive Functions +\eds J. Corssely and M. A. E. Dummett +\publ North-Holland \yr1965 \pp92--130 +\endbib +** +to produce +\showbib +\no9 \by S. Kripke +\nopunct\paper Semantical analysis of intuitionistic logic \rm I; +\inbook in Formal Systems and Recursive Functions +\eds J. Corssely and M. A. E. Dummett +\publ North-Holland \yr1965 \pp92--130 +\endbib + +*\nofrills* has been replaced by *\nopunct* and *\nospace* in \lamstex\ (and +its positioning has been changed), and this usage now extends to bibliography +items also: In \lamstex\ +the above example could be typed as +** +\ininbook +"slip +\bib +\no9 \by S. Kripke +\nopunct\paper Semantical analysis of + intuitionistic logic \rm I; +\inbook Formal Systems and Recursive Functions +\eds J. Corssely and M. A. E. Dummett +\publ North-Holland \yr1965 \pp92--130 +\endbib +** + +Note that on page~\ref{COMNO} we might use +** +\nopunct \paper \rm II, "8UCOMNO"8 +** +if we weren't sure about the treatment of punctuation for the next field. + +\medbreak + +The AMS also allows *\nofrills* to occur before a field name, in order to +suppress punctuation after the {\it previous\/} field. For \lamstex@, where +*\nopunct* and *\nospace* always precede the fields, I have added +** +\noprepunct +\noprespace +** +For example, +to print +\showbib \no 7 +\by P. D. Lax and C. D. Levermore +\paper The small dispersion limit for the KdV equation.~\rm I +\jour Comm. Pure Appl. Math. \vol 36 \yr1983 +\pp 253--290 +\noprepunct\finalinfo (overview) +\morebib\paper \rm II +\pp 571--594 +\morebib\paper \rm III +\pp 809--829 +\endbib +\noindent we can use +** +\bib \no 7 +\by P. D. Lax and C. D. Levermore +"2 +\paper The small dispersion limit for the KdV equation.~\rm I +"2 +\jour Comm. Pure Appl. Math. \vol 36 \yr1983 +"2 +\pp 253--290 +"2 +\noprepunct\finalinfo (overview) +"2 +\morebib\paper \rm II +"2 +\pp 571--594 +"2 +\morebib\paper \rm III +\pp 809--829 +\endbib +** +thereby suppressing the punctuation on the field + immediately preceding the *\finalinfo* (we might not be sure +just which field this is). + +As another example,\pagelabel{FINFO} note that in \lamstex\ the input +** +\bib +\key C \by H. Cartan +\paper Operations dans les construction acycliques +\inbook Seminaire H. Cartan 1954--55 +\bookinfo Expos\'e 6 \publ ENS \publaddr Paris +\finalinfo Reprinted by W. A. Benjamin, New York (1967) +\endbib +** +produces +\altshowbib +\key C \by H. Cartan +\paper Operations dans les construction acycliques +\inbook Seminaire H. Cartan 1954--55 +\bookinfo Expos\'e 6 \publ ENS \publaddr Paris +\finalinfo Reprinted by W. A. Benjamin, New York (1967) +\endbib +\noindent with the information from the +*\finalinfo* field following a period after all the other fields +(see page~\ref{USEFINFO}). To print this in the AMS's manner, +\altshowbib +\key C\by H. Cartan +\paper Operations dans les construction acycliques +\inbook Seminaire H. Cartan 1954--55 +\bookinfo Expos\'e 6 \publ ENS \publaddr Paris +\noprespace\noprepunct\finalinfo + , reprinted by W. A. Benjamin, New York (1967) +\endbib +\noindent we can type +** + . . . +\publ ENS \publaddr Paris +\noprespace\noprepunct\finalinfo , reprinted by + W. A. Benjamin, New York (1967). +\endbib +** + +Notice also +that, once again in conformity with the AMS's changes, + punctuation is supplied automatically after *\finalinfo*, +unless it is preceded by *\nopunct*. + +\medskip + +Finally, it turned out that one more such modifier was needed. When book +or paper titles are printed in quotes, we sometimes want to suppress the +quotation marks. For example, +{\paperinquotes +\showbib +\no2\by L. Auslander +\paper On the Euler characteristic of compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\paper \rm II +\jour Bull. Amer. Math. Soc. \vol67 \yr1961 \pp 405--406 +\endbib +\noindent +looks much better if we suppress the quotations around the II, +\showbib +\no2 +\by L. Auslander +\paper On the Euler characteristic of compact locally affine spaces +\jour Comment. Math. Helv. \vol 35 \yr 1961 \pp25--27 +\morebib +\noquotes\paper \rm II +\jour Bull. Amer. Math. Soc. \vol67 \yr1961 \pp 405--406 +\endbib +\noindent To obtain this, we would type +** +\morebib +\noquotes\paper \rm II + . . . +** + +} + +\section{Storing the fields\label{BASICD}} +One of +the basic problems in the bibliography macros is that we want +to be able to type things like +** + \by ... \paper ... \jour ... +** +instead of +** + \by {...} \paper {...} \jour {...} +** +but we also don't want to force the various elements to be typed in a +particular order, or force all of them to appear. + +The solution to this problem is to have boxes, say *\bybox@*, *\paperbox@*, +*\jourbox@*, \dots, in which to store the information from these various +fields, and to make definitions like +** +\def\by{\unskip\egroup \setbox\bybox@=\hbox\bgroup} +\def\paper{\unskip\egroup \setbox\paperbox@=\hbox\bgroup} +** +The idea is that the *\egroup* matches the *\bgroup* from the previous field, +and then we start storing the current field. (The *\unskip* before the +*\egroup* simply removes any extraneous space at the end of the previous +field; it is convenient to get rid of this space at the very outset, instead +of worrying about it later.) + The definition of +*\bib* will have to start with an extra *\bgroup*, which will be +closed by the *\egroup* of the first field that follows, while *\endbib* will + supply a final *\egroup*, and then take the material in all these +boxes, and suitably arrange them. + +This whole idea works because *\hbox* can be ended by *\egroup*, rather +than an explicit~*}*. +However, several details intrude: + +\Pitem If the user adds one of the + line breaking commands, *\nolinebreak*,\linebreak +*\allowlinebreak*, *\linebreak*, or *\newline* at the end of a field, we +want the corresponding *\penalty* to be inserted {\it after\/} the +punctuation that will follow the field when it is printed, not before. + +Recall (section~\Sref{LBK}) +that the \lamstex\ definitions of *\nolinebreak*,\linebreak + *\allowlinebreak*, and *\linebreak* + have an extra element *\lkerns@* at the end, while + *\newlines* has *\nkerns@*. Originally these +are both *\relax*, but now we will change them, so that they involve very +small kerns like +** +\kern-1sp \kern1sp +** +The presence of such *\kern*'s, presumably not ever explicitly inserted by +the user, will allow us to recognize that such commands were typed, and to +deal +with them suitably (details are presented in section~\Sref{VBOXI}). + +\pitem Some people like to prepare a ``template'' with all possible fields, +** +\bib +\no +\key +\paper + . . . +** +and then fill in only the necessary fields. So we have to deal with the +possibility that certain fields are empty.\pagelabel{EFIELD} + +\pitem Finally, there is the phenomenon reported by Michael Downes +in TUG{\ninerm BOAT}, Volume~11, No.~4. Normally when \tex\ is setting +text it inserts a discretionary break after hyphens, en- and em-dashes, +and explicitly typed discretionary hyphens~*\-*. But these are omitted +when setting an *\hbox* +(in restricted horizontal mode). If the *\hbox* is later *\unhbox*'ed, and +made part of a paragraph, \tex\ will attempt hyphenation, as usual, if it +can't set the paragraph without hyphenation. But when this second attempt is +made, hyphenations are inserted only by the hyphenation algorithm---possible +break points after hyphens, +dashes and discretionary hyphens are not added at this +stage. Since the possible break points after hyphens, dashes and +discretionary hyphens weren't added in the original *\hbox*, they have thus +been +lost forever. So, for example, a compound word like ``Nebraska--Lincoln'' +will not be able to break properly at the end of a line. + +The solution to this problem will be to set everything as a *\noindent*'ed +paragraph within a *\vbox* +with *\hsize=\maxdimen*, and then take the *\vbox* apart. +So we will be using definitions like +\Litbox0=** +\def\paper{\unskip\egroup + \setbox\paperbox@=\vbox\bgroup \hsize=\maxdimen } +** +$$\pagelabel{BASICA}\vcenter{\box0}\tag"\style{\bf A}"$$ + +In this situation, line breaking commands at the end of a field have +to be handled a bit differently. We will add things like +** +\null\kern-1sp\kern1sp +** +so that the *\null* will keep the *\kern*'s from disappearing at the end of +the line. + + +\section{Starting the bibliography macros\label{SBMACS}} +The definition of *\makebib* begins +** +\def\makebib@W{Bibliography} +"slip +\def\makebib{\begingroup + \rm + \bigbreak + \centerline{\smc\makebib@W} + \nobreak\medskip + \sfcode`\.=1000 \everypar={}\parindent=0pt +** +We use *\makebib@W* instead of specifying `*Bibliography*' explicitly, +so that *\newword\makebib* can be used to change this heading +(compare section~\Sref{OTHERE} and Chapter~\ref{acces}). *\rm* is added, just +in case another font has been selected. +The space factor code of the period is changed +to ~*1000* because almost all periods in a bibliography will come from +abbreviations (except for the periods at the ends of each entry, and those + occur at the +ends of paragraphs). We add *\everypar={}* \pagelabel{EVAPI} +just in case *\everypar* was +non-empty before, since each entry begins as a nonindented paragraph, and we +might as well set *\parindent* to~*0pt*, though that shouldn't matter. + +Once *\makebib* has appeared, we might be using not only *\nopunct* and +*\nospace*, but also *\noprepunct* and *\noprespace* and +*\noquotes* +before various elements +of a *\bib...\endbib* entry. +Since all of these can precede almost any construction, + we want to save +ourselves all the agony of section~\Sref{AGONY}, and simply have each of +these set a flag. *\nopunct* and *\nospace*, which already have definitions, +will thus have to be changed by *\makebib*, and, to be on the safe side, +we will reset the flags to be false, +** +\def\makebib{\bigbreak + \centerline{\smc Bibliography} + \nobreak\bigskip + \sfcode`\.=1000 \everypar={}\parindetn=0pt + \def\nopunct{\nopunct@true} + \def\nospace{\nospace@true} + \nopunct@false\nospace@false +** + +As mentioned in section~\Sref{BASICD}, *\lkerns@*, and +*\nkerns@* + have to be changed for the bibliography macros; these +new definitions also have to be added to *\makebib*: +\C** +\def\makebib{\bigbreak + \centerline{\smc Bibliography}% + \nobreak\bigskip + \sfcode`\.=1000 \everypar={}\parindent=0pt + \def\nopunct{\nopunct@true}% + \def\nospace{\noprepunct@true}% + \nopunct@false\nospace@false + \def\lkerns@{\null\kern-1sp\kern1sp}% + \def\nkerns@{\null\kern-2sp\kern2sp}% +} +** + +The *\endmakebib* simply supplies the *\endgroup* that matches the\linebreak +*\begingroup* with which *\makebib* begins: +\C** +\let\endmakebib=\endgroup +** + +Next we add the flags and definitions +\C** +\newif\ifnoprepunct@ +\newif\ifnoprespace@ +\newif\ifnoquotes@ +"2 +\def\noprepunct{\noprepunct@true} +\def\noprespace{\noprespace@true} +\def\noquotes{\noquotes@true} +** + +And then we declare all the boxes needed to hold various constructions: +\C** +\newbox\nobox@ +\newbox\keybox@ +\newbox\bybox@ +"2 +\newbox\paperbox@ +\newbox\paperinfobox@ +"2 +\newbox\jourbox@ +\newbox\volbox@ +\newbox\issuebox@ +\newbox\yrbox@ +"2 +\newbox\pgbox@ +\newbox\ppbox@ +"2 +\newbox\bookbox@ +\newbox\inbookbox@ +\newbox\bookinfobox@ +"2 +\newbox\publbox@ +\newbox\publaddrbox@ +"2 +\newbox\edbox@ +\newbox\edsbox@ +"2 +\newbox\langbox@ +\newbox\translbox@ +\newbox\finalinfobox@ +** + +\section{\CS{bibinfo\@}\label{BIBINFO}} +Each of + various constructions within a *\bib...\endbib* entry, like +*\paper*, *\jour*, \dots, +may be preceded by *\nopunct*,\dots,\linebreak + *\noquotes*, and we need an easy +way to keep track of this information. +We will store all the +necessary information for a *\bib...\endbib* entry +in a control sequence *\bibinfo@* (initially empty at the beginning of each +*\bib*). +Each field like *\paper*, *\jour*, \dots, will first update *\bibinfo@*, +based on the current values of the flags *\ifnopunct@*, \dots, +*\ifnoquotes@*---these values will simply depend on whether *\nopunct*, \dots, +*\noquotes* occurred before this field (but after the preceding field). + + Remember that + *\paperbox@*, *\jourbox@*, \dots, are simply \tex\ integers, +\footnote{More precisely +({\it The \tex book}, page~121), +the *\newbox* routine will *\chardef\paperbox@*, etc., and \tex\ allows +*\chardef*'d quantities to be used as integers.} +which we can produce with + *\the\paperbox@*, +*\the\jourbox@*, \dots. If\linebreak + *\paperbox@* +happens to have the value ~*28* (it did the last time I checked), and +*\jourbox@* happens +to have the value ~*30*, and *\paper* and *\jour* are preceded by +any of *\nopunct*, \dots, *\noquotes*, then we want *\bibinfo@* to be +\setbox1\hbox{$_{\text1}$}\setbox2\hbox{$_{\text2}$} +\setbox3\hbox{$_{\text3}$}\setbox4\hbox{$_{\text4}$} +\setbox5\hbox{$_{\text5}$} +** +28,x"copy1"relax"0x"copy2"relax"0x"copy3"relax"0x"copy4"relax"0x"copy5"relax"030,y"copy1"relax"0y"copy2"relax"0y"copy3"relax"0y"copy4"relax"0y"copy5 +** +\setbox1\hbox{$_{\text1}$}\setbox2\hbox{$_{\text2}$}% +\setbox3\hbox{$_{\text3}$}\setbox4\hbox{$_{\text4}$}% +\setbox5\hbox{$_{\text5}$}% +$\bigl[$or +*30,y"copy1"relax"0y"copy2"relax"0y"copy3"relax"0y"copy4"relax"0y"copy5"relax"028,x"copy1"relax"0x"copy2"relax"0x"copy3"relax"0x"copy4"relax"0x"copy5 +* +if *\jour* appears before *\paper*$\bigr]$, +where +\setbox7\hbox{$_{\text1}$}\setbox2\hbox{$_{\text2}$} +\setbox3\hbox{$_{\text3}$}\setbox4\hbox{$_{\text4}$} +\setbox5\hbox{$_{\text5}$} +$$\align + \text{{\tt x}\copy7\quad is\quad}& + \cases {\tt1}&\text{if {\tt\bs nopunct} precedes + {\tt\bs paper}}\\ + {\tt0}&\text{otherwise}\endcases\\ +\allowdisplaybreak + \text{{\tt x}\copy2\quad is\quad}& + \cases {\tt1}&\text{if {\tt\bs nospace} precedes + {\tt\bs paper}}\\ + {\tt0}&\text{otherwise}\endcases\\ +\allowdisplaybreak + \text{{\tt x}\copy3\quad is\quad}& + \cases {\tt1}&\text{if {\tt\bs noprepunct} precedes + {\tt\bs paper}}\\ + {\tt0}&\text{otherwise}\endcases\\ +\allowdisplaybreak + \text{{\tt x}\copy4\quad is\quad}& + \cases{\tt1}&\text{if {\tt\bs noprespace} precedes + {\tt\bs paper}}\\ + {\tt0}&\text{otherwise}\endcases\\ +\allowdisplaybreak + \text{{\tt x}\copy5\quad is\quad}& + \cases {\tt1}&\text{if {\tt\bs noquotes} precedes + {\tt\bs paper}}\\ + {\tt0}&\text{otherwise}\endcases +\endalign$$ +and similarly for *y*\copy7, \dots, *y*\copy5. + + +To conserve memory, and allow subsequent macros to work quickly, +we want *\bibinfo@* to contain only necessary information; boxes not preceded +by any of +*\nopunct*, \dots, *\noquotes* simply shouldn't show up. + + +The routine *\setbibinfo@#1*, used when *#1* is *\paperbox@*, \dots, +suitably expands *\bibinfo@* if necessary, based on the current +values of +the flags *\ifnopunct@*, \dots, *\ifnoquotes@*: +\C** +\def\setbibinfo@#1{\edef\next@{\ifnopunct@1\else0\fi + \ifnospace@1\else0\fi\ifnoprepunct@1\else0\fi + \ifnoprespace@1\else0\fi\ifnoquotes@1\else0\fi}% + \def\nextii@{00000}% + \ifx\next@\nextii@ + \else + \xdef\bibinfo@{\bibinfo@\the#1,\next@}% + \fi} +** +\setbox1\hbox{$_{\text1}$}\setbox2\hbox{$_{\text2}$}% +\setbox3\hbox{$_{\text3}$}\setbox4\hbox{$_{\text4}$}% +\setbox5\hbox{$_{\text5}$}% +Here we first set *\next@* to the proper *x*\copy1 \dots *x*\copy5. +Then, if this sequence is *00000* (because none of *\nopunct*, \dots, +*\noquotes* appeared) we do nothing; otherwise, we add +\setbox1\hbox{$_{\text1}$}\setbox2\hbox{$_{\text2}$}% +\setbox3\hbox{$_{\text3}$}\setbox4\hbox{$_{\text4}$}% +\setbox5\hbox{$_{\text5}$}% +** +\the#1,x"copy1x"copy2x"copy3x"copy4x"copy5 +** +to *\bibinbfo@*. An *\xdef* was needed to define *\bibinfo@* globally +because we will be using *\setbibino@* within a group, to pass information on +beyond that group (section~\Sref{VBOXII}). + +There is a corresponding *\getbibinfo@#1*, which will +*\let\next@=x*$_{\text1}$, + \dots, +*\let\nextv@=x*$_{\text5}$ when + `*\the#1,*' appears in *\bibinfo@*, or simply *\let* them + *=0* otherwise: +\C** +\def\getbibinfo@#1{% + \ifx\bibinfo@\empty + \let\next@=0\let\nextii@=0\let\nextiii@=0% + \let\nextiv@=0\let\nextv@=0% +"2 + \else + \edef\next@{\def + \noexpand\next@####1\the + #1,####2####3####4####5####6####7\noexpand\next@ + {\let\noexpand\next@=####2\let\noexpand\nextii@=####3% + \let\noexpand\nextiii@=####4\let\noexpand\nextiv@=####5% + \let\noexpand\nextv@=####6}% + \noexpand\next@\bibinfo@\the#1,00000\noexpand\next@}% + \next@ + \fi} +** +By now it should be no problem to unravel this (compare +page~\ref{ADDCSNAME} and Chapter~\ref{NEWC}). +For the sake of speed, we have made a special clause for the (usual) case +where *\bibinfo@* is empty. +We use the rather rare assignments *\let\next@=0* or *\let\next@=1*, etc., +so that later we can use simple *\if* tests, +** +\if\next@1 . . . +** +to test for the value. + + +Note, finally, that these definitions work because *\paperbox@*, \dots, all +represent 2@-digit numbers. There would be ambiguity if, for example, +one had the value ~*9* and another had the value ~*19*; fortunately, that +can't happen, since *\newbox* only creates numbers greater than ~*9*. + + +\section{Additional flags} +Next we introduce the flags for determining the treatment of paper and +book titles: +\C** +\newif\ifbookinquotes@ +\def\bookinquotes{\bookinquotes@true} +\newif\ifpaperinquotes@ +\def\paperinquotes{\paperinquotes@true} +\newif\ifininbook@ +\def\ininbook{\ininbook@true} +** + +We will also need a flag +\C** +\newif\ifopenquotes@ +** +which we will set true after printing each + *\paper* or +*\book* title that has begun with~*``*. +The next field will then supply the closing~*''* at the right time, +and reset the flag to false, + using +the routine +\C** +\def\closequotes@{\ifopenquotes@''\openquotes@false\fi} "8OQFALSE"8 +** + + +In addition, we need special flags to deal with the possibilities of +*\morebib*, *\anotherbib*, and *\transl*. +The definitions of these constructions aren't given until +section~\Sref{ENDS}, but some discussion is necessary +now. These three constructions act almost like an *\endbib*~ *\bib* pair, +first printing the information already collected (but without ending the +paragraph), and then collecting new information. For efficiency, these +constructions and *\endbib* all +call upon a common construction, *\endbib@*, which +does all the work of printing the accumulated information, except that +certain flags will have to be set differently for the various constructions. + +First we have the flags +\C** +\newif\ifbeginbib@ +\newif\ifendbib@ +** +The flag *\ifbeginbib@* will, for example, determine whether or not we should +print *\no* and *\key* information; it will be true when we are +setting the first part of a *\bib...\endbib* entry, but false if we are +printing a *\morebib* part. The flag *\ifendbib@* will, for example, +determine whether we should print the final period at the end of the entry; +it will be false if we are printing the first part of an entry that has +a *\morebib* part to follow, though it will be true when we then set +the *\morebib* part. + +We also need the flags +\C** +\newif\ifprevjour@ +\newif\ifprevbook@ +** +to pass information to *\morebib* and *\anotherbib* about a *\jour* or +*\book* in the main part. + + + +\section{\CS{bib}} +For defining *\bib* we first introduce a new +dimension +\C** +\newdimen\bibindent@ +** +with the default value +\C** +\bibindent@=20pt +** +in terms of which the hanging indentation for *\bib* items will be +specified. This makes it easier to add commands to change this indentation. +(The default style doesn't have any such commands, but other styles do.) +Then we define +\C** +\def\bib{\global\let\bibinfo@=\empty + \global\let\translinfo@=\relax + \beginbib@true + \begingroup + \noindent@\hangindent\bibindent@ \hangafter1 + \bib@} +** +The *\global\let\bibinfo@=\empty* clears out *\bibinfo@* from the previous +*\bib..\endbib*. + *\translinfo@*, which will play a role later, also has +to be cleared out. Then we set *\ifbeginbib@* to be true, begin a group, +start a *\noindent@*'ed paragraph with hanging indentation *\bibindent@* after +the first line, and call *\bib@*. + + +*\bib@* has to start by setting *\nobox@*, *\keybox@*, \dots, to void boxes. +We introduce the abbreviation +\C** +\def\v@id#1{\setbox#1=\box\voidb@x} +** +and then +\C** +\def\bib@{\v@id\nobox@ \v@id\keybox@ \v@id\bybox@ + \v@id\paperbox@ \v@id\paperinfobox@ + \v@id\jourbox@ \v@id\volbox@ \v@id\issuebox@ \v@id\yrbox@ + \v@id\pgbox@ \v@id\ppbox@ + \v@id\bookbox@ \v@id\inbookbox@ \v@id\bookinfobox@ + \v@id\publbox@ \v@id\publaddrbox@ + \v@id\edbox@ \v@id\edsbox@ + \v@id\langbox@ \v@id\translbox@ \v@id\finalinfobox@ + \bgroup} +** +As explained in section~\Sref{BASICD}, + the *\bgroup* will immediately be closed +by an *\egroup* at the beginning of the *\no* or *\key* or \dots\ that +occurs next. + +\section{The basic construction} +The basic definition ({\bf A}) on page~\ref{BASICA} is going to be +changed in several ways. First of all, when *#1* is *\paperbox@*, +*\jourbox@*, etc., +we want to add +** +\unskip"9\setbibinfo@#1"9\egroup +\setbox#1=\vbox\bgroup . . . +** +so that *\bibinfo@* will have + the proper information regarding any *\nopunct*, \dots, *\noquotes* that +precede *\paper*, *\jour*, \dots. Since the information in + *\bibinfo@* is recorded using +*\xdef*'s, this can be done before the *\egroup*; note also that +since each *\nopunct*, \dots, *\noquotes* will occur within a field, and +thus eventually within some *\bgroup...\egroup*, we don't have to worry about + their effects unexpectedly promulgating to another field. + +Inside the *\vbox* we will want to have +** +\hsize=\maxdimen +** +as well as +** +\leftskip=0pt \rightskip=0pt +** +(even if, for some strange reason, the bibliography is being set with other +values, we want to have *\leftskip* and *\rightskip* be zero inside the +preliminary *\vbox*), and +also +** +\hbadness=10000 \hfuzz=\maxdimen +** +(so that *Underfull* and *Overfull* boxes will be reported only later, not +during the *\vbox* step), all followed by +** +\noindent +** +to preclude any extra indentation in our test *\vbox*. + +But if we have an empty field (page~\ref{EFIELD}), in which case +our *\vbox* will have width ~*0pt*, +\footnote{The *\hsize=\maxdimen* + within our *\vbox*\pagelabel{MAXD} + simply describes the width of paragraphs +of text within the *\vbox*, not necessarily the width of the *\vbox* itself.} + we want to reset +our box to *\box\voidb@x*. We can do this with +** +\unskip\setbibinfo@#1\egroup +"9\def\aftergroup@{\ifdim\wd#1=0pt \setbox#1=\box\voidb@x\fi}"9 +\setbox#1=\vbox\bgroup "9\aftergroup\aftergroup@"9 . . . +** + Here the `*\aftergroup@*' is performed immediately after the +*\egroup* from the next field (or from *\endbib*) +that eventually matches the *\bgroup*. + + In addition, in a few cases +we will need to add something extra right after the first *\egroup* (namely, +settings for the flags *\ifprevjour* and *\ifprevbook*). + So +for this general case +we define +\C** +\def\Setnonemptybox@#1#2{% + \unskip\setbibinfo@#1\egroup#2% + \def\aftergroup@{\ifdim\wd#1=0pt + \setbox#1=\box\voidb@x\fi}% + \setbox#1=\vbox\bgroup \aftergroup\aftergroup@ + \hsize=\maxdimen \leftskip=0pt \rightskip=0pt + \hbadness=10000 \hfuzz=\maxdimen + \noindent} +** + and then for the more common case we define +\C** +\def\setnonemptybox@#1{\Setnonemptybox@#1\relax} +** + +\small Notice that we used *\noindent@* in the definition of *\bib*, but +*\noindent* in the definition of *\Setnonemptybox@*. That is because there +is a difference between the situation +\Litbox0=** +\bib \pagelabel{...} \no . . . \endbib +** +$$\box0\tag"\style{\bf A}"$$ +where the invisible *\pagelabel* occurs before any field, +and something like +\Litbox0=** +\bib . . . \paper \pagelabel{...} . . . \endbib +** +$$\box0\tag"\style{\bf B}"$$ +where the *\pagelabel* occurs within a field. + +In case ({\bf A}), the *\bib* contributes a *\bgroup* (via the *\bib@*), and +the *\no* supplies the ending *\egroup*. Within this group, the +*\pagelabel{...}* has already deleted the final space, but even if it didn't, +the *\unskip* before the *\egroup* contributed by *\no* would get rid of it. +Consequently, nothing except a *\write* is contributed by this group. But if +we tried to be too careful, and replaced the *\bgroup* in *\bib@* with +** +\bgroup\futurelet\next\pretendspace@ +** +then, since the invisible *\pagelabel* follows, +the results would be wrong: +\list +\item First *\pretendspace* would contribute *\hskip-1pt\hskip1pt*. +\item Then the *\prevanish@* in *\pagelabel* would set *\saveskip@* to~ *1pt* +and remove the *\hskip1pt*. +\item Then the *\postvanish@* in *\pagelabel* would add back the *1pt* and +then delete the next space, if any. +\item Consequently, the *\unskip\egroup* in *\no* would remove the final +*1pt*, leaving an extra *\hskip-1pt* at the beginning. +\endlist + +In case ({\bf B}), however, the *\noindent* (which eventually calls the +combination +*\futurelet\next\pretendspace@*) makes everything work out correctly if an +invisible element occurs first (followed by something else). Of course, this +won't work +if a *\pagelabel* appears within an {\it empty\/} field, but that doesn't +seem worth worrying about! +\endsmall + +\nopunct\section{\CS{no}, \CS{key}, \dots.} +Now we are ready to give definitions of *\no*, *\key*, \dots, many of +which are +quite +similar. First we have +\C** +\def\no{\setnonemptybox@\nobox@} +\def\key{\setnonemptybox@\keybox@\bf} +\def\by{\setnonemptybox@\bybox@} +** +Notice that *\key* specifies *\bf* for the font. + +For *\bysame* we simply specify the desired rule, rather than waiting for +user input: +\C** +\def\bysame{\setnonemptybox@\bybox@ + \leaders\hrule\hskip3em\null} +** +The *\null* is essential, to prevent the *\unskip* from the next field from +deleting this *\leaders* glue (compare the \lamstex~Manual, page~225). + +The definition of *\paper* is a little more complicated, because we +have to begin with~*``* when *\ifpaperinquotes@* is true, + except not +when *\noquotes* precedes *\paper*. To find out this latter information, + we use +** +\getbibinfo@\paperbox@ +** +which will *\let\nextv@=1* if *\noquotes* preceded *\paper*, but +will\linebreak +*\let\nextv@=0* otherwise: +\C** +\def\paper{\setnonemptybox@\paperbox@ + \ifpaperinquotes@ + \getbibinfo@\paperbox@ + \if\nextv@1\else``\fi + \else + \it + \fi} +** +Notice that we've specified *\it* when *\ifpaperinquotes@* is false (even if +*\noquotes* preceded *\paper*). + +The next definition reverts to the simple case, +\C** +\def\paperinfo{\setnonemptybox@\paperinfobox@} +** +but the definition of *\jour* uses *\Setnonemptybox@*, since we need to +set *\ifprevjour@* true (for possible use by *\morebib* later on): +\C** +\def\jour{\Setnonemptybox@\jourbox@\prevjour@true} +** + +The next definitions are simple (*\vol* merely adds *\bf* for the font), +\C** +\def\vol{\setnonemptybox@\volbox@\bf} +\def\issue{\setnonemptybox@\issuebox@} +\def\yr{\setnonemptybox@\yrbox@} +** + +But *\toappear* is handled quite specially: +\C** +\def\toappear{\noprepunct\finalinfo(to appear)} +** + + +Then come another two simple definitions: +\C** +\def\pg{\setnonemptybox@\pgbox@} +\def\pp{\setnonemptybox@\ppbox@} +** + +The definition of *\book* has both the complexities of +*\paper* (involving quotation marks) and *\jour* (setting a flag), +\C** +\def\book{\Setnonemptybox@\bookbox@\prevbook@true + \ifbookinquotes@\getbibinfo@\bookbox@ + \if\nextv@1\else``\fi + \else + \it +\fi} +** +and the definition of *\inbook* has yet another clause, because of the +flag *\ifinbook@*: +\C** +\def\inbook{\Setnonemptybox@\inbookbox@\prevbook@true + \ifininbook@ in \fi + \ifbookinquotes@\getbibinfo@\inbookbox@ + \if\nextv@1\else``\fi + \fi} +** +(In this case we don't change fonts even if there are no +quotation marks.) + +Then comes another bunch of simple definitions, +\C** +\def\bookinfo{\setnonemptybox@\bookinfobox@} +\def\publ{\setnonemptybox@\publbox@} +\def\publaddr{\setnonemptybox@\publaddrbox@} +\def\ed{\setnonemptybox@\edbox@} +\def\eds{\setnonemptybox@\edsbox@} +\def\lang{\setnonemptybox@\langbox@} +\def\finalinfo{\setnonemptybox@\finalinfobox@} +** + +This leaves only *\transl*, *\morebib*, and *\anotherbib*, all of which +are treated somewhat similarly---it will be easiest to understand their +definitions later (section~\Sref{ENDS}) +after examining how *\endbib* puts all the information together. + + +\section{Manipulating the \CS{vbox}'es\label{VBOXI}} +At the end of a *\bib...\endbib* entry, +we will have stored all our information in various *\vbox*'es, and we now +have to get information out of each such box, *#1*, with a construction +*\getbox@#1*. Most of the time we could simply use +** +\def\getbox@#1{\setbox0=\vbox{\unvbox#1 + \setbox0=\lastbox + \global\setbox1=\hbox{\unhbox0 \unskip\unskip\unpenalty}} + \unhbox1 } +** +Here the inner *\box0* (*\lastbox*) is the final line of this +one line paragraph (having *\hsize=\maxdimen*), at the end of which we have +(see {\it The \tex book}, page~100), +\setbox0\hbox{\<}\setbox1\hbox{\>} +** +\penalty 10000 "copy0\parfillskip glue"copy1 "copy0\rightskip glue"copy1 +** +which we delete with the *\unskip\unskip\unpenalty*. + +But since line breaking commands may have +occurred (either in the middle of the field, or at the end), + our *\vbox* may have several *\hbox*'es, separated by glue and +possibly penalties (*\clubpenalty*, etc.), and we may have to use a *\loop* +to discover all these boxes. +We + add *\vskip-10000 pt* at the beginning as a +marker, the assumption that such a *\vskip* won't be +inserted otherwise. +\C** +\def\getbox@#1{\setbox0=\vbox{\vskip-10000pt "8VSMARK"8 + \unvbox#1% "8GUNV"8 +"2 + \setbox0=\lastbox +"2 + \global\setbox1=\hbox{\unhbox0 \unskip\unskip\unpenalty} +"2 + \ifdim\lastskip=-10000pt + \else +"2 + \loop + \ifdim\lastskip=-10000 pt +"2 + \else + \unskip\unpenalty\setbox0=\lastbox + \global\setbox1=\hbox{\unhbox0 \unhbox1}% + \repeat +"2 + \fi}% + \unhbox1 } +** +Notice that we use the test *\ifdim\lastskip=-10000pt* before entering +the *\loop*, even though it is also used within the *\loop*; this +allows us to bypass the *\loop* completely if it is unnecessary. + + +\small The combination *\setbox0=\lastbox* occurs rather often, so right +before the definition of *\getbox@* we have +\C** +\def\setboxzl@{\setbox\z@\lastbox} +** +and then we use *\setboxzl@* throughout. However, for the sake of +readability, we will always simply print `*\setbox0=\lastbox*'. +\endsmall + +\section{Line breaking commands\label{BIBMACS}} +Next we have to deal with the problem of a line breaking command appearing at +the end of one our fields, since the appropriate penalties must be +inserted {\it after\/} the punctuation that is normally added after the +field. These line breaking commands + produce +\setbox0\hbox{\it n} +** +\null\kern-"copy0",sp",\kern","copy0",sp +** +at the end of the horizontal list produced by *\getbox@*. +More specifically, +\list \advance\litindent15pt +\item *\nolinebreak* produces +\setbox0\hbox{\} +** +\penalty10000 "box0 \null\kern-1sp\kern1sp +** +The \ comes about because *\nolinebreak* remembers the +glue before it, and inserts it after the *\penalty10000*, so that this +glue does {\it not\/} disappear. Of course, it is unlikely that any one would +want to have such a non-disappearing space at the end of a field, but we +might as well allow for the possibility. +\item Similarly, *\allowlinebreak* produces +\setbox0\hbox{\} +** +\penalty0 "box0 \null\kern-1sp\kern1sp +** +\item *\linebreak* produces +\setbox0\hbox{\<}\setbox1\hbox{\>} +** +\penalty-10000 "copy0"relax0pt glue"copy1 \null\kern-1sp\kern1sp +** +Here the *\null\kern-1sp\kern1sp* comes from the last *\hbox* in the +*\vbox*, while the *\penalty-10000 "copy0"relax0pt glue"copy1* comes from the +previous *\hbox*, the *"copy0"relax0pt glue"copy1* + being the *\rightskip* glue, and the +*\penalty-10000* the penalty from *\linebreak*. +\item *\newline* produces +\setbox0\hbox{\<}\setbox1\hbox{\>} +** +"hskip-20pt\null \hfil \penalty-10000 "copy0"relax0pt"copy1 \null\kern-2sp\kern2sp +** +Now the *\null\hfil\penalty-10000 "copy0"relax0pt glue"copy1* comes from the next to last +*\hbox*, the *"copy0"relax0pt glue"copy1* + again being the *\rightskip* glue, and the +*\null\hfil\penalty-10000* coming from the *\newline*. +\endlist + + Since such small +*\kern*'s were +presumably not inserted by the user, their presence indicates that one of +the line breaking commands occurred; the value of the *\kern*, +together with the *\penalty* before the *\null*, allows us to +distinguish the four cases. + +We introduce +the routine *\adjustpunct@#1*, where *#1* is normally some punctuation +symbol, which will find such information, delete all the *\kern*'s, +*\penalty*'s, etc., add the punctuation *#1*, and then put back +the proper *\penalty*. + We begin with +** +\def\adjustpunct@#1{\count@=\lastkern +** +so that *\count@* is the number of scaled points in *\lastkern*. This will +normally either be ~*0*, because there is no *\kern*, or if a *\kern* was +inserted by the user, it will be +something reasonably large or large negative, +presumably \hbox{*>2*} or \hbox{*<-2*}. +In such cases, we just want to add the punctuation +*#1*, except that this must be followed by *\closequotes@*, in case +*''* needs to be added after the punctuation, because the previous field began +with~*``*: +** +\def\adjustpunct@#1{\count@=\lastkern + \ifnum\count@=0 #1\closequotes@\else + \ifnum\count@>2 #1\closequotes@\else + \ifnum\count@<-2 #1\closequotes@\else + . . . +** + +In the remaining, more interesting case, we use +** +\unkern\unkern\setbox0=\lastbox +** +to get rid of the +\setbox0\hbox{\it n} +** +\null \kern-"copy0",sp\kern","copy0",sp +** +Then we save the previous glue in *\skip@* and remove it: +** +\skip@=\lastskip \unskip +** +Now we've reached the point where the original *\penalty* is revealed; +we store it in *\count@@* and remove it: +** +\count@@=\lastpenalty \unpenalty +** +Moreover, in the case of *\newline* (*\count@* is~*2*), we also get rid of +the *\null\hfil*: +** +\ifnum\count@=2 \unskip \setbox0=\lastbox \fi +** +Now we can add the punctuation *#1*, followed by *\closequotes@*; +if *\skip@* is non-zero, because of the \ in the case of +*\nolinebreak* or *\allowlinebreak*, we add this first: +** +\ifdim\skip@=0pt \else \hskip\skip@ \fi +#1\closequotes@ +** +In the case of *\newline* we then add back a *\null\hfill*, and in all +cases we add back the original *\penalty*, now stored in *\count@@*: +\C** +\def\adjustpunct@#1{\count@=\lastkern + \ifnum\count@=0 #1\closequotes@\else + \ifnum\count@>2 #1\closequotes@\else + \ifnum\count@<-2 #1\closequotes@\else + \unkern\unkern\setbox0=\lastbox + \skip@=\lastskip \unskip + \count@@=\lastpenalty\unpenalty + \ifnum\count@=2 \unskip\setbox0=\lastbox\fi + \ifdim\skip@=0pt \else \hskip\skip@ \fi + #1\closequotes@ + \ifnum\count@=2 \null\hfill\fi + \penalty\count@@ + \fi\fi\fi} +** + +\section{Adding punctuation before a field\label{VBOXII}} +The routine *\adjustpunct@* figures prominently in the routine +** +\prepunct@#1#2 +** +which adds *#1*, + some sort of +punctuation, before the field corresponding to *#2*, +which is *\paperbox@*, \dots. + +Before we consider this routine, we need to reconsider the information +in *\bibinfo@*, which we use with the +routine *\getbibinfo@* to funnel information from *\bibinfo@* into +*\next@*, \dots, *\nextv@*. +Note that the information derived from the value of *\next@* and *\nextii@*, +i.e., whether or not *\nopunct* or *\nospace* preceded the field, is not +used when printing the field; this information has to be used +by the {\it next\/} field, to decide whether to print the finishing +punctuation and space, before printing the new material from that next field. + Consequently, +the information from the value of *\next@* and *\nextii@* has to be passed +along to the next field. We will pass this information along by setting the +values of the flags *\ifnopunct@* and *\ifnospace@* once again, thus +providing them with a dual role. + + +Now our definition of *\prepunct@* begins +** +\def\prepucnt@#1#2{\getbibinfo@#2% + "hskip-10pt% first part + \ifnopunct@ + \else + \if\nextiii@0\adjustpunct@#1\fi + \fi +"2 + \closequotes@ + \ifnospace@ + \else + \if\nextiv@0\space\else\fi + \fi + "hskip-10pt% second part + \nopunct@false \nospace@false + \if\next@1\nopunct@true\fi + \if\nextii@1\nospace@true\fi +** + +Before examining the first part of this code, consider the second part: +this sets *\ifnopunct@* to be true if *\nopunct@* preceded the field +and *\ifnospace@* to be true if *\nospace@* preceded the field. + +The first part of the code should now make more sense, when we +remember that + those same assignments will have been made by the field which precedes +this field: +The test *\ifnopunct@* is true if + the previous field is not supposed to have punctuation at the end, +and *\nextiii@* will be~*1* (rather than *0*) if the current field +was followed by *\noprepunct*. In either of these cases, + we don't supply any punctuation; otherwise, we use *\adjustpunct@#1* +to supply the punctuation *#1*. Even when no punctuation is supplied, we +need *\closequotes@*, in case +the previous field set *\ifopenquotes@* true (if *\adjustpunct@* {\it was\/} +used, the *\closequotes* within it has already set *\ifopenquotes@* to be +false [page~\ref{OQFALSE}], so we won't be adding closing quotes twice). +Space following +the punctuation is handled similarly, using the flags *\ifnospace@* and +the value of *\nextiv@*. +\C** +\def\prepunct@#1#2{\getbibinfo@#2% + \ifnopunct@ +"2 + \else + \if\nextiii@0\adjustpunct@#1\fi + \fi +"2 + \closequotes@ +"2 + \ifnospace@ + \else + \if\nextiv@0\space\else\fi + \fi +"2 + \nopunct@false\nospace@false + \if\next@1\nopunct@true\fi + \if\nextii@1\nospace@true\fi} +** + + *\prepunct@#1#2* is usually followed immediately by *\getbox@#2*, so +we introduce an abbreviation for that combination: +\C** +\def\ppunbox@#1{\prepunct@{#1}#2\getbox@#2} +** + +\section{\CS{endbib\@}\label{SEMICOL}} + Now we're ready to actually typeset all the +information acquired by a *\bib...\endbib* entry. +First we +\C** +\let\semicolon@=; +** +so that we can use *\semicolon@* in place of *;* everywhere. This is done +solely for the benefit of French styles (compare section~\Sref{ALF}), +which can then redefine *\semicolon@* (presumably as something like +*" ;*). + + +The final command *\endbib* is defined in terms of +*\endbib@*, which does most of the work. +We begin with +** +\def\endbib@{% + \ifbeginbib@ + \ifvoid\nobox@ + \ifvoid\keybox@\else + \hbox to\bibindent@{[\getbox@\keybox@]\hss}\fi + \else + \hbox to\bibindent@{\hss\getbox@\nobox@. } + \fi + . . . +** +Thus, when *\ifbeginbib@* is true + (which will usually be the case, unless we +are printing remaining information from *\morebib*, *\anotherbib*, or +*\transl*), +if *\box\nobox@* isn't void we +start our *\noindent@*'ed paragraph with +** +\hbox to\bibindent@{\hss\getbox@\nobox@. } +** +a box of width *\bibindent@*, which is also the amount of hanging indentation +we will be using, +containing + the +information in *\box\nobox@*. This information +(from *\getbox@\nobox@*) is followed by a period +and a space, and preceded by *\hss* (rather than *\hfil*, just in case the +number is too long). +Because the *\ifvoid* test always tells us whether or not a particular field +has been set, we don't need any flags for this. Note also that *\getbox@#1* +uses *\unvbox#1* (page~\ref{GUNV}), + so that once we print the information for a +field, the box containing that information +has become void again. + + +If *\box\nobox@* is void, we instead use +the information in *\box\keybox@*, if that isn't void. In this case +we surround the information with brackets, and have it start at the left +margin, with the additional space at the right. + +In the other case, where *\ifbeginbib@* is false, we use +** +\else + \nopunct@true "8NOPUNCTT"8 + \ifvoid\bybox@\else\getbox@\bybox@\fi +\fi +** +We first set *\ifnopunct@* to be true because we don't want the first +field of our *\morebib* or *\anotherbib* or *\transl* portion to +add any punctuation to the end of the previous field, which +will already have been supplied with a closing~ *;* (see +page~\ref{FINTCH}ff.). Normally +*\box\bybox@* will be void for this subsequent portion, but +*\by* could conceivably be used after *\anotherbib*, so we add that in. + + +After this preamble, we start to add the other +various elements in the required +order. Although *\transl* isn't defined until section~\Sref{ENDS}, it +does end up storing its information in *\box\translbox@*, just like +other fields; if this box is nonvoid, then we must be setting this +second portion of the entry, and this information should come first, so + we now add +** +\ifvoid\translbox@\else\ppunbox@,\translbox@\fi +** +to print the information. + +Next comes +** +\ifvoid\paperbox@ +\else + \ppunbox@,\paperbox@ + \ifpaperinquotes@ + \if\nextv@1\else\openquotes@true\fi + \fi +\fi +** +Thus, if *\box\paperbox@* isn't void we add the information in it, +with appropriate punctuation and spacing before it. The *\ppunbox@* routine +has already used *\getbibinfo@\paperbox@* to get information from +*\bibinfo@*. When the flag *\ifpaperinquotes@* is true (so that we are +enclosing paper titles in quotation marks), then the paper title normally +has begun with *``* and we want to set *\ifopenquotes@* to be true, so that +the next routine will know the add the *''*; however, we don't do this +when the *\bibinfo@* has caused +*\nextv@* to be~*1*, since this indicates that a *\noquotes* preceded the +*\paper*, in which case the opening *``* will not have been included in +the paper title. + +After the paper title, we add any *\paperinfo*: +** +\ifvoid\paperinfobox@\else\ppunbox@,\paperinfobox@\fi +** + +Then comes the information in *\jourbox@*, *\volbox@*, *\issuebox@*, \dots. +Information from *\volbox@*, \dots, should be added only if there was +\list\newnumstyle\list1\alph +\item information in *\jourbox@*; +\item or in the case of *\morebib*, information in a previous *\jourbox*. +\endlist +In the latter case, *\ifprevjour@* will have been set true, so we use +\setbox0\hbox{\} +** +\test@false +\ifvoid\jourbox@\else\test@true\ppunbox@,\jourbox@\fi +\ifprevjour@\test@true\fi +\iftest@ + "box0 +\fi +** + +For *\volbox@* we use +** +\ifvoid\volbox@\else\ppunbox@\relax\volbox@\fi +** +since there is no punctuation before the information in *\volbox@*. +Similarly, +** +\ifvoid\issuebox@ + \else\prepunct@\relax\issuebox@ no.~\getbox@\issuebox@\fi +"2 +\ifvoid\yrbox@\else\prepunct@\relax\yrbox@ + (\getbox@\yrbox@)\fi +"2 +\ifvoid\ppbox@\else\ppunbox@,\ppbox@\fi +"2 +\ifvoid\pgbox@\else\prepunct@,\pgbox@ + p.~\getbox@\pgbox@\fi +** +puts ``no. '' before the *\issue*, which has no punctuation before it, +encloses the *\yr* in parentheses, with no punctuation before it, and + adds ``p.~'' before *\pg*. + +Next comes information for a book. As with *\jour*, succeeding information +will be printed only if there is a *\book* or *\inbook* or when +*\ifprevbook@* +is true. The flag *\ifbookinquotes@* also requires steps similar to those +used for *\paper*: +\setbox0\hbox{\} +** +\test@false +\ifvoid\bookbox@\else + \test@true\ppunbox@,\bookbox@ + \ifbookinquotes@\if\nextv@1\else\openquotes@true\fi\fi +\fi +\ifvoid\inbookbox@\else + \test@true\ppunbox@,\inbookbox@ + \ifbookinquotes@\if\nextv@1\else\openquotes@true\fi\fi +\fi +\ifprevbook@\test@true\fi +\iftest@ + "copy0 +\fi +** + + The subsidiary fields include *\edbox@*, *\edsbox@*, +*\bookinfobox@*,\linebreak +*\publbox@*, *\publaddrbox@*, and once again *\yrbox@*, *\ppbox@* +and\linebreak + *\pgbox@*, +since the latter three can be with *\paper* as well as with *\book*. +There's nothing here that we haven't already considered: +** +\ifvoid\edbox@\else\prepunct@\relax\edbox@ + (\getbox@\edbox@, ed.)\fi +"2 +\ifvoid\edsbox@\else\prepunct@\relax\edsbox@ + (\getbox@\edsbox@, eds.)\fi +"2 +\ifvoid\bookinfobox@\else\ppunbox@,\bookinfobox@\fi +"2 +\ifvoid\publbox@\else\ppunbox@,\publbox@\fi +"2 +\ifvoid\publaddrbox@\else\ppunbox@,\publaddrbox@\fi +"2 +\ifvoid\yrbox@\else\ppunbox@,\yrbox@\fi +"2 +\ifvoid\ppbox@\else\prepunct@,\ppbox@ + pp.~\getbox@\ppbox@\fi +"2 +\ifvoid\pgbox@\else\prepunct@,\pgbox@ + p.~\getbox@\pgbox@\fi +** + +Then come the finishing touches. At this point the flag +*\ifendbib@* will be important. It will have been set true if we +are finishing off the whole *\bib...\endbib* entry, but it will be false +if we are simply printing the first portion of an entry, with a further +portion from *\morebib* or *\anotherbib* or *\transl* to follow. +The possibility of a *\finalinfo* field will also play a role. We begin +with the case where there was no *\finalinfo* field: +** +\ifvoid\finalinfobox@ + \ifendbib@ + \ifnopunct@\else.\closequotes@\fi + \else + \ifvoid\langbox@\else\space(\getbox@\langbox@)\fi + \/\semicolon@\closequotes@ "8FINTCH"8 +. . . +** +In other words, if we are truly at the end, we print a period, unless +a *\nopunct* preceded the previous field, which will be indicated by +*\ifnopunct@* being true; the *\closequotes@* is added just in case +the previous field happened to be a *\jour* or *\book* in quotes. + + Otherwise (*\morebib* or *\anotherbib* or +*\transl* information follows), we add any *\lang* field information in +parentheses, and then a semicolon (with the italic correction *\/* +before it, in case the previous field was set in a slanted font), + again calling on *\closequotes@* +to supply any necessary closing quotes. +Notice that no space has been added after the semicolon. The *\prepunct@* +or *\ppunbox* for the next field will add in that space, even though +the extra punctuation will not be added (because we set *\ifnopunct@* +to be true when *\ifbeginbib@* is false [page~\ref{NOPUNCTT}]). + + + +For the other case, where there is a *\finalinfo* field, we use +** +\else + \ifendbib@ + \ppunbox@{.\spacefactor3000\relax}\finalinfobox@ + \ifnopunct@\else.\fi + \else + \ppunbox@,\finalinfobox@\/\semicolon@\fi + \fi +** +So, if we are at the very end, we add a period before the *\finalinfo* +field (unless a *\nopunct* or *\noprepunct* tells us not to), and +then a final period (unless a *\nopunct* preceded the *\finalinfo*). +After the period before the *\finalinfo* material we +change the *\spacefactor* to *3000*, +since that period +is not an abbreviation. + If we're not at the very end, so that the *\finalinfo* +applies only to the first portion of the entry, then we want a comma +before this information, and a semicolon (with *\/* before it). + + +Finally, we add +** +\ifvoid\langbox@\else\space(\getbox@\langbox@)\fi +** +at the very end, to take care of a *\lang* field that has to go after +everything else. + +Our whole definition thus reads: +\C** +\def\endbib@{% + \ifbeginbib@ +"2 + \ifvoid\nobox@ + \ifvoid\keybox@\else + \hbox to\bibindent@{[\getbox@\keybox@]\hss}\fi +"2 + \else + \hbox to\bibindent@{\hss\getbox@\nobox@. }\fi + \ifvoid\bybox@\else\getbox@\bybox@\fi +"2 + \else + \nopunct@true + \ifvoid\bybox@\else\ppunbox@\relax\bybox@\fi + \fi +"2 + \ifvoid\translbox@\else\ppunbox@,\translbox@\fi +"2 + \ifvoid\paperbox@\else\ppunbox@,\paperbox@\ifpaperinquotes@ + \if\nextv@1\else\openquotes@true\fi\fi\fi +"2 + \ifvoid\paperinfobox@\else\ppunbox@,\paperinfobox@\fi +"2 + \test@false + \ifvoid\jourbox@\else\test@true\ppunbox@,\jourbox@\fi + \ifprevjour@\test@true\fi +"2 + \iftest@ +"2 + \ifvoid\volbox@\else\ppunbox@\relax\volbox@\fi +"2 + \ifvoid\issuebox@ + \else\prepunct@\relax\issuebox@ no.~\getbox@\issuebox@\fi +"2 + \ifvoid\yrbox@\else\prepunct@\relax\yrbox@ + (\getbox@\yrbox@)\fi +"2 + \ifvoid\ppbox@\else\ppunbox@,\ppbox@\fi +"2 + \ifvoid\pgbox@\else\prepucnt@,\pgbox@ p.~\getbox@\pgbox@\fi + \fi +"2 + \test@false + \ifvoid\bookbox@\else\test@true\ppunbox@,\bookbox@ + \ifbookinquotes@\if\nextv@1\else\openquotes@true\fi\fi + \fi +"2 + \ifvoid\inbookbox@\else\test@true\ppunbox@,\inbookbox@ + \ifbookinquotes@\if\nextv@1\else\openquotes@true\fi\fi + \fi +"2 + \ifprevbook@\test@true\fi +"2 + \iftest@ +"2 + \ifvoid\edbox@\else\prepunct@\relax\edbox@ + (\getbox@\edbox@, ed.)\fi +"2 + \ifvoid\edsbox@\else\prepunct@\relax\edsbox@ + (\getbox@\edsbox@, eds.)\fi +"2 + \ifvoid\bookinfobox@\else\ppunbox@,\bookinfobox@\fi +"2 + \ifvoid\publbox@\else\ppunbox@,\publbox@\fi +"2 + \ifvoid\publaddrbox@\else\ppunbox@,\publaddrbox@\fi + \ifvoid\yrbox@\else\ppunbox@,\yrbox@\fi +"2 + \ifvoid\ppbox@\else\prepunct@,\ppbox@ pp.~\getbox@\ppbox@\fi +"2 + \ifvoid\pgbox@\else\prepunct@,\pgbox@ p.~\getbox@\pgbox@\fi + \fi +"2 + \ifvoid\finalinfobox@ +"2 + \ifendbib@ + \ifnopunct@\else.\closequotes@\fi +"2 + \else + \ifvoid\langbox@\else\space(\getbox@\langbox@)\fi + \semicolon@\closequotes@ + \fi +"2 + \else +"2 + \ifendbib@ + \ppunbox@{.\spacefactor3000\relax}\finalinfobox@ + \ifnopunct@\else.\fi +"2 + \else + \ppunbox@,\finalinfobox@\semicolon@\space\fi + \fi + \ifvoid\langbox@\else\space(\getbox@\langbox@)\fi +} +** + + + +\section{\CS{endbib}, \CS{morebib}, \CS{anotherbib}, and \CS{transl}\label + {ENDS}} + The construction *\endbib* begins with +** +\unskip\egroup +** +just like all other fields, and then it calls *\endbib@* with the +flag +*\ifendbib@* set true (*\ifbeginbib@* has already been set true +by *\bib*), +finishing up with a *\par* and then an +*\endgroup* to match the *\begingroup* supplied by the original *\bib*: +\C** +\def\endbib{\unskip\egroup + \endbib@true\endbib@\par\endgroup} +** + +*\morebib* uses an *\endbib@* to set the material so far, just like *\endbib*, +except that we set *\ifendbib@* +to be false: +** +\def\morebib{\unskip\egroup + \endbib@false\endbib@ +** +And then we want to call *\bib@* again, to deal with the following material, +except that we also need to reset *\bibinfo@* to be empty + and *\ifbeginbib@* to be false: +\C** +\def\morebib{\unskip\egroup + \endbib@false\endbib@ + \global\let\bibinfo@=\empty + \beginbib@false + \bib@} +** + +And *\anotherbib* is almost the same, except that we also +set *\ifprevjour@* +and *\ifprevbook@* to be false before the *\bib@*, + so that no previous material will be +``remembered'': +\C** +\def\anotherbib{\unskip\egroup + \endbib@false\endbib@ + \global\let\bibinfo@=\empty + \beginbib@false + \prevjour@false\prevbook@false + \bib@} +** + +Finally, *\transl* is something like a cross between *\morebib* and +a more standard field. We want to begin with something like +** +\unskip\egroup +\endbib@false\endbib@ +** +in order to print the previous information. + +Then we want to call *\bib@* again, after first setting +*\ifbeginbib@* to be false, as with *\morebib*. Now we start with +** +\beginbib@false +\bib@ +\egroup +\def\aftergroup@{...} +\egroup\setbox\translbox@=\vbox\bgroup + \aftergroup\aftergroup@ \hsize=\maxdimen . . . + \noindent@} +** +so that we will be putting the following field into *\box\translbox@* in +essentially the same way that *\paper*, *\jour*, etc., put their fields +into boxes, using *\setnonemptybox@*. The one thing we are missing from +*\setnonemptybox@* is the procedure for storing information about +any *\nopunct*, \dots, *\noquotes* that precedes the *\transl*. This +information should be stored in *\bibinfo@*, except that any other information +in *\bibinfo@* should be emptied out, ready to be refilled, if necessary, +with current information for the fields following *\transl*. + +To do this, we first store the information in *\translinfo@*, before the +*\egroup*, +** +\def\transl{\unskip + \xdef\translinfo@{\the\translbox@,\ifnopunct@1\else0\fi + \ifnospace@1\else0\fi\ifnoprepunct@1\else0\fi + \ifnoprespace@1\else0\fi0} +** +(we simply use *0* as the last value, + without bothering about the value of *\ifnoquotes@*, since the +value is never used in setting the translation information anyway), +and +then we set *\bibinfo@* to be *\translinfo@* before calling *\bib@*: +\C** +\def\transl{\unskip + \xdef\translinfo@{\the\translbox@,\ifnopunct@1\else0\fi + \ifnospace@1\else0\fi\ifnoprepunct@1\else0\fi + \ifnoprespace@1\else0\fi0}% +"2 + \egroup + \endbib@false + \endbib@ +"2 + \global\let\bibinfo@=\translinfo@ + \beginbib@false + \bib@ +"2 + \egroup +"2 + \def\aftergroup@{\ifdim\wd\translbox@=0 + \setbox\translbox@=\box\voidb@x\fi}% +"2 + \setbox\translbox@=\vbox\bgroup + \aftergroup\aftergroup@ + \hsize=\maxdimen \leftskip=0pt \rightskip=0pt + \hbadness=10000 \hfuzz=\maxdimen + \noindent@} +** +\medskip + +And that jolly well finishes off the bibliography macros! + + + + +\chapterg Interfacing with B{\eightbf IB}\kern-.1em\tex + \label{bibtex}\endchapterg +\runningchapter{Interfacing with B{\eightit IB}\kern-.1em\tex} + + +It turns out that we can easily prepare an *.aux* file on which \bibtex\ can +operate, so that a \lamstex\ file can use the resulting *.bbl* file. +The control sequence +** +\UseBibTeX +** +will set things up for this. +When *\UseBibTex* is specified (preferably close to the beginning of the +document), a +** +\bibliographystyle{...} +** +line should also appear somewhere. + +Furthermore, when *\UseBibTeX* is specified, + *\cite* will essentially function just as in \latex@, rather +than as in the previous chapter, except that we will +continue to use *(...)* for an optional argument rather than *[...]*. +As in \latex@, a citation of the form +\setbox0\hbox{\$_{\text{1}}$} +\setbox1\hbox{\$_{\text{2}}$} +** +\cite{"box0,"box1,...} +** +had better not +have spaces after the commas, because this multiple argument is going to be +passed directly to the *.aux* file, on which \bibtex\ operates, and \bibtex\ +will insist that no space appears. (Of course, spaces will be made to appear +after the commas in the output.) + + +Finally, when *\UseBibTeX* is specified, +instead of a +** +\makebib + . . . +\endmakebib +** +region, a line +\setbox0\hbox{\$_{\text{1}}$} +\setbox1\hbox{\$_{\text{2}}$} +** +\bibliography{"box0,"box1,...} +** +should appear, at the appropriate place. +In this case, + no specific references should be +given, either in \latex\ or in \lamstex\ format. The references will be +supplied by the *.bbl* file that will eventually be made, and which the +*\bibliography* command will read in, +and +any additions +or changes would be made directly in that file. + + +\section{\CS{UseBibTeX}} +We first declare new streams for writing the *.aux* file, and reading +the *.bbl* file: +\C** +\newwrite\auxwrite@ +\newread\bbl@ +** + +Now *\UseBibTeX* +must first open up an *.aux* file, +** +\immediate\openout\auxwrite@=\jobname.aux +** +and then redefine *\cite*. +We will simply +** +\let\cite=\BTcite@ +** +where *\BTcite@* is defined separately afterwards. +That allows a style file to redefine aspects of *\BTcite@* that deal with +the material actually printed. + + +*\UseBibTeX* will also define *\nocite*, +** +\def\nocite#1{\immediate\write\auxwrite@{\string\citation{#1}} +** +and *\bibliographystyle*, +** +\def\bibliographystyle#1{\immediate\write\auxwrite@ + {\string\bibstyle{#1}}} +** + +Finally, it must define *\bibliography*, and this is somewhat more complex. +To begin with, we want to +** +\def\bibliography@W{Bibliography} +** +so that *\newword\bibliography* can be used. +Then we start with +** +\def\bibliography#1{\immediate\write\auxwrite@ + {\string\bibdata{#1}} + . . . +** +Then we have to see whether a *.bbl* file exists. If it doesn't, we simply +give a message to that effect, +but if the *.bbl* file does exists, we read in a special +macro file *bibtex.tex* before we *\input* the *.bbl* file, since +the *bibtex.tex* macros will make this a file that we can process, +** +\def\bibliography#1{\immediate\write\auxwrite@ + {\string\bibdata{#1}}% + \immediate\openin\bbl@=\jobname.bbl +"2 + \ifeof\bbl@ + \W@{No .bbl file}% +"2 + \else + \immediate\closein\bbl@ + \begingroup + \input bibtex + \input\jobname.bbl + \endgroup + \fi} +"2 +** +Putting this all together, we have +\C** +\def\UseBibTeX{\immediate\openout\auxwrite@=\jobname.aux +"2 + \let\cite=\BTcite@ +"2 + \def\nocite##1{\immediate\write\auxwrite@ + {\noexpand\citation{##1}}}% +"2 + \def\bibliographystyle##1{\immediate\write\auxwrite@ + {\string\bibstyle{##1}}}% +"2 + \def\bibliography@W{Bibliography}% + \def\bibliography##1{% + \immediate\write\auxwrite@{\string\bibdata{##1}}% + \immediate\openin\bbl@=\jobname.bbl +"2 + \ifeof\bbl@ + \W@{No .bbl file}% +"2 + \else + \immediate\closein\bbl@ + \begingroup "8UBTBG"8 + \input bibtex + \input\jobname.bbl + \endgroup + \fi}% + } +** +We use *\string*'s rather than *\noexpand*'s (section +~\Sref{SACN}) +so that +no extra +spaces will appear in the *.aux* file, since \bibtex\ +doesn't seem to like that! + + +The definition of *\BTcite@* (compare the definition of *\cite* in the +previous chapter) leaves the parsing for commas to +*\BTcite@@"allowbreak..."allowbreak\BTcite@@*: +\C** +\def\BTcite@{% + \def\nextii@(##1)##2{% + {\rm[}\BTcite@@##2,\BTcite@@{\rm," }{##1\/}{\rm]}% + \immediate\write\auxwrite@{\string\citation{##2}}}% + \def\nextiii@##1{{\rm[}\BTcite@@##1,\BTcite@@\/{\rm]}% + \immediate\write\auxwrite@{\string\citation{##1}}}% + \def\next@{\ifx\next(\expandafter\nextii@ + \else\expandafter\nextiii@\fi}% + \futurelet\next\next@}% +** +Notice that *\nextii@*, used +in the case of an optional argument *(...)*, explicitly inserts a comma and +space (in the *\rm* font---see the small print note on page~\ref{RMCOMMA}). + *\BTcite@@...,\BTcite@@* + will be defined so that the comma and space is {\it +not\/} added after the final part of the argument. + +The definition of *\BTcite@@* +uses standard parsing methods. +For each individual `\*,*' combination in the argument `*#1,*' +we will call\linebreak + *\BTcite@@@{*\*}* followed by `*{\rm," }*', +{\it except for the last such\/} \, where the comma will simply +be dropped: +\C** +\def\BTcite@@#1,{\BTcite@@@{#1}\futurelet\next\BTcite@@@@} +\def\BTcite@@@@{\ifx\next\BTcite@@ + \expandafter\eat@\else{\rm, }\expandafter\BTcite@@\fi} +** + +Here +*\BTcite@@@* will basically be equivalent to +*\ref* + (compare the definition on page~\ref{DEFREF2}): +\C** +\catcode`\~=11 +\def\BTcite@@@#1{\nolabel@\cite{#1}\relax + \def\nextii@##1~##2\nextii@{##1}% + \csL@{#1}\expandafter\nextii@\Next@\nextii@\fi} +\catcode`\~=\active +** + + The *\nolabel@\cite{#1}\relax* + means that we will initially get an +error message or warning message +\setbox0\hbox{\} +** +No \label found for "box0. +** +which is reasonable, since a *\cite* is essentially like a *\ref*; +the label will be created when we have a *\bibitem* from the *.bbl* file. +As in \latex@, three passes will normally be required: +\list +\item First each *\cite* creates a *\citation* line in the *.aux* file. +\item Then \bibtex\ creates a *.bbl* file, with a *\bibitem* for +each key cited. When we \tex\ the file again, the *\bibitem*'s in the *.bbl* +file will be treated like *\label*'s, and write appropriate +information (forward references) +to the *.lax* file. +\item When we \tex\ the file yet again, these references will finally +be inserted. +\endlist + + +\small Because \bibtex\ makes \pagelabel{RMCOMMA} + *\cite{...}* work like *\ref{...}*, it is then not permissible +to say things like \pagelabel{OPARGCITE} +** +\cite{\bf ...} +** +Once can type +\setbox0\hbox{\$_{\text{1}}$} +\setbox1\hbox{\$_{\text{2}}$} +** +By {\bf\cite{"box0,"box1}} we have ... +** +to print something like \medskip +\centerline{By [{\bf3}, {\bf4}] we have \dots{}} +\medskip +\noindent +(*\rm* has been explicitly specified for +the brackets and comma +definitions), but +a change to the style file should be used if all citations are +supposed to be in *\bf*. +It is even possible to type something like +\setbox0\hbox{\} +** +By {\bf\cite(\it page~123){"box0}} we have ... +** +to print something like \medskip +\centerline{By [{\bf3}, {\it page~123\/}] we have \dots{}} +\medskip +\noindent +(there are no restrictions on the material occurring in the +optional argument). In the +definition of *\BTcite@* we typed *{##1\/}* in the definition of +*\nextii@* to allow for the fact that font change instructions might occur +in this argument. + +\andsmall If we have a multi-key *\cite*, +\setbox0\hbox{\$_{\text{1}}$} +\setbox1\hbox{\$_{\text{2}}$} +** +\cite{"box0,"box1,...} +** +then \$_{\text{1}}$ will give a warning message like +\setbox0\hbox{\$_{\text{1}}$} +** +Warning: No \label found for "copy0. +l.35 ... \cite{"copy0} +** +while +\$_{\text{2}}$ will give a warning message like +\setbox0\hbox{\$_{\text{2}}$} +** +Warning: No \label found for "copy0. +l.35 ... \cite{"copy0} +** +Although it would be nicer if we got a single message involving +\setbox0\hbox{\$_{\text{1}}$} +\setbox1\hbox{\$_{\text{2}}$} +** +l.35 ... \cite{"box0,"box1,...} +** +this doesn't really seem worth worrying about. +\endsmall + +The *.bbl* file will have *\bibitem*'s, but the definition of *\bibitem* + is found only in +the file *bibtex.tex*. However, we will state +\C** +\let\newblock=\relax +** +even though *\newblock* occurs only in the *.bbl* file that is read in after +the *bibtex.tex* file; the reason for this is that different styles might +want to change the definition of *\newblock*. (Many \latex\ style files +define *\newblock* to be *\hskip.11em plus.33em minus.07em*, but the default +\lamstex\ style leaves no extra space between various parts of a +bibliographical entry.) + +Similarly, we define a default routine +\C** +\def\beginthebibliography@#1{\rm "8BTHEBIB"8 + \setbox0\hbox{#1\ }\bibindent@=\wd0 + \bigbreak + \centerline{\smc\bibliography@W}% + \nobreak\medskip + \sfcode`\.=1000 \everypar{}\parindent=0pt} +** +which will be used by the +** +\begin{thebibliography} +** +that occurs in the *.bbl* file; style files can redefine this, +to produce different sorts of formatting for the information in the *.bbl* +file. + +\section{The {\tt bibtex.tex} file} The file *bibtex.tex* is read in right +before the *.bbl* file; its purpose is to make sense out of the various +\latex\ macros that are going to appear. + +The file begins +with +\CC** +%\input cd.tox +"2 +%\input islands.tox +"2 +%\input bib.tox +"2 +%\input alignat.tox +"2 +%\input lists.tox +"2 +%\input cardord.tox +"2 +%\input anynum.tox +"2 +%\input dblacc.tox +"2 +%\input literal.tox +** +(As in section~\Sref{GENDEFS}, we are using double horizontal lines for +code that is in the subsidiary file *bibtex.tex*, rather than in +*lamstex.tex* itself). +Although these +lines are commented out, it might be wise to uncomment them, +if it turns out that adding the extra material from *bibtex.tex* unduly +strains the implementation of \tex\ that is being used. + +This is followed by +\CC** +\catcode`\@=11 +\let\alloc@=\alloc@@ +** +since we will be using a *\newcount* and *\newdimen* +(compare page~\ref{NEWALLOC}). + +Next we have to deal with the fact that the *.bbl* file usually begins +with things like +** +\newcommand{\noopsort}[1]{} +\newcommand{\printfirst}[2]{#1} +** +and perhaps there will be *\newcommand*'s for control sequences without +arguments also. So we have to interpret *\newcommand* correctly. + +For a situation like +\Litbox0=** +\newcommand{\foo}{bar} +** +$$\box0 \tag"\style{\bf A}"$$ +where a control sequence *\foo* without arguments is being defined, we +can simply let +*\newcommand#1* mean *\define#1*. But the general case is more complicated. + +First we define *\args@* so that *\args@1* makes *\toks@* be the token list +*##1*, and *\args@2* makes *\toks@* be the token list *##1##2*, etc\.~(we +want the double *##*'s because *\toks@* will then be used within an *\edef*). +The definition looks pretty strange, +\CC** +\def\args@#1{\count@=1 \toks@={}% + \loop + \edef\next@{\toks@={\the\toks@########\number\count@}}% + \next@ + \ifnum\count@<#1 \advance\count@ by 1 + \repeat} +** +because we have the {\it octuplet\/} *########*, even though we want to +end up with only a pair *##*. The reason we need this octuplet is +that the *\loop...\repeat* construction (section~\Sref{LOOP}) +defines *\iterate* in terms of `*...*'; +when this definition is made, + the octuplet *########* then coalesces into a quadruplet +*####* (unfortunately, even the redefinition of *\loop...\repeat* doesn't get +around {\it this\/} problem), + and then the *\edef* turns this quadruplet into a pair *##*. + + +Now that *\args@* is defined, a situation like +** +\newcommand{\foo}[2]{...} +** +can be taken care of with +\Litbox0=** +\def\newcommand#1[#2]{\args@#2 + \edef\next@{\noexpand\define\noexpand#1\the\toks@} + \next@} +** +$$\vcenter{\box0}\tag"\style{\bf B}"$$ +For example, +** +\newcommand{\switchargs}[2]{#2#1} +** +first uses *\args@2* to make *\toks@* be the token list *##1##2*. +Then the *\edef* makes *\next@* be +** +\define\switch#1#2 +** +so we end up with +** +\define\switch#1#2{#2#1} +** + +For the general case we must use +\CC** +\def\newcommand#1{\def\nextiv@{#1}% + \def\nextii@[##1]{\args@##1% + \edef\next@{\noexpand\define\expandafter\noexpand\nextiv@ + \the\toks@}% + \next@}% + \def\nextiii@{\edef\next@{\noexpand\define + \expandafter\noexpand\nextiv@}\next@}% + \def\next@{\ifx\next[\expandafter\nextii@\else\expandafter + \nextiii@\fi}% + \futurelet\next\next@} +** +Thus, we first save *#1* in *\nextiv@*, and then use a *\futurelet* to +see if the next token is *[*. If it is, + we use *\nextii@*, whose definition is +based on ({\bf B}), except that +we need +** +\expandafter\noexpand\nextiv@ +** +to get back the *\noexpand#1* (compare pages~\ref{EXNE} and ~\ref{EXNE2}). + If the next token isn't *[*, then we use +*\nextiii@*, based on ({\bf A}), again +using +** +\expandafter\noexpand\nextiv@ +** +to get back the *\noexpand#1*. + + +We also need to replicate the definitions of several special commands +from \latex: +\CC** +\def\em{\ifdim\fontdimen1 \the\font>0pt \rm\else\it\fi} +\def\mbox{\leavevmode\hbox} +** +(The actual definition of *\mbox* in \latex\ is +** +\def\mbox#1{\leavevmode\hbox{#1}} +** + but the above definition works +just as well [and even allows category changes, if that matters].) + + +To deal with the various items of the bibliography, we will need a new +counter +\CC** +\newcount\bibitemcount@ +** +for automatically numbered items, and a dimension +\CC** +\newdimen\bibindent@ +** +for the hanging indentation of items. + +A *\bibitem*, which is written by \bibtex@, might have an ``optional +argument'' *[...]*, so we will need maneuvers similar to that for +*\newcommand*. +The case +\setbox0\hbox{\} +** +\bibitem[...]{"copy0} +** +will call +** +\bibitem@{...}{"copy0} +** +while the case +** +\bibitem{"copy0} +** +without the optional argument will call +** +\bibitem@{\number\bibitemcount@}{"copy0} +** +where *\bibitem@#1#2* takes care of making the \ *#2* +act like a *\label* with +the value *#1*, and then printing *#1* at the beginning of the +bibliographical data that follows: +\CC** +\def\bibitem{% + \def\nextii@[##1]##2{\bibitem@{##1}{##2}}% + \def\nextiii@##1{\global\advance\bibitemcount@ by 1 + \bibitem@{\number\bibitemcount@}{##1}}% + \def\next@{\ifx\next[\expandafter\nextii@\else + \expandafter\nextiii@\fi}% + \futurelet\next\next@}% +** + +In order for *\bibitem@#1#2* to make *#2* act like a *\label* with +the value *#1*, we simply have to +** +{\def\thelabel@{#1} + \let\thelabel@@=\empty \let\thelabel@@@=\empty + \let\thelabel@@@@=\empty + \label{#2}} +** +---remember that *\label{...}* will always make sense when *\thelabel@* is +defined, and will record the value of this label in terms of +*\thelabel@*, \dots, *\thelabel@@@@* (we only care about *\thelabel@*, +since it is used for *\ref*, the only thing used by *\cite*). + +And then we start the bibliographic entry with +** +\par\hangafter 1 \hangindent=\bibindent@ +\noindent@\hbox to\bibindent@{#1\hfil}\ignorespaces +** +So the definition is +\CC** +\def\bibitem@#1#2{% + {\def\thelabel@{#1}% + \let\thelabel@@=\empty \let\thelabel@@@=\empty + \let\thelabel@@@@=\empty + \label{#2}}% + \par + \hangafter1 \hangindent=\bibindent@ + \noindent@\hbox to\bibindent@{#1\hfil}\ignorespaces} +** + +Finally, as soon as we hit the +** +\begin{thebibliography}{...} +** +we want everything to be properly set up. Hopefully, this is the only +*\begin* that will occur in the *.bbl* file. +So we give an error message in any other case: +\CC** +\def\begin#1#2{% + \def\next@{#1}\def\nextii@{thebibliography}% + \ifx\next@\nextii@ + \beginthebibliography@{#2}% + \else + \Err@{I can't deal with \string\begin{#1}}% + \fi} +** +Recall that *\beginthebibliography@* (page~\ref{BTHEBIB}) prints the heading, +and sets everything else up properly. + + +At the very end of the file we will encounter +** +\end{thebibliography} +** +Again, hopefully this is the only *\end* that will occur in the *.bbl* +file, and we define +\CC** +\def\end#1{% + \def\next@{#1}\def\nextii@{thebibliography}% + \ifx\next@\nextii@ + \else + \Err@{I can deal with \string\end{#1}}% + \fi} +** +(The fact that we are redefining *\end* isn't important, since the +definitions of *bibtex.tex*, together with the *.bbl* file are all read in +within a *\begingroup"allowbreak..."allowbreak\endgroup* region +(page~\ref{UBTBG}.) + +Finally, we reassign *\alloc@* its original definition from *plain* \tex@, +and make *@* active: +\CC** +\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne + \ch@ck#1#4#2\allocationnumber=\count1#1 + \global#3#5=\allocationnumber + \wlog{\string#5=\string#2\the\allocationnumber}} +\catcode`\@=\active +** + + +\chapter \CS{purge}'ing and \CS{unpurge}'ing\endchapter +There's nothing mysterious about *\purge* and *\unpurge*---they simply +read in a *.tox* or *.tex* file: +\C** +\def\unpurge#1{\input #1\relax} +\def\purge#1{\input #1.tox\relax} +** + +Each *.toc* file clears up the memory space used for certain control sequence +definitions, +by redefining these control sequences. +Control sequences meant for the user (those without *@* in their names) +are set equal to *\undefined*, which \lamstex\ always keeps undefined, +so that their use will give an error message. On the other hand, +control sequences used internally by \lamstex\ (those with *@* in their +names) are simply set equal to *\relax*. For example, +the file +** +lists.tox +** +which eliminates everything for making lists, starts +(again, as in section~\Sref{GENDEFS}, we use double horizontal lines +for code in subsidiary files) +\CC** +\catcode`\@=11 +\let\listformatbi@=\relax + . . . +\let\listformtmi@=\relax + . . . +\let\listformatti@=\relax + . . . +\let\listformate@=\relax +** +thereby removing from memory the initial definitions +of section~\Sref{liststy}. + +Then, for the definitions in section~\Sref{liststy2}, we +\CC** +\expandafter\let\csname list@P1\endcsname=\relax + . . . +\expandafter\let\csname list@Q1\endcsname=\relax + . . . +** +We {\it don't\/} bother with counters like `*\list@C1*', or any thing else + created with a *\new...* construction, because it would create confusion +if we had to restore them in the *.tex* files---each *\newcount* construction +will use up another possibility for a counter, even if we happen to be using +the same name as before. *\newif* works differently, so flags +are set equal to *\relax*, and we also +\CC** +\let\list@@C=\relax + . . . +** +Intermingled with these redefinitions we also have +\CC** +\let\keeplisting=\undefined +\let\list=\undefined +\let\runinitem=\undefined + . . . +** +And at the very end we +make *@* active again, +\CC** +\catcode`\@=\active +** + +On the other hand, the file *lists.tex* essentially consists of all the +definitions for *\lists*, except for things like +** +\expandafter\newcount\csname list@C1\endcsname +** +that aren't removed by *lists.tox*. + + -- cgit v1.2.3