% TABLE OF CONTENTS % % COMMAND LIST ....................................... 2 % GENERAL CONVENTIONS .................................. 4 % COUNTERS, ETC. ....................................... 5 % USEFUL HACKS ......................................... 6 % \par AND \everypar ................................... 8 % SPACING / LINE AND PAGE BREAKING ..................... 9 % PROGRAM CONTROL STRUCTURE MACROS ..................... 12 % FILE HANDLING ........................................ 14 % ENVIRONMENT COUNTER MACROS ........................... 16 % PAGE NUMBERING ....................................... 18 % CROSS REFERENCING MACROS ............................ 19 % ENVIRONMENTS ......................................... 20 % MATH ENVIRONMENTS .................................... 21 % RAGGEDRIGHT, CENTER, FLUSHRIGHT, FLUSHLEFT ........... 22 % EXAMPLE ............................................. 23 % THE LIST ENVIRONMENT ................................. 24 % ITEMIZE AND ENUMERATE ................................ 28 % BOXES ................................................ 30 % THE TABBING ENVIRONMENT .............................. 33 % ARRAY AND TABULAR ENVIRONMENTS ....................... 37 % THE PICTURE ENVIRONMENT .............................. 42 % THEOREM ENVIRONMENTS ................................. 49 % LENGTHS .............................................. 51 % TABLE OF CONTENTS, ETC. .............................. 52 % INITIAL DECLARATION COMMANDS ......................... 53 % INDEX COMMANDS ....................................... 54 % BIBLIOGRAPHY ......................................... 55 % DEBUGGING AND TEST INITIALIZATIONS ................. 56 % OUTPUT ............................................... 58 \catcode`\~=13 \def~{\penalty\@tenthou \ } \catcode`\@=11 % **************************************** % * COMMAND LIST * % **************************************** % % DECLARATIONS: % PREAMBLE: \nofiles \pagelayout \documentstyle \includeonly % \makeindex \makeglossary % IN DOCUMENT : % FONT SELECTION: % SIZE: \normal \small \footnotesize \scriptsize \scriptscriptsize % \big \Big \BIG % STYLE: \bf \it \rm \sl \ss \tt \mit[math mode only] % STYLE: % PAGE: [all global] \pagestyle \thispagestyle \pagenumbering \head % MISC: \raggedright \thicklines \thinlines % PARAMETER: \setlength \settowidth \addtolength \setcounter \addtocounter % NEW: \newlength \newtheorem \newcommand % MISC: \savebox \sbox \obeycr \restorecr % % ENVIRONMENTS: % ? -> PAR: document % PAR -> PAR: list enumerate itemize description % center flushright flushleft % example picture[inner] float[inner] % PAR -> BOX: tabular tabbing % PAR -> MATH: math displaymath equation % MATH -> MATH: array % ANY -> PAR: minipage[inner] % ANY -> BOX: stack % % TEXT-PRODUCING: % WITH TEXT ARGUMENT: % ANY -> BOX: \makebox \mbox \framebox \fbox \dashbox % \shortstack \footnotemark \cite[] \raisebox % ANY -> PAR: \parbox[inner] % PAR -> PAR: \chapter \section ... \footnote[inner] \footnotetext[inner] % MATH: \sqrt \underline \overline % PICTURE: \put \multiput % LIST: \item % WITHOUT TEXT ARGUMENT: % ANY MODE: % SYMBOLS: \$ \{ \} \← \@ \& \# % ACCENTS: See TeXbook % OTHER: \rule \ref \pageref \today \usebox \typein \input \cite % MATH: \over % PAR MODE: \include \bibliography \tableofcontents \listoffigures ... % LIST: \item \arabic \roman \Roman \alph \Alph % PICTURE: \line \vector \circle \oval % ARRAY & TABULAR: \hline \vline % % SPACING & BREAKING: % ANY : \hfill \hspace \hspacer % PAR : \newpage \newpage \vspace \vspacer \noindent % PAR & INNER MATH % : \newpage \clearpage \cleardoublepage % : \pagebreak \nopagebreak \linebreak \nolinebreak \newline % MATH : \over \; \, \! % MULTILINE : \\ % TABBING : \pushtab \poptab \> \< \+ \- \kill ... % ARRAY & TABULAR % : \multicolumn \noalign % % NO DIRECT CHANGES TO DOCUMENT: % \index \glossary \typeout \label \tableentry \stop \writecommand % % PARAMETERS: % % \columnsep \footinsertskip \intextsep % \columnseprule \footruleheight \oddsidemargin % \columnwidth \footruleshift \textfloatsep % \evensidemargin \footsep \textheight % \floatsep \headheight \textwidth % \footheight \headsep \topmargin % ALPHABETIZED LIST: % % ORDINARY COMMANDS: % % \Alph \include \parbox % \Roman \index \put % \\ \item \raisebox % \alph \label \ref % \appendix \line \roman % \arabic \linebreak \rule % \bibliography \listoffigures \section % \chapter \listoftables \shortstack % \circle \makebox \stop % \cite \mbox \subsection % \cite \multicolumn \subsubsection % \cleardoublepage \multiput \tableentry % \clearpage \tableofcontents % \dashbox \newline \today % \fbox \newpage \typein % \footnotemark \noindent \typeout % \footnotetext \nolinebreak \usebox % \framebox \nopagebreak \vector % \glossary \oval \vline % \hline \pagebreak \vspace % \hspace \pageref \writecommand % % % ENVIRONMENTS & DECLARATIONS: % % For each of these commands, the same command name prefixed by 'end' % is also reserved--e.g., \enddocument. % % \BIG \footnotesize \pagestyle % \Big \head \picture % \addtocounter \includeonly \raggedright % \addtolength \itemize \restorecr % \array \list \savebox % \big \makeglossary \sbox % \center \makeindex \scriptscriptsize % \description \math \scriptsize % \displaymath \minipage \setcounter % \document \newcommand \setlength % \documentstyle \newlength \settowidth % \enumerate \newtheorem \small % \equation \nofiles \stack\tabbing % \example \normal \tabular % \float \obeycr \thicklines % \flushleft \pagelayout \thinlines % \flushright \pagenumbering \thispagestyle % % % PARAMETERS : % % \columnsep \footinsertskip \intextsep % \columnseprule \footruleheight \oddsidemargin % \columnwidth \footruleshift \textfloatsep % \evensidemargin \footsep \textheight % \floatsep \headheight \textwidth % \footheight \headsep \topmargin % % % TABBING COMMANDS: % % These commannds are defined only within a tabbing environment. % % \kill \> \- % \pushtab \< \= % \poptab \+ % **************************************** % * GENERAL CONVENTIONS * % **************************************** % % SAVED VERSIONS OF TeX PRIMITIVES: % % The TeX primitive \foo is saved as \@@foo . The following primitives % are handled in this way: \let\@@par=\par \let\@@relax=\relax \let\@@input=\input \let\@@end=\end % SAVED VERSIONS OF TeX PARAMETERS % % \normalbaselineskip and \normallineskip hold the % normal values of \baselineskip and \lineskip % Any font-changing commands that change the normal value of \lineskip % and \baselineskip should change their saved values. % **************************************** % * COUNTERS, ETC. * % **************************************** % % \@zero : A dimen of zero points. It's more efficient to write % \parindent\@zero than \parindent 0pt. % \@tenthou : A count with value 10000. % \@sss : A skip of 0pt plus 1fill minus 1fill. % \@flushglue : Glue used for \right- & \leftskip to = 0pt plus 1fil % Redefine PLAIN.TEX macros not to be \outer \def\newcount{\alloc@0\count\countdef\insc@unt} \def\newdimen{\alloc@1\dimen\dimendef\insc@unt} \def\newskip{\alloc@2\skip\skipdef\insc@unt} \def\newbox{\alloc@4\box\chardef\insc@unt} \def\newwrite{\alloc@7\write\chardef\sixt@@n} \newwrite\@unused \newcount\@tempcnta \newcount\@tempcntb \newif\if@tempswa\@tempswatrue \newdimen\@zero \@zero = 0pt \newdimen\@tempdima \newdimen\@tempdimb \newbox\@tempboxa \newcount\@tenthou \@tenthou = 10000 \newskip\@sss \@sss = 0pt plus 1fill minus 1fill \newskip\@flushglue \@flushglue = 0pt plus 1fil \newskip\@tempskipa \newtoks\@temptokena % **************************************** % * USEFUL HACKS * % **************************************** % % \@latexerror{MSG} : Types 'LaTeX Error: MSG.' and halts. % \@namedef{NAME} : Expands to \def\NAME , except name can contain any % characters. % \@nameuse{NAME} : Expands to \NAME . % % \@ifnextchar X{YES}{NO} % : Expands to YES if next character is an 'X', % and to NO otherwise. (Uses temps a-c.) % NOTE: GOBBLES ANY SPACE FOLLOWING IT. % \@ifundefined{NAME}{YES}{NO} % : If \NAME is undefined then it executes YES, % otherwise it executes NO. More precisely, % true if \NAME either undefined or = \relax. % \@ifdefinable \NAME {YES} % : Executes YES if the user is allowed to define \NAME, % otherwise it gives an error. The user can define \NAME % if \@ifundefined{NAME} is true, 'NAME' /= 'relax' % and the first three letters of 'NAME' are not % 'end'. % \newcommand{\FOO}[i]{TEXT} % : User command to define \FOO to be a macro with % i arguments (i = 0 if missing) having the definition % TEXT. % \@car T1 T2 ... Tn\@nil == T1 (unexpanded) % % \@cdr T1 T2 ... Tn\@nil == T2 ... Tn (unexpanded) % % \typeout{message} : produces a warning message on the terminal % % \@warning{message}: prints 'LaTeX Warning: message.' % % \typein{message} : Types message, asks the user to type in a command, then % executes it \newwrite\@unused \def\typein#1{\typeout{#1}\read0 to\@typein\@typein\ifhmode \unskip\fi} \def\typeout#1{\immediate\write\@unused{}\message{#1}} \def\@warning#1{\typeout{LaTeX Warning: #1.}} \def\@namedef#1{\expandafter\def\csname #1\endcsname} \def\@nameuse#1{\csname #1\endcsname} \def\@car#1#2\@nil{#1} \def\@cdr#1#2\@nil{#2} % \@carcube T1 ... Tn\@nil = T1 T2 T3 , n > 3 \def\@carcube#1#2#3#4\@nil{#1#2#3} \def\@latexerr#1{\errmessage{LaTeX Error: #1}} \def\newcommand#1{\@ifnextchar [{\@argdef#1}{\@argdef#1[0]}} \long\def\@argdef#1[#2]#3{\@ifdefinable #1{\@tempcnta#2\relax \edef\@tempa{\long\def#1}\@tempcntb 1 \let\@tempb\relax\@whilenum\@tempcnta>0 \do{\edef\@tempa{\@tempa\@tempb\the\@tempcntb}\advance\@tempcntb 1 \advance \@tempcnta -1}\let\@tempb##\@tempa{#3}}} \def\@ifdefinable #1#2{\edef\@tempa{\expandafter\@cdr\string #1\@nil} \@ifundefined{\@tempa}{\edef\@tempb{\expandafter\@carcube \@tempa xxxx\@nil}% \ifx \@tempb\@qend \@notdefinable\else \ifx \@tempa\@qrelax \@notdefinable\else #2\fi\fi}{\@notdefinable}} \def\@notdefinable{\@latexerr{Reusing command name '\@tempa'}} \def\@ifundefined#1#2#3{\expandafter\ifx\csname #1\endcsname\relax#2\else#3\fi} % The following define \@qend and \@qrelax to be the strings 'end' and % 'relax' with the characters \catcoded 12. \edef\@qend{\expandafter\@cdr\string\end\@nil} \edef\@qrelax{\expandafter\@cdr\string\relax\@nil} % \@ifnextchar X{YES}{NO} % BEGIN % \@tempe := X % uses \let % \@tempa := YES % \@tempb := NO % \futurelet\@tempc % \@ifnch % END % % \@ifnch == % BEGIN % if \@tempc = blank space % then \@tempd := def(\@xifnch) % else if \@tempc = \@tempe % then \@tempd := def(\@tempa) % else \@tempd := def(\@tempb) % fi % fi % \@tempd % END % % \@xifnch == % BEGIN % gobble blanks % \futurelet\@tempc % \@ifnch % END % \def\@ifnextchar#1#2#3{\let\@tempe #1\def\@tempa{#2}\def\@tempb{#3}\futurelet \@tempc\@ifnch} \def\@ifnch{\ifx \@tempc \@sptoken \let\@tempd\@xifnch \else \ifx \@tempc \@tempe\let\@tempd\@tempa\else\let\@tempd\@tempb\fi \fi \@tempd} \def\:{\let\@sptoken= } \: % this makes \@sptoken a space token \def\:{\@xifnch} \expandafter\def\: {\futurelet\@tempc\@ifnch} % **************************************** % * \par AND \everypar * % **************************************** % % There are two situations in which \par may be changed: % % - Long-term changes, in which the new value is to remain in effect % until the current environment is left. The environments that % change \par in this way are the following: % % * All list environments (itemize, quote, etc.) % * Environments that turn \par into a noop: % tabbing, array and tabular. % % - Temporary changes, in which \par is restored to its previous value the % next time it is executed. The following are all such uses. % * \@endparenv % * The mechanism for avoiding page breaks and getting the % spacing right after section heads. % % To permit the proper interaction of these two situations, long-term % changes are made by the following command: % \@setpar{VAL} : To set \par. It \def's \par and \@par to VAL. % Short-term changes are made by the usual \def\par commands. % The original values are restored after a short-term change % by the \@restorepar and \@restoreeverypar commands. % % NOTE: \@@par always is defined to be the original TeX \par. % % \everypar is changed only for the short term. Whenever \everypar % is set non-null, it should restore itself to null when executed. % The following commands change \everypar in this way: % * \item % * \@endparenv % % WARNING: Commands that make short-term changes to \par and \everypar % must take account of the possibility that the new commands and the % ones that do the restoration may be executed inside a group. In % particular, \everypar is executed inside a group whenever a new paragraph % begins with a left brace. The \@restore... operations are local to % the current group. Thus, if \everypar is redefined to do a % \@restoreeverypar, it could take several executions of \everypar before % the restoration 'holds'. This usually causes no problem. However, to % prevent the extra executions from doing harm, use a global switch % to keep anything harmful in the new \everypar from being done twice. % \def\@par{\let\par=\@@par\par} \def\@setpar#1{\def\par{#1}\def\@par{#1}} \def\@restorepar{\def\par{\@par}} % OBSOLETE COMMANDS: %\def\@seteverypar#1{\everypar{#1}\def\@everypar{#1}} %\def\@restoreeverypar{\everypar{\@everypar}} %\def\@everypar{\everypar{}} % ********************************************** % * SPACING / LINE AND PAGE BREAKING * % ********************************************** % % USER COMMANDS: % \nopagebreak[i] : i = 0,...,4. Default argument = 4. Puts a penalty % into the vertical list output as follows: % 0 : penalty = 0 % 1 : penalty = \@lowpenalty % 2 : penalty = \@medpenalty % 3 : penalty = \@highpenalty % 4 : penalty = 10000 % \pagebreak[i] : same as \nopagebreak except negatives of its penalty % \linebreak[i], \nolinebreak[i] : analogs of the above % \obeycr : defines == \\. % \restorecr : restores to its usual meaning. % % \\ : initially defined to be \newline % \\[LENGTH] : initially defined to be \vspace{LENGTH}\newline \def\nopagebreak{\@ifnextchar[{\@nopgbk}{\@nopgbk[4]}} \def\@nopgbk[#1]{\ifvmode \penalty \@getpen{#1}\else \@bsphack\vadjust{\penalty \@getpen{#1}}\@esphack\fi} \def\pagebreak{\@ifnextchar[{\@pgbk}{\@pgbk[4]}} \def\@pgbk[#1]{\ifvmode \penalty -\@getpen{#1}\else \@bsphack\vadjust{\penalty -\@getpen{#1}}\@esphack\fi} \def\nolinebreak{\@ifnextchar[{\@nolnbk}{\@nolnbk[4]}} \def\@nolnbk[#1]{\ifvmode \@nolnerr\else \@tempskipa\lastskip \unskip \penalty \@getpen{#1}\ifdim \@tempskipa >\@zero \hskip\@tempskipa\ignorespaces\fi\fi} \def\linebreak{\@ifnextchar[{\@lnbk}{\@lnbk[4]}} \def\@lnbk[#1]{\ifvmode \@nolnerr\else \@bsphack\penalty -\@getpen{#1}\@esphack\fi} \def\newline{\ifvmode \@nolnerr \else \hfil \penalty -\@tenthou\relax\fi} %{ BRACE MATCHING \def\\{\@ifnextchar[{\@newline}{\newline}} \def\@newline[#1]{\vspace{#1}\newline} \def\@nolnerr{\@latexerr{There's no line here}} \def\@getpen#1{\ifcase #1\relax 0 \or \@lowpenalty\relax \or \@midpenalty\relax \or \@highpenalty\relax \else \@tenthou \fi} % @nobreak : Switch used to avoid page breaks caused by \label after a section % heading, etc. It should be GLOBALLY set true after the \nobreak % and GLOBALLY set false by the next invocation of \everypar. % \newif\if@nobreak \@nobreakfalse % \@bsphack ... \@esphack % used by macros such as \index that want to be invisible -- i.e., % not leave any extra space when used in the middle of text. Such % a macro should begin with \@bsphack and end with \@esphack % The macro in question should not create any text, nor change the % mode. % % \@bsphack == % BEGIN % \dimen\@savsk := \lastskip % if hmode then \@savsf := \spacefactor fi % END % % \@esphack == % BEGIN % if hmode % then \spacefactor := \@savsf % if \dimen\@savsk > 0pt then \ignorespaces fi % fi % END % \newdimen\@savsk \newcount\@savsf \def\@bsphack{\@savsk\lastskip \ifhmode\@savsf\spacefactor\fi} \def\@esphack{\ifhmode\spacefactor\@savsf {}\ifdim \@savsk >\@zero\ignorespaces \fi \fi} % VERTICAL SPACING: % % The command \@addvskip{SKIP} is used to put a vertical skip of SKIP into % the document. \@addskip{S1} \@addskip{S2} is equivalent to % \addskip{maximum of S1, S2}. \addskip should be used only in vertical % mode. It does nothing if @nobreak = true % % Note: the argument of \@addskip must be a register--either a skip % or a dimension register--or - a register, as in -\fooreg. % % \@addvskip{SKIP} == % BEGIN % if @nobreak = true % else if \lastskip =0 % then \vskip SKIP % else if \lastskip < SKIP % then \vskip -\lastskip % \vskip SKIP % else if \SKIP < 0 and \lastskip >= 0 % then \vskip SKIP % fi % fi % fi % fi % END \def\@addvskip#1{\if@nobreak\else \ifdim \lastskip =\@zero \vskip #1 \else \@xaddvskip{#1}\fi\fi} \def\@xaddvskip#1{\ifdim \lastskip <#1 \vskip-\lastskip\vskip #1\else \ifdim #1<\@zero \ifdim \lastskip <\@zero\else \vskip #1\fi\fi\fi} \def\vspace#1{\ifvmode\vskip #1 \else \@bsphack\vadjust{\vskip #1}\@esphack\fi} \def\vspacer#1{\ifvmode\vbox{\vskip #1}\else \@bsphack\vadjust{\vbox{\vskip #1}}\@esphack\fi} % HORIZONTAL SPACE \def\hspace#1{\ \unskip\hskip #1} \def\hspacer#1{\ \unskip\hbox{\hskip #1}} % A PARAGRAPH ENVIRONMENT is one such that it is left in vertical mode -- % i.e., after a \par. The list environment is the prime example. % The LATEX convention is that, from the user's viewpoint, this environment % starts a new paragraph -- i.e., gets a full \parskip space above it -- % iff he leaves a blank space before the environment. If not, the % space left above is (1 - \topsepcorrection) * \parskip. % The text after the environment starts a new paragraph -- i.e., gets % a full \parskip space above it and a \parindent indentation if and % only if he leaves a blank line after the end of the paragraph environment. % Otherwise, the space above it is the same as at the beginning of the % environment, and there is no \parindent indentation. % % This is accomplished by starting the environment with a % \@beginparenv command and ending it with an \@endparenv command. % % \@beginparenv == % BEGIN % if vertical mode % then \topsep := 0pt % else \topsep := -\topsepcorrection * \parskip % fi % \par % \@addvskip{\topsep} % END % \@endparenv == % BEGIN % if horizontal mode then \par fi % \@addvskip{\topsep} % \endgroup %% ends the \begin commands \begingroup % \par == BEGIN % \@restorepar % \everypar{} % \par % \@addvskip{0 pt} %% remove any negative skip % END % \everypar == BEGIN \hskip - \parindent \everypar{} END % \begingroup %% to match the \end commands \endgroup % END \def\@beginparenv{\ifvmode \topsep\@zero \else \topsep -\topsepcorrection\parskip \fi \par\@addvskip\topsep} \def\@endparenv{\ifhmode\par\fi\@addvskip\topsep\endgroup \def\par{\@restorepar\everypar{}\par\@addvskip\@zero}% \everypar{\hskip -\parindent \everypar{}}\begingroup} {\catcode`\^^M=13 \gdef\obeycr{\catcode`\^^M=13 \def^^M{\\}\@gobblecr}\gdef\restorecr{\catcode`\^^M=5 }} %} BRACE MATCHING % ********************************************** % * PROGRAM CONTROL STRUCTURE MACROS * % ********************************************** % % \@whilenum TEST \do {BODY} % \@whiledim TEST \do {BODY} : These implement the loop % while TEST do BODY od % where TEST is a TeX \ifnum or \ifdim test, respectively. % They are optimized for the normal case of TEST initially false. % % \@whilesw SWITCH \fi {BODY} : Implements the loop % while SWITCH do BODY od % where SWITCH is a command defined by \newswitch. % Optimized for normal case of SWITCH initially false. % % \@for NAME := LIST \do {BODY} : Assumes that LIST expands to A1,A2, ... ,An . % Executes BODY n times, with NAME = Ai on the i-th iteration. % Optimized for the normal case of n = 1. Works for n=0. % % \@tfor NAME := LIST \do {BODY} % if, before expansion, LIST = T1 ... Tn where each Ti is a % token or {...}, then executes BODY n times, with NAME = Ti % on the i-th iteration. Works for n=0. % % NOTES: 1. These macros use no \@temp sequences. % 2. These macros do not work if the body contains anything that looks % syntactically to TeX like an improperly balanced \if \else \fi. % % \@whilenum TEST \do {BODY} == % BEGIN % if TEST % then BODY % \@iwhilenum{TEST \relax BODY} % END % % \@iwhilenum {TEST BODY} == % BEGIN % if TEST % then BODY % \@nextwhile = def(\@iwhilenum) % else \@nextwhile = def(\@whilenoop) % fi % \@nextwhile {TEST BODY} % END % % \@whilesw SWITCH \fi {BODY} == % BEGIN % if SWITCH % then BODY % \@iwhilesw {SWITCH BODY}\fi % fi % END % % \@iwhilesw {SWITCH BODY} \fi == % BEGIN % if SWITCH % then BODY % \@nextwhile = def(\@iwhilesw) % else \@nextwhile = def(\@whileswnoop) % fi % \@nextwhile {SWITCH BODY} \fi % END \def\@whilenoop#1{} \def\@whilenum#1\do #2{\ifnum #1\relax #2\relax\@iwhilenum{#1\relax #2\relax}\fi} \def\@iwhilenum#1{\ifnum #1\let\@nextwhile=\@iwhilenum \else\let\@nextwhile=\@whilenoop\fi\@nextwhile{#1}} \def\@whiledim#1\do #2{\ifdim #1\relax#2\@iwhiledim{#1\relax#2}\fi} \def\@iwhiledim#1{\ifdim #1\let\@nextwhile=\@iwhiledim \else\let\@nextwhile=\@whilenoop\fi\@nextwhile{#1}} \def\@whileswnoop#1\fi{} \def\@whilesw#1\fi#2{#1#2\@iwhilesw{#1#2}\fi\fi} \def\@iwhilesw#1\fi{#1\let\@nextwhile=\@iwhilesw \else\let\@nextwhile=\@whileswnoop\fi\@nextwhile{#1}\fi} % \@for NAME := LIST \do {BODY} == % BEGIN \@forloop expand(LIST),\@nil,\@nil \@@ NAME {BODY} END % % \@forloop CAR, CARCDR, CDRCDR \@@ NAME {BODY} == % BEGIN % NAME = CAR % if def(NAME) = def(\@nnil) % else BODY; % NAME = CARCDR % if def(NAME) = def(\@nnil) % else BODY % \@iforloop CDRCDR \@@ NAME \do {BODY} % fi % fi % END % % \@iforloop CAR, CDR \@@ NAME {BODY} = % NAME = CAR % if def(NAME) = def(\@nnil) % then \@nextwhile = def(\@fornoop) % else BODY ; % \@nextwhile = def(\@iforloop) % fi % \@nextwhile name cdr {body} % % \@tfor NAME := LIST \do {BODY} % = \@tforloop LIST \@nil \@@ NAME {BODY} % % \@tforloop car cdr \@@ name {body} = % name = car % if def(name) = def(\@nnil) % then \@nextwhile == \@fornoop % else body ; % \@nextwhile == \@forloop % fi % \@nextwhile name cdr {body} % \def\@nnil{\@nil} \def\@empty{} \def\@fornoop#1\@@#2#3{} \def\@for#1:=#2\do#3{\edef\@fortmp{#2}\ifx\@fortmp\@empty \else \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}\fi} \def\@forloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else #5\def#4{#2}\ifx #4\@nnil \else#5\@iforloop #3\@@#4{#5}\fi\fi} \def\@iforloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile=\@fornoop \else #4\relax\let\@nextwhile=\@iforloop\fi\@nextwhile#2\@@#3{#4}} \def\@tfor#1:=#2\do#3{\xdef\@fortmp{#2}\ifx\@fortmp\@empty \else \@tforloop#2\@nil\@nil\@@#1{#3}\fi} \def\@tforloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil \let\@nextwhile=\@fornoop \else #4\relax\let\@nextwhile=\@tforloop\fi\@nextwhile#2\@@#3{#4}} % **************************************** % * FILE HANDLING * % **************************************** % % THE FOLLOWING USER COMMANDS ARE DEFINED IN THIS PART: % \document : Reads in the .AUX files and \catcode's @ to 12. % \nofiles : Suppresses all file output by setting \@tfile false. % \includeonly{NAME1, ... ,NAMEn} % : Causes only parts NAME1, ... ,NAMEn to be read by % their \include commands. Works by setting \@partsw true % and setting \@partlist to NAME1, ... ,NAMEn. % \include{NAME} : Does an \input NAME unless \partsw is true and % NAME is not in \@partlist. If \@tfile is true, then % it directs .AUX output to NAME.AUX, including a % checkpoint at the end. % \input{NAME} : The same as TeX's \input, except it allows optional % braces around the file name. % % VARIABLES, SWITCHES AND INTERNAL COMMANDS: % \@mainaux : Output file number for main .AUX file. % \@partaux : Output file number for current part's .AUX file. % \@auxout : Either \@mainout or \@partout, depending on which .AUX % file output goes to. % \@input{foo} : If file foo exists, then \input's it, otherwise types % a warning message. % @tfile : Switch -- set false if no .TOC, .IDX etc files are to be % written. % @afile : Switch -- false if no .AUX files are to be written. % @partsw : Set true by a \includeonly command. % \@partlist : Set to the argument of the \includeonly command. % % \cp@FOO : The checkpoint for \included file FOO.TEX, written % by \@writeckpt at the end of file FOO.AUX % % \document == % BEGIN % \begingroup % \@input{\jobname.aux} % \endgroup % if \@afile = T % then open file \@mainaux for writing % write ``\relax''on file \@mainaux % fi % \begin == \@begin % END % % \includeonly{FILELIST} == % BEGIN % \@partsw := T % \@partlist := FILELIST % \@tfile := F % inhibit .TOC, etc. files % END % % \include{FILE} == % BEGIN % \clearpage % if \@afile = T % then \immediate\write\@mainaux{\string\@input{FILE.AUX}} % fi % if \@partsw = T % then \@tempswa := F % \@tempb == FILE % for \@tempa := \@partlist % do if eval(\@tempa) = eval(\@tempb) % then \@tempswa := T fi % od % fi % % if \@tempswa = T % then \@auxout := \@partaux % if \@afile = T % then \immediate\openout\@partaux{FILE.AUX} % \immediate\write\@partaux{\relax} % fi % \@input{FILE.TEX} % \clearpage % \@writeckpt{FILE} % \@auxout := \@mainaux % else \cp@FILE % fi % END % % \@writeckpt{FILE} == % BEGIN % if \@afile = T % \immediate\write on file \@partaux: % \gdef\cp@FILE{ %% } % for \@tempa := \cl@@ckpt % do \immediate\write on file \@partaux: % \string\setcounter{eval(\@tempa)}{eval(\c@eval(\@tempa))} % od %% { % \immediate\write on file \@partaux: } % fi % END % % INITIALIZATION % \@tempswa := T \newif\if@tfile \@tfiletrue \newif\if@afile \@afiletrue \newif\if@partsw \@partswfalse \newwrite\@mainaux \newwrite\@partaux \def\document{\begingroup\@input{\jobname.aux}\endgroup \if@afile \immediate\openout\@mainaux=\jobname.aux \immediate\write\@mainaux{\relax}\fi\normal\everypar{}\let\begin\@begin} \def\nofiles{\@tfilefalse\@afilefalse\typeout {No auxiliary output files.}\typeout{}} \def\@input#1{\openin1 #1 \ifeof1 \typeout {No file #1.}\else\closein1 \relax\@@input #1 \fi} \let\@auxout=\@mainaux \def\includeonly#1{\@partswtrue\def\@partlist{#1}\@tfilefalse} \def\include#1{\clearpage \if@afile \immediate\write\@mainaux{\string\@input{#1.AUX}}\fi \@tempswatrue\if@partsw \@tempswafalse\def\@tempb{#1}\@for \@tempa:=\@partlist\do{\ifx\@tempa\@tempb\global\@tempswatrue\fi}\fi \if@tempswa \if@afile \let\@auxout=\@partaux \immediate\openout\@partaux #1.AUX \immediate\write\@partaux{\relax}\fi\@input{#1.TEX}\clearpage \@writeckpt{#1}\let\@auxout=\@mainaux\else\@nameuse{cp@#1}\fi} \def\@writeckpt#1{\if@afile \immediate\write\@partaux{\string\global\string\@namedef{cp@#1}\@charlb}% \@for\@tempa:=\cl@@ckpt\do{\immediate\write\@partaux {\string\setcounter{\@tempa}{\the\@nameuse{c@\@tempa}}}}% \immediate\write\@partaux{\@charrb}\fi} \def\input{\@ifnextchar \bgroup{\@iinput}{\@@input }} \def\@iinput#1{\@@input #1 } % The following defines \@charlb and \@charrb to be { and }, respectively % with \catcode 11. {\catcode`[=1 \catcode`]=2 \catcode`{=11 \catcode`}=11 \gdef\@charlb[{] \gdef\@charrb[}] ]% }brace matching % **************************************** % * ENVIRONMENT COUNTER MACROS * % **************************************** % % An environment foo has an associated counter defined by the % following control sequences: % \c@foo : Contains the counter's numerical value. It is defined by % \newcount\foocounter. % \co@foo : Macro that expands to the printed value of \foocounter. % For example, if sections are numbered within chapters, % and section headings look like % Section II-3. The Nature of Counters % then \co@section might be defined by: % \def\co@section{\@Roman{\c@chapter}-\@arabic{\c@section}} % % NOTE: \co@foo MUST BE DEFINED IN SUCH A WAY THAT \edef\bar{\co@foo} % DEFINES \bar SO THAT IT WILL EVALUATE TO THE COUNTER VALUE AT THE TIME % OF THE \edef, EVEN AFTER \foocounter AND ANY OTHER COUNTERS HAVE BEEN % CHANGED. THIS WILL HAPPEN IF YOU USE THE STANDARD COMMANDS \@arabic, % \@Roman, ETC. % % \cl@foo : List of counters to be reset when foo stepped. Has format % countera,counterb,counterc. % % The following commands are used to define and modify counters. % \setcounter{FOO}{VAL} : Globally sets \foocounter equal to VAL. % \addtocounter{FOO}{VAL}: Globally increments \foocounter by VAL. % \newnumbering{FOO}{DEF}: Redefines \co@FOO to be DEF % \@stepcounter{FOO} : Globally increments counter \c@FOO % and resets all subsidiary counters. % \@refstepcounter{FOO} : Same a \@stepcounter, but it also defines % \@currentreference so that a subsequent % \label{bar} command causes \ref{bar} to % generate the current value of counter foo. % \@definecounter{FOO} : Initializes counter FOO (with empty reset list). % Also adds FOO to \cl@@ckpt -- the reset % list of a dummy counter @ckpt used for % taking checkpoints. % \@addtoreset{FOO}{BAR} : Adds counter FOO to the list of counters % \cl@BAR to be reset when counter bar is stepped. % % NUMBERING MACROS: % \arabic{COUNTER} : Representation of COUNTER as arabic numerals. % \roman{COUNTER} : Representation of COUNTER as lower-case % Roman numerals. % \Roman{COUNTER} : Representation of COUNTER as upper-case % Roman numerals. % \alph{COUNTER} : Representation of COUNTER as a lower-case % letter: 1 = a, 2 = b, etc. % \Alph{COUNTER} : Representation of COUNTER as an upper-case % letter: 1 = A, 2 = B, etc. % % THE ABOVE ARE IMPLEMENTED IN TERMS OF THE FOLLOWING: % \@arabic\FOOcounter : Representation of \FOOcounter as arabic numerals. % \@roman\FOOcounter : Representation of \FOOcounter as lower-case % Roman numerals. % \@Roman\FOOcounter : Representation of \FOOcounter as upper-case % Roman numerals. % \@alph\FOOcounter : Representation of \FOOcounter as a lower-case % letter: 1 = a, 2 = b, etc. % \@Alph\FOOcounter : Representation of \FOOcounter as an upper-case % letter: 1 = A, 2 = B, etc. \def\setcounter#1#2{\@ifundefined{c@#1}{\@nocnterr}% {\global\csname c@#1\endcsname#2\relax}} \def\addtocounter#1#2{\@ifundefined{c@#1}{\@nocnterr}% {\global\advance\csname c@#1\endcsname #2\relax}} \def\newnumbering#1#2{\@ifundefined{c@#1}{\@nocnterr}% {\@ifundefined{co@#1}{\@latexerr{\string\newnumbering\space of #1 illegal}}% {\@namedef{co@#1}{#2}}}} \def\@nocnterr{\@latexerr{No such counter}} \def\@stepcounter#1{\global\expandafter\advance\csname c@#1\endcsname 1 \@for\@tempa:=\csname cl@#1\endcsname\do{\setcounter\@tempa0 }} \def\cl@@ckpt{page} \def\@definecounter#1{\expandafter\newcount\csname c@#1\endcsname \setcounter{#1}0 \expandafter\gdef\csname cl@#1\endcsname{}\@addtoreset {#1}{@ckpt}} \def\@addtoreset#1#2{\expandafter\ifx\csname cl@#2\endcsname \@empty \expandafter\xdef\csname cl@#2\endcsname{#1}\else \expandafter\xdef\csname cl@#2\endcsname {\csname cl@#2\endcsname ,#1}\fi} % Numbering commands for \newnumbering and \list arguments \def\arabic#1{\@arabic{\@nameuse{c@#1}}} \def\roman#1{\@roman{\@nameuse{c@#1}}} \def\Roman#1{\@Roman{\@nameuse{c@#1}}} \def\alph#1{\@alph{\@nameuse{c@#1}}} \def\Alph#1{\@Alph{\@nameuse{c@#1}}} \def\@arabic#1{\ifnum #1>0 \number #1\fi} \def\@roman#1{\romannumeral #1} \def\@Roman#1{\expandafter\uppercase\expandafter{\romannumeral #1}} \def\@alph#1{\ifcase#1\or a\or b\or c\or d\else\@ialph{#1}\fi} \def\@ialph#1{\ifcase#1\or \or \or \or \or e\or f\or g\or h\or i\or j\or k\or l\or m\or n\or o\or p\or q\or r\or s\or t\or u\or v\or w\or x\or y\or z\else\@ctrerr\fi} \def\@Alph#1{\ifcase#1\or A\or B\or C\or D\else\@Ialph{#1}\fi} \def\@Ialph#1{\ifcase#1\or \or \or \or \or E\or F\or G\or H\or I\or J\or K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or Y\or Z\else\@ctrerr\fi} \def\@ctrerr{\@latexerr{Counter too large}} % **************************************** % * PAGE NUMBERING * % **************************************** % % Page numbers are produced by a page counter, used just like any other % counter. The only difference is that \c@page contains the number of % the next page to be output (the one currently being produced), rather % than one minus it. Thus, it is normally initialized to 1 rather than % 0. \c@page is defined to be \count0, rather than a count assigned by % \newcount. % % The user sets the pagenumber style with the \pagenumbering{FOO} % command, which sets \pagecounter to 1 and defines \co@page to be % \FOO. For example, \pagenumbering{roman} causes pages to be numbered % i, ii, etc. The command \newnumbering{page}{...} can be used % to get fancier page numbers, like -ii-. \countdef\c@page=0 \def\cl@page{} \def\pagenumbering#1{\global\c@page1 \gdef\co@page{\csname @#1\endcsname \c@page}} % **************************************** % * CROSS REFERENCING MACROS * % **************************************** % % The user writes \label{foo} to define the following cross-references: % \ref{foo} : value of most recently incremented referencable counter. % in the current environment. (Chapter, section, theorem % and enumeration counters counters are referencable, % footnote counters are not.) % \pageref{foo} : page number at which \label{foo} command appeared. % where foo can be any string of characters not containing '\', '{' or '}'. % % Note: The scope of the \label command is delimited by environments, so % \begin{theorem} \label{foo} ... \end{theorem} \label{bar} % defines \ref{foo} to be the theorem number and \ref{bar} to be % the current section number. % % Note: \label does the right thing in terms of spacing -- i.e., % leaving a space on both sides of it is equivalent to leaving % a space on either side. % % This is implemented as follows. A referencable counter CNT is % incremented by the command \@refstepcounter{CNT} , which sets % \@currentlabel == {CNT}{eval(\co@CNT)}. The command % \label{FOO} then writes the following on file \@auxout : % \newlabel{FOO}{{eval(\@currentlabel)}{eval(\co@page)}} % % \ref{FOO} == % BEGIN % if \r@foo undefined % then ?? % Warning: 'reference foo on page ... undefined' % else \@car \eval(\r@FOO)\@nil % fi % END % % \pageref{foo} = % BEGIN % if \r@foo undefined % then ?? % Warning: 'reference foo on page ... undefined' % else \@cdr \eval(\r@FOO)\@nil % fi % END % \def\ref#1{\@ifundefined{r@#1}{{\bf ??}\@warning {Reference #1 on page \co@page \space undefined}}{\edef\@tempa{\@nameuse{r@#1}}\expandafter \@car\@tempa \@nil}} \def\pageref#1{\@ifundefined{r@#1}{{\bf ??}\@warning {Reference #1 on page \co@page \space undefined}}{\edef\@tempa{\@nameuse{r@#1}}\expandafter \@cdr\@tempa\@nil}} \def\label#1{\@bsphack\if@afile {\let\co@page\relax \xdef\@gtempa{\write\@auxout{\string \newlabel{#1}{{\@currentlabel}{\co@page}}}}}\@gtempa \if@nobreak \ifvmode\nobreak\fi\fi\fi\@esphack} \def\newlabel#1#2{\@ifundefined{r@#1}{}{\@warning{Label '#1' multiply defined}}\global\@namedef{r@#1}{#2}} \def\@refstepcounter#1{\@stepcounter{#1}\edef\@currentlabel{\@nameuse{co@#1}}} \def\@setcurrentlabel{} % For \label commands that come before any environment % **************************************** % * ENVIRONMENTS * % **************************************** % % \begin{foo} and \end{foo} are used to delimit environment foo. % \begin{foo} starts a group and calls \foo if it is defined, otherwise % it does nothing. \end{foo} checks to see that it matches the % corresponding \begin and if so, it calls \endfoo and does an % \endgroup. Otherwise, \end{foo} does nothing. % % If \end{foo} needs to ignore blanks after it, then \endfoo should % globally set the @ignore switch true with \global\@ignoretrue. % % The ordinary LaTeX definition of \end is saved as \@end, and is % restored by each \begin. Some envionments, notably \array and % \tabular, need the \end... command executed immediately, before % checking that it correctly matches the \begin. These environments % must redefine \end. The redefined environment should call % \@checkend to check the proper matching, and then do an \endgroup. % % Note: \begin is defined so that the first time it is called it % expects to see a \begin{document} and leads to an error % otherwise. % % \@currenvir : the name of the current environment % % NOTE: \@@end is defined to be the \end command of TeX82. % % \enddocument is the user's command for ending the manuscript file. % % \stop is a panic button -- to end TeX in the middle. % \def\@currenvir{document} \newif\if@ignore \def\enddocument{\stop} \def\stop{\clearpage\@@end} \def\begin#1{\def\@tempa{#1}\ifx\@currenvir\@tempa \def\enddocument{\fi\stop} \document \else\@nodocument\fi} \def\@nodocument{\@latexerr{Missing \string\begin{\@currenvir}}} \everypar{\@nodocument} %% To get an error if text appears before the \nullfont %% \begin{document} \def\@begin#1{\@ifundefined{#1}{\let\@tempa\relax\@latexerr {Environment #1 undefined}}{\begingroup \let\end\@end \def\@currenvir{#1}\def\@tempa{\csname #1\endcsname}}\@tempa} \def\end#1{\global\@ignorefalse\def\@tempa{#1}\ifx \@tempa\@currenvir \csname end#1\endcsname \endgroup \if@ignore \ignorespaces\fi\else \@badend{#1}\fi} \let\@end=\end \def\@checkend#1{\def\@tempa{#1}\ifx \@tempa\@currenvir \else\@badend{#1}\fi} \def\@badend#1{\@latexerr{\string\begin{\@currenvir} ended by \string\end{#1}}} % ********************************************** % * MATH ENVIRONMENTS * % ********************************************** % % \( == BEGIN if math mode % then error: '\( in math mode' % else $ % fi % END % % \) == BEGIN if math mode % then if inner mode % then $ % else error ``\[ closed with \)'' % else error 'unmatched \)' % fi % END % % \[ == BEGIN if math mode % then error: '\[ in math mode' % else $$ % fi % END % % \] == BEGIN if math mode % then if inner mode % then error '\( closed with \]' % else $$ % else error 'unmatched \]' % fi % END % % \equation == BEGIN \@refstepcounter{equation} $$ END % % \endequation == BEGIN \eqno (\co@equation) $$\ignorespaces END % % NOTE: The document style must define \co@equation etc., and do % the appropriate \@addtoreset. It should also redefine \endequation % if another format for the equation number is desired other than the % standard (...). \def\({\ifmmode\@latexerr {\string\(\space in math mode}\else$%%$BRACE MATCH HACK \fi} \def\){\ifmmode\ifinner$\else\@latexerr %%$ BRACE MATCH HACK {\string\[\space closed with \string\)}\fi\else \@latexerr {Unmatched \string\)}\fi} \def\[{\ifmmode\@latexerr {\string\[\space in math mode}\else$$%%$$ BRACE MATCH HACK \fi} \def\]{\ifmmode\ifinner\@latexerr {\string\(\space closed with \string\]}\else$$\fi%%$$ BRACE MATCH HACK \else \@latexerr {Unmatched \string\]}\fi\ignorespaces} \let\math=\( \let\endmath=\) \let\displaymath=\[ \def\enddisplaymath{\]\global\@ignoretrue} \@definecounter{equation} \def\equation{$$ % $$ BRACE MATCHING HACK \@refstepcounter{equation}} \def\endequation{\eqno (\co@equation)% $$ BRACE MATCHING HACK $$\global\@ignoretrue} % ************************************************ % * RAGGEDRIGHT, CENTER, FLUSHRIGHT, FLUSHLEFT * % ************************************************ % % % \raggedright sets @raggedright switch to true, and sets % \rightskip. Other paragraphing environments should % check @raggedright to set up \rightskip and \leftskip appropriately. % Note: \raggedright changes \rightskip only if \leftskip=0pt, so it % doesn't mess things up if it appears inside a \flushleft environment. % % \center, \flushright and \flushleft set % \rightskip = 0pt or \@flushglue (as appropriate) % \leftskip = 0pt or \@flushglue (as appropriate) % \parindent = 0pt % \parfillskip = 0pt. % \\ == \par \vskip -\parskip % \\[LENGTH] == \\ \vskip LENGTH % As with all paragraphing environments, they use \@beginparenv % and \@endparenv. \def\raggedright{\@raggedrighttrue \ifdim\leftskip =\@zero\rightskip0pt plus 5em\fi} \newif\if@raggedright \@raggedrightfalse \def\@centercr{\par\@addvskip{-\parskip}\@ifnextchar [{\@icentercr}{\ignorespaces}} \def\@icentercr[#1]{\vskip #1\ignorespaces} \def\center{\@beginparenv \let\\=\@centercr\rightskip\@flushglue\leftskip\@flushglue \parindent\@zero\parfillskip\@zero\ignorespaces} \let\endcenter=\@endparenv \def\flushleft{\@beginparenv \let\\=\@centercr\rightskip\@flushglue\leftskip\@zero \parindent\@zero\parfillskip\@zero\ignorespaces} \let\endflushleft=\@endparenv \def\flushright{\@beginparenv \let\\=\@centercr\rightskip\@zero\leftskip\@flushglue \parindent\@zero\parfillskip\@zero\ignorespaces} \let\endflushright=\@endparenv % **************************************** % * EXAMPLE * % **************************************** % % This environment uses the fixed-width \tt font, turns blanks into spaces % and starts a new line for each . A blank line leaves a \baselineskip % space. % % redefined to \par, where \par redefined to \@par$ $ % No indentation % Space redefined to \space % {\catcode`\^^M=13 \gdef\@examsetcr{\catcode`\^^M=13 \let^^M=\@examcr}} \def\@examcr{\par\@addvskip{-\parskip}\indent} \def\@iexamcr[#1]{\vskip #1\indent\@gobblecr} {\catcode`\^^M=13 \gdef\@gobblecr{\@ifnextchar {\@gobble}{\ignorespaces}}} \def\@gobble#1{} \def\example{\@beginparenv % { BRACE MATCH HACK \def\\{\par\@addvskip{-\parskip}\@ifnextchar [{\@iexamcr}{\indent\@gobblecr}}% \rightskip\@zero\leftskip\@zero \parindent\@zero\parfillskip\@flushglue \@examsetcr\obeyspaces\tt\indent\@gobblecr} \let\endexample=\@endparenv % **************************************** % * THE LIST ENVIRONMENT * % **************************************** % % The generic commands for creating an indented environment -- enumerate, % itemize, quote, etc -- are % \list{LABEL}{COMMANDS} ... \endlist % which can be invoked by the user as the list environment. The LABEL % argument specifies item labeling. COMMANDS contains commands for % changing the horizontal and vertical spacing parameters. % % Each item of the environment is begun by the command: % \item[ITEMLABEL] : produces an item labeled by ITEMLABEL. If the % argument is missing, then the LABEL argument of the \list % command is used as the item label. The \arabic, \roman, etc. % commands can be used to number the item. For example, if % LABEL = (\alph), then an \item command for the third item of the % list produces the label (c). % % The macro \@everyitem is executed immediately before the item label % is generated--but before any text is inserted--on every \item WITH NO % EXPLICIT ARGUMENT. More precisely, the % order of execution is \@everyitem\xdef\...{\hbox{ITEMLABEL}}. One use for % this is to make definitions that appear at the current nesting level. % (Local definitions made by an ITEMlABEL vanish because the ITEMLABEL % appears inside an \hbox.) This is used by the enumerate environment for % setting \@currentlabel to make \label work for enumerations. % % When you leave a list environment, returning either to an enclosing % list or normal text mode, LaTeX begins a new paragraph if and only if % you leave a blank line after the \end command. This is accomplished % by the \@endparenv command. % % Blank lines are ignored every other reasonable place--i.e.: % - Between the \begin{list} and the first \item, % - Between the \item and the text of that item. % - Between the end of the last item and the \end{list}. % % For an environment like quotation, in which items are not labeled, % the entire environment is a single item. It is defined by % letting \quotation == \list{}{...}\item[]. (Note the [], there in % case the first character in the environment is a '['.) The spacing % parameters provide a great deal of flexability in designing the % format, including the ability to let the indentation of the first % paragraph be different from that of the subsequent ones. % % The following variables are used inside a list environment: % \@totalleftmargin : The distance that the prevailing left margin is % indented from the outermost left margin, % \linewidth : The width of the current line. Must be % initialized to \hsize. % item : A counter for doing item numbering -- contains % the number of the current item at an \@everyitem. % It is incremented only by an \item with no explicit % argument. % \@saveitem : A local counter to save the value of the item % counter upon entry to \list, and to restore it % on \endlist. % @inlabel : A switch that is false except between the time an % \item is encountered and the time the TeX actually % enters horizontal mode. Should be tested by % commands that can be messed up by the list % environment's use of \everypar. % \box\@labels : When @inlabel = true, it holds the labels % to be put out by \everypar. % @noparitem : A switch set by \list when @inlabel = true. % Handles the case of a \list being the first thing % in an item. % @newlist : Set true by \list, set false by the first \item's % text (by \everypar). % @noitemarg : Set true when executing an \item with no explicit % argument. Used to save space. To save time, % make two separate \@item commands. % \topsepcorrection : a number, usually between 0 and 1, used to define % the default \topsep, as explained below. It is % set by a command like \def\topsepcorrection{.25}. % % Throughout a list environment, \hsize is the width of the current % line, measured from the outermost left margin to the outermost right % margin. Environments like tabbing should use \linewidth instead of % \hsize. % % Here are the parameters of a list that can be set by commands in % the \list's COMMANDS argument. These parameters are all TeX % skips or dimensions (defined by \newskip or \newdimen), so the usual % TeX or LaTeX commands can be used to set them. The commands will % be executed in vmode if and only if the \list was preceded by a % \par (or something like an \end{list}), so the spacing parameters % can be set according to whether the list is inside a paragraph % or is its own paragraph. % % VERTICAL SPACING: (skips) % \topsep : Extra space between first item and preceding paragraph. % Total space is \topsep plus \parskip of the enclosing % environment. % \itemsep : Extra space between successive items. Total interitem % space is \itemsep + \parsep (of this list). % \parsep : Space between paragraphs within an item -- the \parskip % for this environment. % % HORIZONTAL SPACING (dimens) % \leftmargin : space between left margin of enclosing environment % (or of page if top level list) and left margin of % this list. Must be nonnegative. % \rightmargin : analogous. % \listparindent : extra indentation at beginning of every paragraph % of a list except the one started by the \item % command. May be negative! Usually, labeled lists % have \listparindent equal to zero. % \itemindent : extra indentation added right BEFORE an item label. % \labelwidth : width of box that contains the label. % If non-postive, then the item begins flush with % the left margin (except as corrected by \itemindent), % followed by \labelsep space. % \labelsep : space between end of label box and text of % first item. % % DEFAULT VALUES: % % \topsep : If list entered in vertical mode % then 0 pt % else -\topsepcorrection * \parskip of enclosing % environment. % \itemsep : Same as \topsep % \parsep : \parskip of enclosing environment + % minimum of 0 and new \topsep % \leftmargin : \d@leftmargin % \rightmargin : 0 pt % \listparindent : 0 pt % \labelwidth : \d@labelwidth % \labelsep : \d@labelsep % % \list{LABEL}{COMMANDS} == % BEGIN % \@everyitem :=L null % \@saveitem :=L \c@list % \c@list :=G 0 % \topsep :=L if vmode then 0 pt % else -\topsepcorrection * \parskip % \itemsep :=L 0 pt % \parsep :=L \parskip % if \topsep < 0pt then \parsep := \parsep + \topsep fi % \leftmargin :=L \d@leftmargin %Set default value % \rightmargin :=L 0 pt %Set default value % \listparindent :=L 0 pt %Set default value % \itemindent :=L 0pt %Set default value % \labelwidth :=L \d@labelwidth %Set default value % \labelsep :=L \d@labelsep %Set default value % \@itemlabel :=L LABEL % COMMANDS % \@topsep :=L \topsep + \parskip - \parsep % NOTE: \@topsep + \parsep = \topsep + % \parskip of enclosing environment % if @inlabel = true % then @noparitem :=L true % else if hmode then \unskip fi \par % fi % \leftskip :=L 0pt % Restore paragraphing parameters % if @raggedright % then \raggedright % else \rightskip :=L 0pt % fi % \parfillskip :=L 0pt + 1fil % % NOTE: \@setpar called on every \list in case \par has been temporarily % munged before the \list command. % \@setpar{if @newlist = false then {\@@par} fi} % \parskip :=L \parsep % \@newlist :=G T % \parindent :=L \listparindent % \linewidth :=L \linewidth - \rightmargin -\leftmargin % \@totalleftmargin :=L \@totalleftmargin + \leftmargin % \parshape 1 \@totalleftmargin \linewidth % \ignorespaces % gobble space up to \item % END % % \endlist == BEGIN \c@list :=G \@saveitem \@endparenv % % \item == BEGIN if next char = [ % then \@item % else @noitemarg := true % \@item[@itemlabel] % END % % \@item[LAB] == % BEGIN % if @noparitem = true % then @noparitem := false % NOTE: then clause % % hardly every taken, % \box\@labels :=G \hbox{\hskip -\leftmargin % so made a macro % \box\@labels % \@donoparitem % \hskip \leftmargin } % else if @inlabel = true % then \indent \par % previous item empty. % fi % if hmode then 2 \unskip's % To remove any space at end of prev. % \par % paragraph that could cause a blank % fi % line. % if @newlist = T % then % \@addvskip{\@topsep} % \penalty \@beginlistpenalty % else % \@addvskip{\itemsep} % \penalty \@itempenalty % fi % @inlabel :=G true % fi % % \everypar{ @newlist :=G F % if @inlabel = true % then @inlabel :=G false % \hskip -\parindent % \box\@labels % \box\@labels :=G null % fi % \everypar{} } % if @noitemarg = true % then @noitemarg := false % \c@list :=G \c@list + 1 % \@everyitem % fi % \box\@labels :=G \@labels \hskip \itemindent % if \labelwidth > 0pt % then \hskip - (\labelwidth + \labelsep) % \hbox to \labelwidth % else \hbox % fi % {LAB} % \hskip\labelsep % \ignorespaces %gobble space up to text % END % % % DEFINE \dimen's and \count \newskip\topsep \newskip\itemsep \newskip\parsep \newskip\@topsep \newdimen\leftmargin \newdimen\rightmargin \newdimen\listparindent \newdimen\itemindent \newdimen\labelwidth \newdimen\labelsep \newdimen\linewidth \newdimen\@totalleftmargin \@totalleftmargin=\@zero \newcount\c@list \newcount\@saveitem \newcount\@listdepth \@listdepth=0 \newcount\@beginlistpenalty \newcount\@itempenalty \newbox\@labels \newif\if@inlabel \@inlabelfalse \newif\if@newlist \@newlistfalse \newif\if@noparitem \@noparitemfalse \newif\if@noitemarg \@noitemargfalse \def\list#1#2{\def\@everyitem{}\@saveitem\c@list \global\c@list 0 \ifvmode \topsep\@zero \else \topsep -\topsepcorrection\parskip \fi \itemsep\@zero \parsep\parskip \ifdim \topsep <\@zero \advance\parsep \topsep\fi \leftmargin\d@leftmargin \rightmargin \@zero \listparindent \@zero \itemindent \@zero \labelwidth\d@labelwidth \labelsep\d@labelsep \def\@itemlabel{#1}#2\relax \@topsep\topsep \advance\@topsep \parskip \advance\@topsep -\parsep \if@inlabel \@noparitemtrue \else \ifhmode \unskip \fi \par \fi \leftskip\@zero \if@raggedright \raggedright \else \rightskip\@zero \fi \parfillskip\@flushglue \@setpar{\if@newlist\else{\@@par}\fi}% \parskip\parsep \global\@newlisttrue \parindent\listparindent \advance\linewidth -\rightmargin \advance\linewidth -\leftmargin \advance\@totalleftmargin \leftmargin \parshape 1 \@totalleftmargin \linewidth \ignorespaces} \def\endlist{\global\c@list\@saveitem\@endparenv} \def\item{\@ifnextchar [{\@item}{\@noitemargtrue \@item[\@itemlabel]}} \def\@donoparitem{\@noparitemfalse \global\setbox\@labels\hbox{\hskip -\leftmargin \unhbox\@labels \hskip \leftmargin}} \def\@item[#1]{\if@noparitem \@donoparitem \else \if@inlabel \indent \par \fi \ifhmode \unskip\unskip \par \fi \if@newlist \@addvskip\@topsep \penalty\@beginlistpenalty \else \@addvskip\itemsep \penalty\@itempenalty \fi \global\@inlabeltrue \fi \everypar{\global\@newlistfalse \if@inlabel\global\@inlabelfalse \hskip -\parindent \box\@labels\fi \everypar{}} \if@noitemarg \@noitemargfalse \global\advance\c@list 1 \@everyitem \fi \global\setbox\@labels \hbox{\unhbox\@labels \hskip \itemindent \ifdim \labelwidth > \@zero \hskip -\labelwidth \hskip -\labelsep \hbox to \labelwidth \else \hbox \fi {#1\hss}\hskip \labelsep}\ignorespaces} % **************************************** % * ITEMIZE AND ENUMERATE * % **************************************** % % Enumeration is done with four counters: enum@i, enum@ii, enum@iii % and enum@iv, where enum@N controls the numbering of the Nth level % enumeration. The ordinary counter definitions \co@enum@i, etc. % determine how items are referenced. E.g., defining \co@enum@ii % to be % \Alph{enum@i}-\roman{enum@ii} % makes a reference to the third subitem of the second item % look like B-iii. The actual item numbers are generated by % the commands \ce@enum@i, ... , \ce@enum@iv. Thus, defining % \ce@enum@ii to be % [\roman{enum@ii}] % Makes second-level list items numbered [i], [ii], etc. % % To make the \setcounter{enumerate} work properly, in the enumeration % at depth N, \c@enumerate is defined so it expands to \c@enum@N. % However, \newnumbering{enumerate} does not work. % % The dimension \enum@i@margin, \enum@ii@margin, etc. determine the % left margins of the enumeration levels -- i.e., \enum@iii@margin % is the amount by which the left margin of the level-3 enumeration % is indented with respect to the level-2 enumeration's left margin. % They should be dimensions specified in em's, so they'll work right % with arbitrary font sizes. They are set by commands such as % \def\enum@iii@margin{2.3em} % % The item numbers are moved to the right of the label box, so they are % always a distance of \labelsep from the item. % % The vertical spacing is controlled by defining a macro \@enumspacing % that is put in the second argument to a \list macro. It should % set \topsep, \itemsep and \parsep. Note that by using an \ifvmode % or \ifhmode, it can set these parameters differently depending % upon whether or not there is a blank line before the \begin{enumerate}. % \@enumdepth holds the current enumeration nesting depth and can be tested % by \@enumspacing. % % Itemization is controlled by four commands: \item@i, \item@ii, % \item@iii, and \item@iv. To cause the second-level list to be % bulleted, you just define \item@ii to be $\bullet$. The control % sequences \item@i@margin, etc. are analogous to the corresponding ones % for enumeration. \@itemspacing and \@itemdepth are the % analogs of \@enumspacing and \@enumdepth. % % % \enumerate == % BEGIN % if \@enumdepth > 3 % then errormessage: ``Too deeply nested''. % else \@enumdepth :=L \@enumdepth + 1 % \@enumctr :=L eval(enum@\romannumeral\the\@enumdepth) % \@enumitem == \ce@enum@eval(\@enumctr) % \setcounter{\@enumctr}{0} % \list{\hfill\@enumitem} % { \@everyitem == BEGIN \@refstepcounter{\@enumctr} END % \leftmargin = \@nameuse{\@enumctr @margin} % \@enumspacing } % fi % END % % \endenumerate == \endlist % \newcount\@enumdepth \@enumdepth = 0 \@definecounter{enum@i} \@definecounter{enum@ii} \@definecounter{enum@iii} \@definecounter{enum@iv} \def\c@enumerate{\@nameuse{c@\@enumctr}} \def\@toodeep{\@latexerr{Too deeply nested}} \def\enumerate{\ifnum \@enumdepth >3 \@toodeep\else \advance\@enumdepth 1 \edef\@enumctr {enum@\romannumeral\the\@enumdepth}% \edef\@enumitem{\expandafter\noexpand \csname ce@\@enumctr\endcsname}% \setcounter{\@enumctr}0% \list{\hfill \@enumitem}% {\def\@everyitem{\@refstepcounter{\@enumctr}}% \leftmargin\@nameuse{\@enumctr @margin}\@enumspacing}\fi} \let\endenumerate =\endlist % \itemize == % BEGIN % if \@itemdepth > 3 % then errormessage: 'Too deeply nested'. % else \@itemdepth :=L \@itemdepth + 1 % \@itemitem == eval(item@\romannumeral\the\@itemdepth) % \list{\hskip\@sss\@nameuse{\@itemitem}} % {\leftmargin :=L \@nameuse{\@itemitem @margin} % \@itemspacing } % fi % END % % \enditemize == \endlist % \newcount\@itemdepth \@itemdepth = 0 \def\itemize{\ifnum \@itemdepth >3 \@toodeep\else \advance\@itemdepth 1 \edef\@itemitem{item@\romannumeral\the\@itemdepth}% \list{\hfill \@nameuse{\@itemitem}}% {\leftmargin\@nameuse{\@itemitem @margin}\@itemspacing}\fi} \let\enditemize =\endlist % ********************************************* % * BOXES * % ********************************************* % % USER COMMANDS: % % \makebox [WID][POS]{OBJ} % : puts OBJ in an \hbox of width WID, positioned by POS. % POS = l -> flushleft, POS = r -> flushright. % Default is centered. % If WID is missing, then POS is also missing and OBJ % is put in an \hbox of its natural width. % % \mbox{OBJ} == \makebox{OBJ}, and is more efficient. % % \makebox (X,Y)[POS]{OBJ} % : puts OBJ in an \hbox of width X * \unitlength % and height Y * \unitlength. POS arguments are % l or r for flushleft, flushright and t or b % for top, bottom -- or combinations like tr or rb. % Default for horizontal and vertical are centered. % % \savebox N ... : where '...' are any \makebox arguments % like \makebox, except it doesn't produce text but % saves the value in \box N , N = 0 ... 9. % \sbox N{OBJ} is an efficient abbreviation for % \savebox N{OBJ}. % % \framebox ... : like \makebox, except it puts a 'frame' around % the box. The frame is made of lines of thickness % \framerule, separated by space \framesep from the % text -- except for \framebox(X,Y) ... , where the % thickness of the lines is as for the picture environment, % and there is no separation added. % \fbox{OBJ} is an efficient abbreviation for \framebox{OBJ} % % \parbox[POS]{WIDTH}{TEXT} : Makes a box with \hsize TEXT, positioned % by POS as follows: % c : \vcenter (placed in $...$ if not in math mode) % b : \vbox % t : \vtop % default value is c. % Restores the original definitions of: % \par % Resets the following parameters: % \parindent = 0pt % \hsize = WIDTH % \linewidth = WIDTH % \@totalleftmargin = 0pt % \leftskip = 0pt % \rightskip = 0pt % \parfillskip = 0pt plus 1fil % \lineskip = \normallineskip % \baselineskip = \normalbaselineskip % % \parbox[POS]{WIDTH}{TEXT} : In math mode: same as ordinary \parbox % except type of box depends upon POS as follows: % % \rule {WIDTH}{HEIGHT}[RAISED] : Makes a WIDTH X HEIGHT rule, raised % RAISED. % % % \raisebox{DISTANCE}[HEIGHT][DEPTH]{BOX} : Raises BOX up by DISTANCE % length (down if DISTANCE negative). Makes TeX think that % the new box extends HEIGHT above the line and DEPTH below, for % a total vertical length of HEIGHT+DEPTH. Default values of % HEIGHT & DEPTH = actual height and depth of box in new position. % % \makebox == % BEGIN % if next char = ( % then \@makepicbox % else if next char = [ % then \@makebox % else \mbox fi % fi % END % % \@makebox[LEN] == % BEGIN % leave vertical mode % if next char '[' then \@imakebox[LEN] % else \@imakebox[LEN][x] fi % END % % \@imakebox[LEN][POS]{OBJ} == % BEGIN % \hbox to LEN % { \mb@l :=L \mb@r :=L \hss % \let\mb@POS = \relax % \mb@l OBJ \mb@r } % END % % \@makepicbox(X,Y) == % BEGIN % leave vertical mode % if next char = [ then \@imakepicbox(X,Y) % else \@imakepicbox(X,Y)[] fi % END % % \@imakepicbox(X,Y)[POS]{OBJ} == % BEGIN % \vbox to Y * \unitlength % { \mb@l :=L \mb@r :=L \hss % \mb@t :=L \mb@b :=L \hss % tfor \@tempa := POS % one iteration for each token in POS % do \mb@eval(\@tempa) :=L null od % \mb@t % \hbox to X * \unitlength % {\mb@l OBJ \mb@r } % \mb@b} % END % \def\makebox{\@ifnextchar ({\@makepicbox}{\@ifnextchar [{\@makebox}{\mbox}}} \def\mbox#1{\ \unskip\hbox{#1}} \def\@makebox[#1]{\ \unskip\@ifnextchar [{\@imakebox[#1]}{\@imakebox[#1][x]}} \long\def\@imakebox[#1][#2]#3{\hbox to#1{\let\mb@l\hss \let\mb@r\hss \expandafter\let\csname mb@#2\endcsname\relax \mb@l #3\mb@r}} \def\@makepicbox(#1,#2){\ \unskip\@ifnextchar [{\@imakepicbox(#1,#2)}{\@imakepicbox(#1,#2)[]}} \long\def\@imakepicbox(#1,#2)[#3]#4{\vbox to#2\unitlength {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss \let\mb@t\vss \@tfor\@tempa :=#3\do{\expandafter\let \csname mb@\@tempa\endcsname\relax}% \mb@t\hbox to #1\unitlength{\mb@l #4\mb@r}\mb@b}} \def\savebox#1{\@ifnextchar ({\@savepicbox#1}{\@ifnextchar [{\@savebox#1}{\sbox#1}}} \def\sbox#1#2{\setbox#1\hbox{#2}} \def\@savebox#1[#2]{\@ifnextchar [{\@isavebox#1[#2]}{\@isavebox#1[#2][x]}} \long\def\@isavebox#1[#2][#3]#4{\setbox#1 \hbox{\@imakebox[#2][#3]{#4}}} \def\@savepicbox#1(#2,#3){\@ifnextchar [{\@isavepicbox#1(#2,#3)}{\@isavepicbox#1(#2,#3)[]}} \long\def\@isavepicbox#1(#2,#3)[#4]#5{\setbox#1 \hbox{\@imakepicbox (#2,#3)[#4]{#5}}} \def\usebox#1{\ \unskip\copy #1\relax} \long\def\frame#1{\ \unskip \vbox{\vskip-\@halfwidth\hrule height\@halfwidth depth \@halfwidth \vskip-\@halfwidth\hbox{\hskip-\@halfwidth \vrule width\@wholewidth \hskip-\@halfwidth #1\hskip-\@halfwidth \vrule width \@wholewidth \hskip -\@halfwidth}\vskip -\@halfwidth\hrule height \@halfwidth depth \@halfwidth\vskip -\@halfwidth}} \newdimen\fboxrule \newdimen\fboxsep \long\def\fbox#1{\ \unskip\setbox\@tempboxa\hbox{#1}\@tempdima\fboxrule \advance\@tempdima \fboxsep \advance\@tempdima \dp\@tempboxa \hbox{\lower \@tempdima\hbox {\vbox{\hrule height \fboxrule \hbox{\vrule width \fboxrule \hskip\fboxsep \vbox{\vskip\fboxsep \box\@tempboxa\vskip\fboxsep}\hskip \fboxsep\vrule width \fboxrule} \hrule height \fboxrule}}}} \def\framebox{\@ifnextchar ({\@framepicbox}{\@ifnextchar [{\@framebox}{\fbox}}} \def\@framebox[#1]{\@ifnextchar [{\@iframebox[#1]}{\@iframebox[#1][x]}} \long\def\@iframebox[#1][#2]#3{\ \unskip \savebox\@tempboxa[#1][#2]{\kern\fboxsep #3\kern\fboxsep}\@tempdima\fboxrule \advance\@tempdima \fboxsep \advance\@tempdima \dp\@tempboxa \hbox{\lower \@tempdima\hbox {\vbox{\hrule height \fboxrule \hbox{\vrule width \fboxrule \hskip-\fboxrule \vbox{\vskip\fboxsep \box\@tempboxa\vskip\fboxsep}\hskip -\fboxrule\vrule width \fboxrule} \hrule height \fboxrule}}}} \def\@framepicbox(#1,#2){\@ifnextchar [{\@iframepicbox(#1,#2)}{\@iframepicbox(#1,#2)[]}} \long\def\@iframepicbox(#1,#2)[#3]#4{\frame{\@imakepicbox(#1,#2)[#3]{#4}}} \def\parbox{\@ifnextchar [{\@iparbox}{\@iparbox[c]}} \long\def\@iparbox[#1]#2#3{\ \unskip \@pboxswfalse \if #1b\vbox \else \if #1t\vtop \else \ifmmode \vcenter \else \@pboxswtrue $\vcenter \fi \fi \fi{\let\par\@@par\parindent\@zero\hsize #2\linewidth #2\@totalleftmargin\@zero \leftskip\@zero \rightskip\@zero \parfillskip\@flushglue \lineskip\normallineskip \baselineskip\normalbaselineskip #3}\if@pboxsw $\fi} \newif\if@pboxsw \def\rule#1#2{\@ifnextchar[{\@rule{#1}{#2}}{\@rule{#1}{#2}[\@zero]}} \def\@rule#1#2[#3]{\@tempdima#2\advance\@tempdima #3\ \unskip\hbox{\vrule width#1 height\@tempdima depth-#3}} \def\raisebox#1{\@ifnextchar[{\@argraisebox{#1}}{\@raisebox{#1}}} \long\def\@raisebox#1#2{\setbox\@tempboxa\hbox{#2}\@tempdima\ht\@tempboxa \advance\@tempdima #1\ \unskip\hbox{\vrule width\@zero height\@tempdima depth-#1\raise #1\vbox to\@zero{\vss\box\@tempboxa}}} \def\@argraisebox#1[#2]{% \@ifnextchar[{\@iiraisebox{#1}[#2]}{\@iiraisebox{#1}[#2][\@zero]}} \long\def\@iiraisebox#1[#2][#3]#4{\ \unskip \hbox{\vrule width\@zero height#2 depth#3\raise #1\vbox to \@zero{\vss\hbox{#4}}}} % **************************************** % * THE TABBING ENVIRONMENT * % **************************************** % % \dimen(\@firsttab + i) = distance of tab stop i from left margin % 0 <= i <= 15 (?). % % \dimen\@firsttab is initialized to \@totalleftmargin, so it starts % at the prevailing left margin. % % \@maxtab = number of highest defined tab register % probably = \@firsttab + 12 % \@nxttabmar = tab stop number of next line's left margin % \@curtabmar = tab stop number of current line's left margin % \@curtab = number of the current tab. At start of line, % it equals \@curtabmar % \@hightab = largest tab number currently defined. % \@tabpush = depth of \pushtab's % % \box\@curline = contents of current line, excluding left margin skip, % and excluding contents of current field % \box\@curfield = contents of current field % % @rjfield = switch: T iff the last field of the line should be % right-justified at the right margin. % % \@pgmsep = distance left by the \' command between the current % position and the field that is ``left-shifted''. % Default definition = \d@labelsep % % UTILITY MACROS % \@stopfield : closes the current field % \@addfield : adds the current field to the current line. % \@contfield : continues the current field % \@startfield : begins the next field % \@stopline : closes the current line and outputs it % \@startline : starts the next line % \@ifatmargin : an \if that is true iff the current line. % has width zero % % \@startline == % BEGIN % \@curtabmar :=G \@nxttabmar % \@curtab :=G \@curtabmar % \box\@curline :=G null % \@startfield % \strut % END % % \@stopline == % BEGIN % \unskip % \@stopfield % if @rjfield = T % then @rjfield :=G F % \hbox to \hsize{\hskip \dimen\@curtabmar % \box\@curline % \hfil % \box\@curfield} % else \@addfield % \hbox {\hskip \dimen\@curtabmar % \box\@curline} % fi % END % % \@startfield == % BEGIN % \box\@curfield :=G \hbox { % END % % \@stopfield == % BEGIN % } % END % % \@contfield == % BEGIN % \box\@curfield :=G \hbox { \unhbox\@currfield %%} brace matching % END % \@addfield == % BEGIN % \box\@curline :=G \unbox\@curline * \unbox\@curfield % END % % \@ifatmargin == % BEGIN % if dim of box\@curline = 0pt then % END % % % \tabbing == % BEGIN % \lineskip :=L 0pt % \> == \@rtab % \< == \@ltab % \= == \@settab % \+ == \@tabplus % \- == \@tabminus % \` == \@tabrj % \' == \@tablab % \\ == BEGIN \@stopline \@startline END % \\[DIST] == BEGIN \@stopline \vskip DIST \@startline\ignorespaces END % \@hightab :=G \@nxttabmar :=G \@firsttab % \@tabpush :=G 0 % \dimen\@firsttab := \@totalleftmargin % @rjfield :=G F % \@beginparenv % \vskip \parskip % \@startline % \ignorespaces % END % % \@endtabbing == % BEGIN % \@stopline % if \@tabpush > 0 then error message: ''unmatched \poptabs'' fi % \@endparenv % END % % \@rtab == % BEGIN % \@stopfield % \@addfield % if \@curtab < \@hightab % then \@curtab :=G \@curtab + 1 % else error message ``Undefined Tab'' fi % \@tempdima := \dimen\@curtab - \dimen\@curtabmar % - width of box \@curline % \box\@curline :=G \hbox{\unhbox\@curline + \hskip\@tempdima} % \@startfield % END % % \@settab == % BEGIN % \@stopfield % \@addfield % if \@curtab < \@maxtab % then \@curtab :=G \@curtab+1 % else error message: ``Too many tabs'' fi % if \@curtab > \@hightab % then \@hightab :=L \@curtab fi % \dimen\@curtab :=L \dimen\@curtabmar + width of \box\@curline % \@startfield % END % % \@ltab == % BEGIN % \@ifatmargin % then if \@curtabmar > \@firsttab % then \@curtab :=G \@curtab - 1 % \@curtabmar :=G \@curtabmar - 1 % else error message ``Too many untabs'' fi % else error message ``Left tab in middle of line'' % fi % END % % \@tabplus == % BEGIN % if \@nxttabmar < \@maxtab % then \@nxttabmar :=G \@nxttabmar+1 % else error message ``Too many tabs'' % fi % END % % \@tabminus == % BEGIN % if \@nxttabmar > \@firsttab % then \@nxttabmar :=G \@nxttabmar-1 % else error message ``Too many untabs'' % fi % END % % \@tabrj == % BEGIN \@stopfield % \@addfield % @rjfield :=G T % \@startfield % END % % \@tablab == % BEGIN \@stopfield % \box\@curline := \hbox{ \box\@curline % \hskip - width of \box\@curfield % \hskip -\@pgmsep % \box\@curfield % \hskip \@pgmsep } % \@startfield % END % % \pushtabs == % BEGIN % \@stopfield % \@tabpush :=G \@tabpush + 1 % \begingroup % \@contfield % END % % \poptabs == % BEGIN % \@stopfield % if \@tabpush > 0 % then \endgroup % \@tabpush :=G \@tabpush - 1 % else error message: ``Too many \poptabs'' % fi % \@contfield % END % \newif\if@rjfield \newcount\@firsttab \newcount\@maxtab \newdimen\@gtempa \@firsttab=\allocationnumber \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa \newdimen\@getempa \@maxtab=\allocationnumber \dimen\@firsttab=0pt \newcount\@nxttabmar \newcount\@curtabmar \newcount\@curtab \newcount\@hightab \newcount\@tabpush \newbox\@curline \newbox\@curfield \def\@startline{\global\@curtabmar\@nxttabmar\relax \global\@curtab\@curtabmar\setbox\@curline\hbox {}\@startfield\strut} \def\@stopline{\unskip\@stopfield\if@rjfield \global\@rjfieldfalse\hbox to\hsize{\hskip\dimen\@curtabmar \box\@curline\hfil\box\@curfield}\else\@addfield \hbox{\hskip\dimen\@curtabmar\box\@curline}\fi} \def\@startfield{\global\setbox\@curfield\hbox\bgroup}%{ BRACE MATCH HACK \let\@stopfield=} \def\@contfield{\global\setbox\@curfield\hbox\bgroup\unhbox\@curfield} \def\@addfield{\global\setbox\@curline\hbox{\unhbox \@curline\unhbox\@curfield}} \def\@ifatmargin{\ifdim \wd\@curline =\@zero} \def\@tabcr{\@stopline\@ifnextchar[{\@itabcr}{\@startline\ignorespaces}} \def\@itabcr[#1]{\vskip #1\@startline\ignorespaces} \def\kill{\@stopfield\@startline\ignorespaces} % REMOVE \outer FROM PLAIN'S DEF OF \+ \def\+{\tabalign} \def\tabbing{\lineskip \@zero\let\>\@rtab\let\<\@ltab\let\=\@settab \let\+\@tabplus\let\-\@tabminus\let\`\@tabrj\let\'\@tablab \let\\=\@tabcr\global\@hightab \@firsttab\global\@nxttabmar \@firsttab\dimen\@firsttab\@totalleftmargin \global\@tabpush0 \global\@rjfieldfalse\@beginparenv \vskip\parskip\@startline\ignorespaces} \def\endtabbing{\@stopline\ifnum\@tabpush > 0 \@latexerr {Unmatched \string\poptabs}\fi\@endparenv} \def\@rtab{\@stopfield\@addfield\ifnum \@curtab<\@hightab \global\advance\@curtab 1 \else\@latexerr{LATEX ERROR: Undefined tab}\fi \@tempdima\dimen\@curtab \advance\@tempdima -\dimen\@curtabmar \advance\@tempdima -\wd\@curline \setbox\@curline\hbox{\unhbox\@curline\hskip\@tempdima} \@startfield\ignorespaces} \def\@settab{\@stopfield\@addfield\ifnum \@curtab < \@maxtab \global\advance\@curtab 1 \else\@latexerr{LATEX ERROR: Too many tabs}\fi \ifnum\@curtab > \@hightab \@hightab\@curtab\fi \dimen\@curtab\dimen\@curtabmar \advance\dimen\@curtab \wd\@curline\@startfield\ignorespaces} \def\@ltab{\@ifatmargin\ifnum\@curtabmar > \@firsttab \global\advance\@curtab -1 \global\advance\@curtabmar -1 \else \@latexerr{Too many untabs}\fi\else \@latexerr{Left tab in mid line}\fi\ignorespaces} \def\@tabplus{\ifnum \@nxttabmar < \@maxtab \global\advance\@nxttabmar 1 \else \@latexerr{Too many tabs}\fi\ignorespaces} \def\@tabminus{\ifnum\@nxttabmar > \@firsttab \global\advance\@nxttabmar -1 \else \@latexerr{Too many untabs}\fi\ignorespaces} \def\@tabrj{\@stopfield\@addfield\global\@rjfieldtrue\@startfield\ignorespaces} \def\@tablab{\@stopfield\setbox\@curline\hbox{\box\@curline \hskip -\wd\@curfield \hskip -\@pgmsep \box\@curfield \hskip \@pgmsep}\@startfield\ignorespaces} \def\pushtabs{\@stopfield\@addfield\global\advance\@tabpush 1 \begingroup \@contfield} \def\poptabs{\@stopfield\@addfield\ifnum\@tabpush > 0 \endgroup \global\advance\@tabpush -1 \else \@latexerr{Too many \string\poptabs}\fi\@contfield} %INITIALIZATION: \def\@pgmsep{\d@labelsep} % **************************************** % * ARRAY AND TABULAR ENVIRONMENTS * % **************************************** % % ARRAY PARMETERS: % \arraycolsep : half the width separating columns in an array environment % \tabcolsep : half the width separating columns in a tabular environment % \arrayrulewidth : width of rules % \doublerulesep : space between adjacent rules in array or tabular % % PREAMBLE: % The PREAMBLE argument of an array or tabular environment can contain % the following: % l,r,c : indicate where entry is to be placed. % | : for vertical rule % @{EXP} : inserts the text EXP in every column. \arraycolsep or \tabcolsep % spacing is suppressed. % *{N}{PRE} : equivalent to writing N copies of PRE in the preamble. PRE % may contain *{N'}{EXP'} expressions. % % SPECIAL ARRAY COMMANDS: % \multicolumn{N}{FORMAT}{ITEM} : replaces the next N column items by % ITEM, formatted according to FORMAT. FORMAT should contain at most % one l,r or c. If it contains none, then ITEM is ignored. % % \vline : draws a vertical line the height of the current row. May % appear in an array element entry. % \hline : draws a horizontal line between rows. Must appear either % before the first entry (to appear above the first row) or right % after a \\ command. % % \array == if next char = [ then \@array else \@array[c] fi % % \@array[POS]{PREAMBLE} == % BEGIN % \end == \@endarray % \@acol == \@arrayacol % \@classz == \@arrayclassz % \@classiv == \@arrayclassiv % \@arraymakepreamble{PREAMBLE} % \\ == \@arraycr % \@preamble == \halign{\strut eval{\@preamble}\cr %% } BRACE MATCHING % \@startpbox == \@@startpbox % if POS = t then \vtop % else if POS = b then \vbox % else \vcenter % fi fi % { %% } BRACE MATCHING HACK % \par ==L \relax % \@sharp == # % \lineskip :=L 0pt % \baselineskip :=L 0pt % \@preamble % END % %% {{ BRACE MATCHING HACK % \@endarray{NAME} == BEGIN \crcr }} % \@checkend{NAME} \endgroup % END % % \tabular{PREAMBLE} == % BEGIN % \@acol == \@tabacol % \@classz == \@tabclassz % \@classiv == \@tabclassiv % \@arraymakepreamble{PREAMBLE} % \\ == \@arraycr % if in par mode % then \end == \@endpartabular % \@beginparenv % \parindent :=L 0pt % if @inlabel = T % then % \vtop % else enter hmode % \vbox % fi % else \end == \@endarray % \vbox % fi % { %% } BRACE MATCHING % \@preamble == \halign{\strut eval{\@preamble}\cr %% } BRACE MATCHING % \@startpbox == \@@startpbox % \lineskip :=L 0pt % \baselineskip :=L 0pt % \par ==L \relax % \@sharp == # % \@preamble % END % %%{{ BRACE MATCHING % \@endpartabular{NAME} == BEGIN \crcr}} % \@checkend{NAME} \@endparenv % END % % \@tabnoparhack == % BEGIN if @inlabel = T then \indent \the\everypar fi % % \@arraycr == % BEGIN % if next char = [ % then \@argarraycr % else \cr % END % % \@ararraycr[LENGTH] == % BEGIN % if LENGTH > 0 % then \@tempdima := depth of \strutbox + LENGTH % \vrule height 0pt width 0pt depth \@tempdima % \cr % else \cr \noalign{\vskip LENGTH} % END \def\array{\@ifnextchar[{\@array}{\@array[c]}} \def\@array[#1]#2{\let\end\@endarray \let\@acol\@arrayacol \let\@classz\@arrayclassz \let\@classiv\@arrayclassiv \@arraymakepreamble{#2}\let\\\@arraycr \edef\@preamble{\halign \bgroup \strut \@preamble \cr}% \let\@startpbox\@@startpbox \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi \bgroup \let\par\relax \let\@sharp##\lineskip\@zero\baselineskip\@zero\@preamble} \def\@endarray#1{\crcr\egroup\egroup\@checkend{#1}\endgroup} \def\tabular#1{\let\@acol\@tabacol \let\@classz\@tabclassz \let\@classiv\@tabclassiv \@arraymakepreamble{#1}\let\\\@arraycr \ifvmode \@partabular \else \ifhmode \ifinner \let\end\@endarray \vbox \else \@partabular \fi \else \let\end\@endarray \vbox \fi \fi \bgroup \edef\@preamble{\halign \bgroup \strut \@preamble \cr}% \let\@startpbox\@@startpbox \lineskip\@zero\baselineskip\@zero \let\par\relax\let\@sharp##\@preamble} \def\@partabular{\let\end\@endpartabular \@beginparenv \parindent\@zero \if@inlabel \ \unskip\vtop \else \ \unskip\vbox \fi} \def\@endpartabular#1{\crcr \egroup\egroup \@checkend{#1}\@endparenv\endgroup} \def\@tabnoparhack{\if@inlabel \indent \the\everypar \fi} \def\@arraycr{\@ifnextchar[{\@argarraycr}{\cr}} \def\@argarraycr[#1]{\ifdim #1>\@zero \@xargarraycr{#1}\else \@yargarraycr{#1}\fi} \def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp\strutbox \vrule height\@zero depth\@tempdima width\@zero \cr} \def\@yargarraycr#1{\cr\noalign{\vskip #1}} % \multicolumn{NUMBER}{FORMAT}{ITEM} == % BEGIN % \multispan{NUMBER} % \begingroup % \@addamp == null % \@arraymakepreamble{FORMAT} % \@sharp == ITEM % \@startpbox == \@@startpbox % \strut % \@preamble % \endgroup % END \def\multicolumn#1#2#3{\multispan{#1}\begingroup \def\@addamp{}\@arraymakepreamble{#2}% \def\@sharp{#3}\let\@startpbox\@@startpbox \strut \@preamble\endgroup\ignorespaces} % Codes for classes and character numbers of array, tabular and % multicolumn arguments. % % Character Class Number % --------- ----- ------ % c 0 0 % l 0 1 % r 0 2 % % | 1 - % @ 2 - % p 3 - % {@-exp} 4 - % {p-arg} 5 - % % \@testpach \foo : expands \foo, which should be an array parameter token, % and sets \@chclass and \@chnum to its class and number. % Uses \@lastchclass to distinguish 4 and 5 % % Preamble error codes % 0: 'illegal character' % 1: 'Missing @-exp' % 2: 'Missing p-arg' % % \@addamp == % BEGIN if @firstamp = true then @firstamp := false % else & fi % END % % \@arraymakepreamble TOKENLIST == % BEGIN % @firstamp := T % \@lastchclass := 6 % \@preamble == null % \@sharp == \relax % \@startpbox == \relax % \@expast{TOKENLIST} % for \@nextchar := expand(\@tempa) % do \@testpach{\@nextchar} % case of \@chclass % 0 -> \@classz % 1 -> \@classi % ... % 5 -> \@classv % end case % \@lastchclass := \@chclass % od % case of \@lastchclass % 0 -> \hskip \arraycolsep % lrc % 1 -> % | % 2 -> \@preamerr1 % 'Missing @-exp' % @ % 3 -> \@preamerr2 % 'Missing p-arg' % p % 4 -> % @-exp % 5 -> \hskip \arraycolsep % p-exp % end case % END % % \@arrayclassz == % BEGIN % \@preamble := \@preamble * % case of \@lastchclass % 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep % 1 -> \@addamp \hskip \arraycolsep % 2 -> % impossible % 3 -> % impossible % 4 -> \@addamp % 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep % 6 -> \@addamp \hskip \arraycolsep % end case % * case of \@chnum % 0 -> \hfil$\@sharp$\hfil % 1 -> $\@sharp$\hfil % 2 -> \hfil$\@sharp$ % end case % END % % \@tabclassz == similar to \@arrayclassz % % \@classi == % BEGIN % \@preamble := \@preamble * % case of \@lastchclass % 0 -> \hskip \arraycolsep \@arrayrule % 1 -> \hskip \doublerulesep \@arrayrule % 2 -> % impossible % 3 -> % impossible % 4 -> \@arrayrule % 5 -> \hskip \arraycolsep \@arrayrule % 6 -> \@arrayrule % end case % END % % \@classii == % BEGIN % \@preamble := \@preamble * % case of \@lastchclass % 0 -> % 1 -> \hskip .5\arrayrulewidth % 2 -> % impossible % else -> % end case % END % % \@classiii == % BEGIN % \@preamble := \@preamble * % case of \@lastchclass % 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep % 1 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep % 2 -> % impossible % 3 -> % impossible % 4 -> \@addamp % 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep % 6 -> \@addamp \hskip \arraycolsep % end case % END % % \@arrayclassiv == BEGIN \@preamble := \@preamble * $ \@nextchar$ END % % \@tabclassiv == same as \@arrayclassv except without the $ ... $ % % \@classv == % BEGIN % \@preamble := \@preamble * \@startpbox{\@nextchar}\ignorespaces\@sharp\egroup % END % % \@expast{S}: Sets \@tempa := S with all instances of *{N}{STRING} % replaced by N copies of STRING, where N > 0. An * % appearing inside braces is ignored, but *-expressions % inside STRING are expanded, so nested *-expressions are % handled properly. % % \@expast{S} == BEGIN \@xexpast S *0x\@@ END % % \@xexpast S1 *{N}{S2} S3 \@@ == % BEGIN % \@tempa := S1 % \@tempcnta := N % if \@tempcnta > 0 % then while \@tempcnta > 0 do \@tempa := \@tempa S2 % \@tempcnta := \@tempcnta - 1 od % \@tempb == \@xexpast % else \@tempb == \@xexnoop % fi % \expandafter \@tempb \@tempa S3 \@@ % END % \def\@xexnoop #1\@@{} \def\@expast#1{\@xexpast #1*0x\@@} \def\@xexpast#1*#2#3#4\@@{\edef\@tempa{#1}\@tempcnta#2\relax \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do {\edef\@tempa{\@tempa#3}\advance\@tempcnta by -1}\let\@tempb\@xexpast \else \let\@tempb\@xexnoop\fi \expandafter\@tempb \@tempa #4\@@} \newif\if@firstamp \def\@addamp{\if@firstamp \@firstampfalse \else \edef\@preamble{\@preamble &}\fi} \def\@arrayacol{\edef\@preamble{\@preamble \hskip \arraycolsep}} \def\@tabacol{\edef\@preamble{\@preamble \hskip \tabcolsep}} \def\@ampacol{\@addamp \@acol} \def\@acolampacol{\@acol\@addamp\@acol} \def\@preamerr#1{\@latexerr{\ifcase #1 Illegal character\or Missing @-exp\or Missing p-arg\fi\space in preamble}} \def\@arraymakepreamble#1{\@firstamptrue\@lastchclass6 \def\@preamble{}\let\@sharp\relax \let\@startpbox\relax \@expast{#1}\expandafter\@tfor \expandafter \@nextchar \expandafter:\expandafter=\@tempa\do{\@testpach\@nextchar \ifcase \@chclass \@classz \or \@classi \or \@classii \or \@classiii \or \@classiv \or\@classv \fi\@lastchclass\@chclass}% \ifcase \@lastchclass \@acol \or \or \@preamerr 1\or \@preamerr 2\or \or \@acol \fi} \def\@arrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or \or \or \@addamp \or \@acolampacol \or \@firstampfalse \@acol \fi \edef\@preamble{\@preamble \ifcase \@chnum \hfil$\@sharp$\hfil \or $\@sharp$\hfil \or \hfil$\@sharp$\fi}} \def\@tabclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or \or \or \@addamp \or \@acolampacol \or \@firstampfalse \@acol \fi \edef\@preamble{\@preamble \ifcase \@chnum \hfil\ignorespaces\@sharp\unskip\hfil \or \ignorespaces\@sharp\unskip\hfil \or \hfil\ignorespaces\@sharp\unskip\fi}} \def\@classi{\ifcase \@lastchclass \@acol \@arrayrule \or \@addtopreamble{\hskip \doublerulesep}\@arrayrule\or \or \or \@arrayrule \or \@acol \@arrayrule \or \@arrayrule \fi} \def\@classii{\ifcase \@lastchclass \or \@addtopreamble{\hskip .5\arrayrulewidth}\fi} \def\@classiii{\ifcase \@lastchclass \@acolampacol \or \@acolampacol \or \or \or \@addamp \or \@acolampacol \or \@ampacol \fi} \def\@tabclassiv{\@addtopreamble\@nextchar} \def\@arrayclassiv{\@addtopreamble{$ \@nextchar$}} \def\@classv{\@addtopreamble{\@startpbox{\@nextchar}\ignorespaces \@sharp\egroup}} \def\@addtopreamble#1{\edef\@preamble{\@preamble #1}} \newcount\@chclass \newcount\@lastchclass \newcount\@chnum \newdimen\arraycolsep \newdimen\tabcolsep \newdimen\arrayrulewidth \newdimen\doublerulesep \def\@arrayrule{\@addtopreamble{\hskip -.5\arrayrulewidth \vrule width \arrayrulewidth\hskip -.5\arrayrulewidth}} \def\@testpach#1{\@chclass \ifnum \@lastchclass=2 4 \else \ifnum \@lastchclass=3 5 \else 0 \if #1c\@chnum 0 \else \if #1l\@chnum 1 \else \if #1r\@chnum 2 \else \@chclass \if #1|1 \else \if #1@2 \else \if #1p3 \else 0 \@preamerr 0\fi \fi \fi \fi \fi \fi \fi \fi} \def\hline{\noalign{\hrule height \arrayrulewidth}} \def\vline{\vrule width \arrayrulewidth} % \@startpbox{WIDTH} TEXT \egroup == \parbox{WIDTH}{TEXT} \def\@startpbox#1{\vtop\bgroup \let\par\@@par \parindent\@zero\hsize #1\linewidth #1\@totalleftmargin\@zero \leftskip\@zero \rightskip\@zero \parfillskip\@flushglue \lineskip\normallineskip \baselineskip\normalbaselineskip} \let\@@startpbox=\@startpbox % **************************************** % * THE PICTURE ENVIRONMENT * % **************************************** % % \unitlength = value of dimension argument % \@wholewidth = current line width % \@halfwidth = half of current line width % \@linefnt = font for drawing lines % % \picture(XSIZE,YSIZE)(XORG,YORG) % BEGIN % leave vmode % \vbox to YSIZE * \unitlength % { \par == \relax % \vskip YORG * \unitlength % \hbox to XSIZE * \unitlength { \hskip -XORG * \unitlength \hbox{} % END % % \endpicture == % BEGIN % \hss } \vss } % END % % \put(X, Y){OBJ} == % BEGIN % \@killglue % \raise Y * \unitlength \hbox to 0pt { \hskip X * \unitlength % OBJ \hss } % \ignorespaces % END % % \multiput(X,Y)(DELX,DELY){N}{OBJ} == % BEGIN % \@killglue % \@multicnt := N % \@xdim := X * \unitlength % \@ydim := Y * \unitlength % while \@multicnt > 0 % do \raise \@ydim \hbox to 0pt { \hskip \@xdim % OBJ \hss } % \@multicnt := \@multicnt - 1 % \@xdim := \@xdim + DELX * \unitlength % \@ydim := \@ydim + DELY * \unitlength % od % \ignorespaces % END % % \shortstack[POS]{TEXT} : Makes a \vbox containing TEXT stacked as % a one-column array, positioned l, r or c as indicated by POS. \newdimen\@wholewidth \newdimen\@halfwidth \newdimen\unitlength \def\picture(#1,#2){\ \unskip \@ifnextchar({\@picture(#1,#2)}{\@picture(#1,#2)(0,0)}} \def\@picture(#1,#2)(#3,#4){\vbox to #2\unitlength\bgroup \let\par\relax\vskip#4\unitlength \hbox to #1\unitlength\bgroup \hskip -#3\unitlength \hbox{}} \def\endpicture{\hss\egroup\vss\egroup} \long\def\put(#1,#2)#3{\@killglue\raise#2\unitlength\hbox to \@zero{\hskip #1\unitlength #3\hss}\ignorespaces} \long\def\multiput(#1,#2)(#3,#4)#5#6{\@killglue\@multicnt=#5\relax \@xdim=#1\unitlength \@ydim=#2\unitlength \@whilenum \@multicnt > 0\do {\raise\@ydim\hbox to \@zero{\hskip \@xdim #6\hss}\advance\@multicnt -1\advance\@xdim #3\unitlength\advance\@ydim #4\unitlength}\ignorespaces} \def\@killglue{\unskip\@whiledim \lastskip >\@zero\do{\unskip}} % TEMPORARY DEFINITIONS \def\thinlines{\let\@linefnt\tenln \@halfwidth .2pt\@wholewidth .4pt} \def\thicklines{\let\@linefnt\tenlnw \@halfwidth .5pt\@wholewidth 1.0pt} \newdimen\@halfwidth \newdimen\@wholewidth \def\shortstack{\@ifnextchar[{\@shortstack}{\@shortstack[c]}} \def\@shortstack[#1]{\ \unskip \vbox\bgroup\baselineskip-1pt\lineskip 3pt\let\mb@l\hss \let\mb@r\hss \expandafter\let\csname mb@#1\endcsname\relax \let\\\@stackcr\@ishortstack} \def\@ishortstack#1{\halign{\mb@l ##\unskip\mb@r\cr #1\crcr}\egroup} \def\@stackcr{\@ifnextchar[{\@istackcr}{\cr\ignorespaces}} \def\@istackcr[#1]{\cr\noalign{\vskip #1}\ignorespaces} % \line(X,Y){LEN} == % BEGIN % \@xarg := X % \@yarg := Y % \@linelen := LEN * \unitlength % if \@xarg = 0 % then \@vline % else if \@yarg = 0 % then \@hline % else \@sline % if % if % END % % \@sline == % BEGIN % if \@xarg < 0 % then @negarg := T % \@xarg := -\@xarg % \@yyarg := -\@yarg % else @negarg := F % \@yyarg := \@yarg % fi % \@tempcnta := |\@yyarg| % if \@tempcnta > 6 % then error: 'LATEX ERROR: Illegal \line or \vector argument.' % \@tempcnta := 0 % fi % \box\@linechar := \hbox{\@linefnt \@getlinechar(\@xarg,\@yyarg) } % if \@yarg > 0 then \@upordown = \raise % \@currlineht := 0 % else \@upordown = \lower % \@currlineht := height of \box\@linechar % fi % \@currlinewd := width of \box\@linechar % if @negarg % then \hskip - width of \box\@linechar % \@tempa == \hskip - 2* width of box \@linechar % else \@tempa == \relax % fi % %% Put out integral number of line segments % while \@currlinewd < \@linelen % do \@upordown \@currlineht \copy\@linechar % \@tempa % \@currlineht := \@currlineht + ht of \box\@linechar % \@currlinewd := \@currlinewd + width of \box\@linechar % od % % %% Put out last segment % \@currlineht := \@currlineht - height of \box\@linechar % \@currlinewd := \@currlinewd - width of \box\@linechar % \@tempdima := \@linelen - \@currlinewd % \@tempdimb := \@tempdima - width of \box\@linechar % if @negarg then \hskip -\@tempdimb % else \hskip \@tempdimb % fi % \@tempdima := 1000 * \@tempdima % \@tempcnta := \@tempdima / width of \box\@linechar % \@tempdima := (\@tempcnta * ht of \box\@linechar)/1000 % \@currlineht := \@currlineht + \@tempdima % if \@linelen < width of box\@linechar % then \hskip width of box\@linechar % else \hbox{\@upordown \@currlineht \copy\@linechar} % fi % END % % \@hline == % BEGIN % if \@xarg < 0 then \hskip -\@linelen \fi % \vrule height \@halfwidth depth \@halfwidth width \@linelen % if \@xarg < 0 then \hskip -\@linelen \fi % END % % \@vline == if \@yarg < 0 \@downline else \@upline fi % % % \@getlinechar(X,Y) == % BEGIN % \@tempcnta := 8*X - 9 % if Y > 0 % then \@tempcnta := \@tempcnta + Y % else \@tempcnta := \@tempcnta - Y + 64 % fi % \char\@tempcnta % END % % \vector(X,Y){LEN} == % BEGIN % \@xarg := X % \@yarg := Y % \@linelen := LEN * \unitlength % if \@xarg = 0 % then \@vvector % else if \@yarg = 0 % then \@hvector % else \@svector % if % if % END % % \@hvector == % BEGIN % \@hline % {\@linefnt if \@xarg < 0 then \@getlarrow(1,0) % else \@getrarrow(1,0) % fi} % END % % \@vvector == if \@yarg < 0 \@downvector else \@upvector fi % % \@svector == % BEGIN % \@sline % \@tempcnta := |\@yarg| % if \@tempcnta < 5 % then \hskip - width of \box\@linechar % \@upordown \@currlineht \hbox % {\@linefnt % if @negarg then \@getlarrow(\@xarg,\@yyarg) % else \@getrarrow(\@xarg,\@yyarg) % fi } % else error: 'LATEX ERROR: Illegal \line or \vector argument.' % fi % END % % \@getlarrow(X,Y) == % BEGIN % if Y = 0 % then \@tempcnta := '33 % else \@tempcnta := 16 * X - 9 % \@tempcntb := 2 * Y % if \@tempcntb > 0 % then \@tempcnta := \@tempcnta + \@tempcntb % else \@tempcnta := \@tempcnta - \@tempcntb + 64 % fi % fi % \char\@tempcnta % END % % \@getrarrow(X,Y) == % BEGIN % \@tempcntb := |Y| % case of \@tempcntb % 0 : \@tempcnta := '55 % 1 : if X < 3 % then \@tempcnta := 24*X - 6 % else if X = 3 % then \@tempcnta := 49 % else \@tempcnta := 58 fi % fi % 2 : if X < 3 % then \@tempcnta := 24*X - 3 % else \@tempcnta := 51 % X must = 3 % fi % 3 : \@tempcnta := 16*X - 2 % 4 : \@tempcnta := 16*X + 7 % endcase % if Y < 0 % then \@tempcnta := \@tempcnta + 64 % fi % \char\@tempcnta % END \newif\if@negarg \def\line(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax \@linelen=#3\unitlength \ifnum\@xarg =0 \@vline \else \ifnum\@yarg =0 \@hline \else \@sline\fi \fi} \def\@sline{\ifnum\@xarg< 0 \@negargtrue \@xarg -\@xarg \@yyarg -\@yarg \else \@negargfalse \@yyarg \@yarg \fi \ifnum \@yyarg >0 \@tempcnta\@yyarg \else \@tempcnta -\@yyarg \fi \ifnum\@tempcnta>6 \@badlinearg\@tempcnta0 \fi \setbox\@linechar\hbox{\@linefnt\@getlinechar(\@xarg,\@yyarg)}% \ifnum \@yarg >0 \let\@upordown\raise \@currlineht\@zero \else\let\@upordown\lower \@currlineht \ht\@linechar\fi \@currlinewd=\wd\@linechar \if@negarg \hskip -\wd\@linechar \def\@tempa{\hskip -2\wd\@linechar}\else \let\@tempa\relax \fi \@whiledim \@currlinewd <\@linelen \do {\@upordown\@currlineht\copy\@linechar \@tempa \advance\@currlineht \ht\@linechar \advance\@currlinewd \wd\@linechar}% \advance\@currlineht -\ht\@linechar \advance\@currlinewd -\wd\@linechar \@tempdima\@linelen\advance\@tempdima -\@currlinewd \@tempdimb\@tempdima\advance\@tempdimb -\wd\@linechar \if@negarg \hskip -\@tempdimb \else \hskip \@tempdimb \fi \multiply\@tempdima 1000 \@tempcnta \@tempdima \@tempdima \wd\@linechar \divide\@tempcnta \@tempdima \@tempdima \ht\@linechar \multiply\@tempdima \@tempcnta \divide\@tempdima 1000 \advance\@currlineht \@tempdima \ifdim \@linelen <\wd\@linechar \hskip \wd\@linechar \else\@upordown\@currlineht\copy\@linechar\fi} \def\@hline{\ifnum \@xarg <0 \hskip -\@linelen \fi \vrule height \@halfwidth depth \@halfwidth width \@linelen \ifnum \@xarg <0 \hskip -\@linelen \fi} \def\@badlinearg{\@latexerr{Bad \string\line\space or \string\vector \space argument}} \def\@getlinechar(#1,#2){\@tempcnta#1\relax\multiply\@tempcnta 8 \advance\@tempcnta -9 \ifnum #2>0 \advance\@tempcnta #2\relax\else \advance\@tempcnta -#2\relax\advance\@tempcnta 64 \fi \char\@tempcnta} \def\vector(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax \@linelen=#3\unitlength \ifnum\@xarg =0 \@vvector \else \ifnum\@yarg =0 \@hvector \else \@svector\fi \fi} \def\@hvector{\@hline\hbox to 0pt{\@linefnt \ifnum \@xarg <0 \@getlarrow(1,0)\hss\else \hss\@getrarrow(1,0)\fi}} \def\@vvector{\ifnum \@yarg <0 \@downvector \else \@upvector \fi} \def\@svector{\@sline \@tempcnta\@yarg \ifnum\@tempcnta <0 \@tempcnta=-\@tempcnta\fi \ifnum\@tempcnta <5 \hskip -\wd\@linechar \@upordown\@currlineht \hbox{\@linefnt \if@negarg \@getlarrow(\@xarg,\@yyarg) \else \@getrarrow(\@xarg,\@yyarg) \fi}% \else\@badlinearg\fi} \def\@getlarrow(#1,#2){\ifnum #2 =0 \@tempcnta='33\else \@tempcnta=#1\relax\multiply\@tempcnta 16 \advance\@tempcnta -9 \@tempcntb=#2\relax\multiply\@tempcntb 2 \ifnum \@tempcntb >0 \advance\@tempcnta \@tempcntb\relax \else\advance\@tempcnta -\@tempcntb\advance\@tempcnta 64 \fi\fi\char\@tempcnta} \def\@getrarrow(#1,#2){\@tempcntb=#2\relax \ifnum\@tempcntb < 0 \@tempcntb=-\@tempcntb\relax\fi \ifcase \@tempcntb\relax \@tempcnta='55 \or \ifnum #1<3 \@tempcnta=#1\relax\multiply\@tempcnta 24 \advance\@tempcnta -6 \else \ifnum #1=3 \@tempcnta=49 \else\@tempcnta=58 \fi\fi\or \ifnum #1<3 \@tempcnta=#1\relax\multiply\@tempcnta 24 \advance\@tempcnta -3 \else \@tempcnta=51\fi\or \@tempcnta=#1\relax\multiply\@tempcnta 16 \advance\@tempcnta -2 \else \@tempcnta=#1\relax\multiply\@tempcnta 16 \advance\@tempcnta 7 \fi\ifnum #2<0 \advance\@tempcnta 64 \fi \char\@tempcnta} \def\@vline{\ifnum \@yarg <0 \@downline \else \@upline\fi} \def\@upline{\hbox to \@zero{\hskip -\@halfwidth \vrule width \@wholewidth height \@linelen depth \@zero\hss}} \def\@downline{\hbox to \@zero{\hskip -\@halfwidth \vrule width \@wholewidth height \@zero depth \@linelen \hss}} \def\@upvector{\@upline\setbox\@tempboxa\hbox{\@linefnt\char'66}\raise \@linelen \hbox to\@zero{\lower \ht\@tempboxa\box\@tempboxa\hss}} \def\@downvector{\@downline\lower \@linelen \hbox to \@zero{\@linefnt\char'77\hss}} % \dashbox{D}(X,Y) == % BEGIN % leave vertical mode % \hbox to 0pt { % \baselineskip := 0pt % \lineskip := 0pt % %% HORIZONTAL DASHES % \@dashdim := X * \unitlength % \@dashcnt := \@dashdim + 200 % to prevent roundoff error % \@dashdim := D * \unitlength % \@dashcnt := \@dashcnt / \@dashdim % if \@dashcnt is odd % then \@dashdim := 0pt % \@dashcnt := (\@dashcnt + 1) / 2 % else \@dashdim := \@dashdim / 2 % \@dashcnt := \@dashcnt / 2 - 1 % \box\@dashbox := \hbox{\vrule height \@halfwidth % depth \@halfwidth width \@dashdim} % \put(0,0){\copy\@dashbox} % \put(0,Y){\copy\@dashbox} % \put(X,0){\hskip -\@dashdim\copy\@dashbox} % \put(X,Y){\hskip -\@dashdim\box\@dashbox} % \@dashdim := 3 * \@dashdim % fi % \box\@dashbox := \hbox{\vrule height \@halfwidth % depth \@halfwidth width D * \unitlength % \hskip D * \unitlength} % \@tempcnta := 0 % \put(0,0){\hskip \@dashdim % while \@tempcnta < \@dascnt % do \copy\@dashbox % \@tempcnta := \@tempcnta + 1 % od % } % \@tempcnta := 0 % put(0,Y){\hskip \@dashdim % while \@tempcnta < \@dascnt % do \copy\@dashbox % \@tempcnta := \@tempcnta + 1 % od % } % % %% vertical dashes % \@dashdim := Y * \unitlength % \@dashcnt := \@dashdim + 200 % to prevent roundoff error % \@dashdim := D * \unitlength % \@dashcnt := \@dashcnt / \@dashdim % if \@dashcnt is odd % then \@dashdim := 0pt % \@dashcnt := (\@dashcnt + 1) / 2 % else \@dashdim := \@dashdim / 2 % \@dashcnt := \@dashcnt / 2 - 1 % \box\@dashbox := \hbox{\hskip -\@halfwidth % \vrule width \@wholewidth % height \@dashdim } % \put(0,0){\copy\@dashbox} % \put(X,0){\copy\@dashbox} % \put(0,Y){\lower\@dashdim\copy\@dashbox} % \put(X,Y){\lower\@dashdim\copy\@dashbox} % \@dashdim := 3 * \@dashdim % fi % \box\@dashbox := \hbox{\vrule width \@wholewidth % height D * \unitlength } % \@tempcnta := 0 % put(0,0){\hskip -\halfwidth % \vbox{while \@tempcnta < \@dashcnt % do \vskip D*\unitlength % \copy\@dashbox % \@tempcnta := \@tempcnta + 1 % od % \vskip \@dashdim % } } % \@tempcnta := 0 % put(X,0){\hskip -\halfwidth % \vbox{while \@tempcnta < \@dashcnt % do \vskip D*\unitlength % \copy\@dashbox % \@tempcnta := \@tempcnta + 1 % od % \vskip \@dashdim % } % } % } % END DASHES % % \@imakepicbox(X,Y) % END \def\dashbox#1(#2,#3){\ \unskip\hbox to \@zero{\baselineskip \@zero% \lineskip \@zero% \@dashdim=#2\unitlength% \@dashcnt=\@dashdim \advance\@dashcnt 200 \@dashdim=#1\unitlength\divide\@dashcnt \@dashdim \ifodd\@dashcnt\@dashdim=\@zero% \advance\@dashcnt 1 \divide\@dashcnt 2 \else \divide\@dashdim 2 \divide\@dashcnt 2 \advance\@dashcnt -1 \setbox\@dashbox=\hbox{\vrule height \@halfwidth depth \@halfwidth width \@dashdim}\put(0,0){\copy\@dashbox}% \put(0,#3){\copy\@dashbox}% \put(#2,0){\hskip-\@dashdim\copy\@dashbox}% \put(#2,#3){\hskip-\@dashdim\box\@dashbox}% \multiply\@dashdim 3 \fi \setbox\@dashbox=\hbox{\vrule height \@halfwidth depth \@halfwidth width #1\unitlength\hskip #1\unitlength}\@tempcnta=0 \put(0,0){\hskip\@dashdim \@whilenum \@tempcnta < \@dashcnt \do{\unskip\copy\@dashbox\advance\@tempcnta 1 }}\@tempcnta=0 \put(0,#3){\hskip\@dashdim \@whilenum \@tempcnta < \@dashcnt \do{\unskip\copy\@dashbox\advance\@tempcnta 1 }}% \@dashdim=#3\unitlength% \@dashcnt=\@dashdim \advance\@dashcnt 200 \@dashdim=#1\unitlength\divide\@dashcnt \@dashdim \ifodd\@dashcnt \@dashdim=\@zero% \advance\@dashcnt 1 \divide\@dashcnt 2 \else \divide\@dashdim 2 \divide\@dashcnt 2 \advance\@dashcnt -1 \setbox\@dashbox\hbox{\hskip -\@halfwidth \vrule width \@wholewidth height \@dashdim}\put(0,0){\copy\@dashbox}% \put(#2,0){\copy\@dashbox}% \put(0,#3){\lower\@dashdim\copy\@dashbox}% \put(#2,#3){\lower\@dashdim\copy\@dashbox}% \multiply\@dashdim 3 \fi \setbox\@dashbox\hbox{\vrule width \@wholewidth height #1\unitlength}\@tempcnta0 \put(0,0){\hskip -\@halfwidth \vbox{\@whilenum \@tempcnta < \@dashcnt \do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta 1 }% \vskip\@dashdim}}\@tempcnta0 \put(#2,0){\hskip -\@halfwidth \vbox{\@whilenum \@tempcnta< \@dashcnt \relax\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta 1 }% \vskip\@dashdim}}}\@makepicbox(#2,#3)} % CIRCLES AND OVALS % % USER COMMANDS: % % \circle{D} : Produces the circle with the diameter as close as % possible to D * \unitlength. \put(X,Y){\circle{D}} % puts the circle with its center at (X,Y). % % \oval(X,Y) : Makes an oval as round as possible that fits in the % rectangle of width X * \unitlength and height % Y * \unitlength. The reference point is the lower % left-hand corner of the circumscribing rectangle. % % \oval(X,Y)[POS] : Save as \oval(X,Y) except it draws only the % half or quadrant of the oval indicated by POS. % E.G., \oval(X,Y)[t] draws just the top half % and \oval(X,Y)[br] draws just the bottom right % quadrant. In all cases, the reference point is % the same as the unqualified \oval(X,Y) command. % % TEMPORARY DEFINITIONS \def\oval(#1,#2){\@ifnextchar[{\@oval(#1,#2)}{\@oval(#1,#2)[]}} \def\@oval(#1,#2)[#3]{\@warning{\string\oval\space not available yet}} \def\circle#1{\@warning{\string\circle\space not available yet}} %INITIALIZATION \thinlines \newcount\@xarg \newcount\@yarg \newcount\@yyarg \newcount\@multicnt \newdimen\@xdim \newdimen\@ydim \newbox\@linechar \newdimen\@linelen \newdimen\@currlinewd \newdimen\@currlineht \newdimen\@dashdim \newbox\@dashbox \newcount\@dashcnt % **************************************** % * THEOREM ENVIRONMENTS * % **************************************** % % The user creates his own theorem-like environments with the command % \newtheorem{NAME}{TEXT}[COUNTER] or % \newtheorem{NAME}[OLDNAME]{TEXT} % This defines the environment NAME to be just as one would expect a % theorem environment to be, except that it prints ``TEXT'' instead of % ``Theorem''. % % If OLDNAME is given, then environments NAME and OLDNAME use the same % counter, so using a NAME environment advances the number of the next % NAME environment, and vice-versa. % % If COUNTER is given, then environment NAME is numbered within COUNTER. % E.g., if COUNTER = subsection, then the first NAME in subsection 7.2 % is numbered TEXT 7.2.1. % % The way NAME environments are numbered can be changed by the % \newnumbering command. % % DOCUMENT STYLE PARAMETERS % % \@thmcounter{COUNTER} : A command such that % \edef\co@COUNTER{\@thmcounter{COUNTER}} % defines \co@COUNTER to produce a number for a theorem environment. % The default is: % BEGIN \noexpand\arabic{COUNTER} END % % \@thmcountersep : A separator placed between a theorem number and % the number of the counter within which it is numbered. % E.g., to make the third theorem of section 7.2 be numbered % 7.2-3, \@thmcountersep should be \def'ed to '-'. Its % default is '.'. % % \@makethmnumber{NAME}{NUMBER} : A command that produces a printed % theorem number. E.g., \@makethmnumber{Lemma}{3.7} might % produce {\bf Lemma 3.7:}. % % \@thmlistcmd : A theorem is a list environment. This command % is used in the second argument to the \list command % in order to change the margins, etc. The command should % NOT set \labelwidth. The theorem number is produced % as an \item, so \itemindent will move the theorem number % relative to the left margin. A font-changing command in % the \@thmlistcmd argument will be executed before the % theorem number is typeset. % % \newtheorem{NAME}{TEXT}[COUNTER] == % BEGIN % if \NAME is definable % then \@definecounter{NAME} % if COUNTER present % then \@addtoreset{NAME}{COUNTER} fi % \co@NAME == BEGIN \co@COUNTER \@thmcountersep % eval\@thmcounter{NAME} END % else \co@NAME == BEGIN eval\@thmcounter{NAME} END % \NAME == \@theorem{NAME}{TEXT} % \endNAME == \endlist % else error % fi % END % % \newtheorem{NAME}[OLDNAME]{TEXT}== % BEGIN % if \NAME is definable % then \co@NAME == \co@OLDNAME % \NAME == \@theorem{OLDNAME}{TEXT} % \endNAME == \endlist % else error % fi % END % % \@theorem{NAME}{TEXT} == % BEGIN % \@refstepcounter{NAME} % \list{}{\labelwidth := 0pt % \leftmargin := 0pt % \@thmlistcmd } % \item[\@makethmnumber{TEXT}{\co@NAME}] % END \def\newtheorem#1{\@ifnextchar[{\@oldtheorem{#1}}{\@newtheorem{#1}}} \def\@newtheorem#1#2{% \@ifnextchar[{\@xnewtheorem{#1}{#2}}{\@ynewtheorem{#1}{#2}}} \def\@xnewtheorem#1#2[#3]{\expandafter\@ifdefinable\csname #1\endcsname {\@definecounter{#1}\@addtoreset{#1}{#3}% \expandafter\edef\csname co@#1\endcsname{\expandafter\noexpand \csname co@#3\endcsname \@thmcountersep \@thmcounter{#1}}% \@namedef{#1}{\@theorem{#1}{#2}}\@namedef{end#1}{\endlist}}} \def\@ynewtheorem#1#2{\expandafter\@ifdefinable\csname #1\endcsname {\@definecounter{#1}% \expandafter\edef\csname co@#1\endcsname{\@thmcounter{#1}}% \@namedef{#1}{\@theorem{#1}{#2}}\@namedef{end#1}{\endlist}}} \def\@oldtheorem#1[#2]#3{\expandafter\@ifdefinable\csname #1\endcsname {\@namedef{co@#1}{\@nameuse{co@#2}}% \@namedef{#1}{\@theorem{#2}{#3}}% \@namedef{end#1}{\endlist}}} \def\@theorem#1#2{\@refstepcounter{#1}\list{}{\labelwidth\@zero \leftmargin\@zero\@thmlistcmd}\item[\@makethmnumber{#2}{\@nameuse{co@#1}}]} %DEFAULT VALUES \def\@thmcounter#1{\noexpand\arabic{#1}} \def\@thmcountersep{.} \def\@makethmnumber#1#2{\bf #1 #2:} \let\@thmlistcmd=\relax % **************************************** % * LENGTHS * % **************************************** % % USER COMMANDS: % % \newlength{\NAME} == \newskip\NAME % \setlength{\NAME}{VALUE} == \NAME :=L VALUE % \addtolength{\NAME}{VALUE} == \NAME :=L \NAME + VALUE % \settowidth{\NAME}{TEXT} == \NAME :=L width of \hbox{TEXT} % \def\newlength#1{\@ifdefinable#1{\newskip#1}} \def\setlength#1#2{#1#2} \def\addtolength#1#2{\advance#1 #2} \def\settowidth#1#2{\setbox\@tempboxa\hbox{#2}#1\wd\@tempboxa} % ***************************************** % * TABLE OF CONTENTS, ETC. * % ***************************************** % % CONVENTIONS: % t@foo = T if and only if table foo should be produced. % It should be set to true only if @tfile = true. % \tf@foo = file number for output. % % \contentsline{TYPE}{ENTRY}{PAGE} % Macro to produce a TYPE entry in a table of contents, etc. % It will appear in the .TOC or other file. For example, % The entry for subsection 1.4.3 in the table of contents might % be produced by: % \contentsline{subsection}{\makebox{30pt}[r]{1.4.3} Gnats and Gnus}{22} % The \writecommand command is used to write command sequences % without expanding them. % % \l@TYPE{ENTRY}{PAGE} % Macro defined by document style for making an entry of % type TYPE in a table of contents, etc. E.g., the document % style should define \l@chapter, \l@section, etc. % % \addtocontents{TABLE}{TYPE}{ENTRY} % User command for adding his own entry to a table of contents, etc. % It adds the entry % \contentsline{TYPE}{ENTRY}{page} % to the .TABLE file. % % \addtocontents{TABLE}{TYPE}{ENTRY} == % BEGIN % if \t@TABLE = T % then \@temptokena := \co@page % \@tempa == write \string\contentsline % {TYPE}{ENTRY}{\the\@temptokena} % \@tempa % fi % END % % \writecommand{\FOO} == \string\FOO % % Here's how you define a \tableofcontents or similar command: % \newif\ift@toc % Define the t@toc switch % \newwrite\tf@toc % Define the file \tf@toc % \def\tableofcontents{% % \begin{center} % \big CONTENTS % write ``CONTENTS'' % \end{center} % \par % \vskip 20pt % add vertical space % \@input{\jobname.toc} % read the old .toc file % \if@tfile % \global\t@toctrue % \global in case inside an environment % \openout\tf@toc=\jobname.toc % \else \global\t@tocfalse % \fi} \def\addtocontents#1#2#3{\csname ift@#1\endcsname \@temptokena{\co@page}% \edef\@tempa{\expandafter% \write\csname tf@#1\endcsname{\string\contentsline{#2}{#3}{\the\@temptokena}}}% \@tempa\fi} \def\contentsline#1{\csname l@#1\endcsname} \def\writecommand#1{\string#1} % **************************************** % * INITIAL DECLARATION COMMANDS * % **************************************** % % DOCUMENT STYLE AND PAGE LAYOUT % ------------------------------ % % The user specifies a page layout style with a command % \pagelayout{ARG1,ARG2,...,ARGn}. For each i: if there is a predefined % page layout macro \pl@ARGi, then that macro is executed. Otherwise, % the file ARGi.PLO is \input. % % The \documentstyle command is similar, except that the macro name is % \ds@ARGi and the file name is ARGi.STY . % % \pagelayout{ARGLIST} == % BEGIN % for \@cursty := ARGLIST % do if \pl@[eval(\@cursty)] undefined % then \input [eval(\@cursty)].PLO % else \pl@[eval(\@cursty)] % od % END % % \documentstyle{ARGLIST} == % BEGIN % for \@cursty := ARGLIST % do if \ds@[eval(\@cursty)] undefined % then \input [eval(\@cursty)].STY % else \ds@[eval(\@cursty)] % od % END % \def\pagelayout#1{\@for\@cursty:=#1\do {\@ifundefined{pl@\@cursty}{\input \@cursty.PLO}{\@nameuse{pl@\@cursty}}}} \def\documentstyle#1{\@for\@cursty:=#1\do {\@ifundefined{ds@\@cursty}{\input\@cursty.STY}{\@nameuse{ds@\@cursty}}}} % **************************************** % * INDEX COMMANDS * % **************************************** % % \makeindex == % BEGIN % if \@tfile = T % then open file \jobname.IDX as \@indexfile % \index{ITEM} == % BEGIN % \@bsphack % write of {\indexentry{ITEM}{page number}} % \@esphack % END % fi % END % % INITIALIZATION: % % \index{ITEM} == BEGIN \@bsphack \@esphack END % \def\makeindex{\if@tfile \newwrite\@indexfile \immediate\openout\@indexfile=\jobname.IDX \def\index##1{\@bsphack{\let\co@page\relax \xdef\@gtempa{\write\@indexfile{\string \indexentry{##1}{\co@page}}}}\@gtempa \if@nobreak \ifvmode\nobreak\fi\fi\@esphack}\typeout {Writing index file \jobname.IDX }\fi} \def\index#1{\@bsphack\@esphack} \def\makeglossary{\if@tfile \newwrite\@glossaryfile \immediate\openout\@glossaryfile=\jobname.IDX \def\glossary##1{\@bsphack{\let\co@page\relax \xdef\@gtempa{\write\@glossaryfile{\string \glossaryentry{##1}{\co@page}}}}\@gtempa \if@nobreak \ifvmode\nobreak\fi\fi\@esphack}\typeout {Writing glossary file \jobname.IDX }\fi} \def\glossary#1{\@bsphack\@esphack} % **************************************** % * BIBLIOGRAPHY * % **************************************** % % A bibliography is created by the bibliography environment, which % generates a title such as ``References'', and a list of entries. % The BIBTeX program will create a file containing such an environment, % which will be read in by the \bibliography command. % % The bibliography environment is a list environment. Instead % of using \item items in the bibliography are % produced by the following commands: % \bibitem{NAME} : Produces a numbered entry cited as NAME. % \bibitem[LABEL]{NAME} : Produces an entry labeled by LABEL and % cited by NAME. % The former is used for bibliographies with citations like [1], [2], etc.; % the latter is used for citations like [Knuth82]. % % The document style must define the bibliography environment. This % environment has a single argument, which is the widest bibliography % label-- e.g., if the [Knuth67] is the widest entry, then thist argument % will be Knuth67. The \bibliography command must begin a list environment, % which the \endbibliography command ends. % % Entries are cited by the command \cite{NAME}. % % PARAMETERS % % \@cite : A macro such that \@biblabelcite{LABEL1,LABEL2} % produces the output for a \cite{FOO1,FOO2} command, % where entry FOOi is defined by \bibitem[LABELi]{FOOi}. % The default definition is \@cite{FOO} -> [FOO] % \@bibnum : A macro such that \@bibnumcite produces the number % for a numbered citation. It has the default definition % \@bibnum -> \arabic{list}. % \@biblabel : A macro to produce the label in the bibliography % entry. For \bibitem[LABEL]{NAME}, the label is % generated by \@biblabel{LABEL}. It has the default % definition \@biblabel{LABEL} -> [LABEL]. % CONVENTION % % \b@FOO : The name or number of the reference created by \cite{FOO} % E.g., if \cite{FOO} -> [17] , then \b@FOO -> 17. % % A typical \bibliography definition would be % \def\bibliography#1{% % \begin{center} % To generate the 'BIBLIOGRAPHY' % \big BIBLIOGRAPHY % \end{center} % \vskip 15pt % Leave some extra space. % \list{\@biblabel{\@bibnum}} % For numbered items. % {\settowidth\labelwidth{\@biblabel{#1}} % set \labelwidth % \leftmargin\labelwidth % set \leftmargin % \addtolength\leftmargin\labelsep}} % % \def\bibitem{\@ifnextchar[{\@lbibitem}{\@bibitem}} \def\@lbibitem[#1]#2{\item[#1]\if@afile \immediate\write\@auxout {\string\bibcite{#2}{#1}}\fi\ignorespaces} \def\@bibitem#1{\item\if@afile \immediate\write\@auxout {\string\bibcite{#1}{\@bibnum}}\fi\ignorespaces} \def\bibcite#1#2{\global\@namedef{b@#1}{#2}} \def\cite#1{\def\@citea{}\@cite{\@for\@citeb:=#1\do {\@citea\def\@citea{,}\@ifundefined {b@\@citeb}{{\bf ?}\typeout {Citation \@citeb\space on page \co@page \space undefined.}}% {\csname b@\@citeb\endcsname}}}} %DEFAULT DEFINITIONS \def\@cite#1{[#1]} \def\@bibnum{\arabic{list}} \let\@biblabel=\@cite % **************************************** % * DEBUGGING AND TEST INITIALIZATIONS * % **************************************** % % DEBUGGING \tracingonline=1 \tracingstats1 % SHOWS HOW MUCH STUFF TeX HAS USED \def\showoutput{\tracingonline1\tracingoutput1 \showboxbreadth99999\showboxdepth99999\errorstopmode} \def\makeatletter{\catcode`\@=11 } \def\makeatother{\catcode`\@=12 } % TEMPORARY DEFINITIONS \def\clearpage{\par\vfil\eject} \font\tenln=line10 \font\tenlnw=linew10 \def\normal{\rm} % OUTPUT FOR INITIAL TESTING \output{\typeout{Page \co@page.}\shipout\box255\@stepcounter{page}} \pagenumbering{roman} \def\co@equation{\@arabic\c@equation} \tracingstats1 % SHOWS HOW MUCH STUFF TeX HAS USED \hsize = 450pt \linewidth\hsize \parskip = 5pt plus 2pt \def\@lowpenalty{51} \def\@midpenalty{151} \def\@highpenalty{301} % LIST \def\topsepcorrection{.25} \@beginlistpenalty = -200 \@itempenalty = -100 \def\d@leftmargin{3em} \def\d@labelwidth{2.3em} \def\d@labelsep{.7em} % ENUMERATION \let\@enumspacing=\relax \def\enum@i@margin{2em} \def\ce@enum@i{\arabic{enum@i}.} \def\co@enum@i{\arabic{enum@i}} \def\enum@ii@margin{2em} \def\ce@enum@ii{\Alph{enum@ii}.} \def\co@enum@ii{\co@enum@i\Alph{enum@ii}} \def\enum@iii@margin{2em} \def\ce@enum@iii{\roman{enum@iii}.} \def\co@enum@iii{\co@enum@ii\roman{enum@iii}} \def\enum@iv@margin{1.7em} \def\ce@enum@iv{(\alph{enum@iv})} \def\co@enum@iv{\co@enum@iii(\alph{enum@iii})} % ITEMIZE \let\@itemspacing=\relax \def\item@i{---} % Should be $\bullet$ \def\item@i@margin{2.5em} \def\item@ii{=\kern -.2em=} %should be $*$ \def\item@ii@margin{2.5em} \def\item@iii{\raise .5ex\hbox{.}} %Should be --- \def\item@iii@margin{2.5em} \def\item@iv{:} % Should be $\cdot$ \def\item@iv@margin{2.5em} % ARRAY AND TABULAR \arraycolsep = 5pt \tabcolsep = 6pt \arrayrulewidth = .4pt \doublerulesep = 2pt % THE PICTURE ENVIRONMENT \unitlength = 1pt \fboxsep = 3pt \fboxrule = .4pt % **************************************** % * OUTPUT * % **************************************** % % % PAGE LAYOUT PARAMETERS % % \topmargin : Extra space added to top of page. % @twoside : boolean. T if two-sided printing % \oddsidemargin : IF @twoside = T % THEN extra space added to left of odd-numbered % pages. % ELSE extra space added to left of all pages. % \evensidemargin : IF @twoside = T % THEN extra space added to left of even-numbered % pages. % \headheight : height of head % \headsep : separation between head and text % \footheight : height of foot % \footsep : separation between text and foot % \textheight : height of text on page, excluding head and foot % \textwidth : width of printing on page % \columnsep : IF @twocolumn = T % THEN width of space between columns % \columnseprule : IF @twocolumn = T % THEN width of rule between columns (0 if none). % \columnwidth : IF @twocolumn = T % THEN (\textwidth - \columnsep)/2 % ELSE \textwidth % It is set by the \@maketwocolumn and \@makeonecolumn % commands. % % PAGE STYLE PARAMETERS: % % \floatsep : Space left between floats. % \textfloatsep : Space between last top float or first bottom float % and the text. % \intextsep : Space left on top and bottom of an in-text float. % \footruleheight : Height of rule separating footnotes from text. % \footruleshift : Amount that the rule is shifted up from its ``natural'' % position just below the last line of the main text. % It must be a nonnegative dimension. % \footinsertskip : Space between main text and footnotes. The rule % separating footnotes from text occurs in this space. % \@fptop : Glue to go at top of float column -- must be 0pt + % stretch % \@fpsep : Glue to go between floats in a float column. % \@fpbot : Glue to go at bottom of float column -- must be 0pt + % stretch % \@dblfptop, \@dblfpsep, \@dblfpbot % : Analogous for double-column float page in two-column % format. % % PAGE LAYOUT SWITCHES AND MACROS % % @twocolumn : Boolean. T if two columns per page. % % PAGE STYLE MACROS AND SWITCHES % % \@oddhead : IF @twoside = T % THEN macro to generate head of odd-numbered pages. % ELSE macro to generate head of all pages. % \@evenhead : IF @twoside = T % THEN macro to generate head of even-numbered pages. % \@oddfoot : IF @twoside = T % THEN macro to generate foot of odd-numbered pages. % ELSE macro to generate foot of all pages. % \@evenfoot : IF @twoside = T % THEN macro to generate foot of even-numbered pages. % \@footnote{NUMBER} : The environment within which a footnote numbered % \end@footnote NUMBER is composed. It is called with TeX in % internal vertical mode, with the appropriate \hsize. % This environment can assume nothing else about its % context. It must set things like font size, % \parskip and \parindent. % % @specialpage : boolean. T if current page is to have a special format. % \@specialstyle : If its value is foo then % IF @specialpage = T % THEN the command \ps@foo is executed to temporarily % reset the page style parameters before composing % the current page. This command should execute % only \def's and \edef's, making only local % definitions. % \@clearpagestyle : If its value is foo, then \ps@foo is executed to reset % the page style on the last float page output by a % \clearpage command if it is a left-hand page. % % % FLOAT PLACEMENT PARAMETERS % % The following parameters are set locally at the beginning of % each one-column page or column of a two-column page by the macro % \@floatplacement, and at the beginning of each two-column page % by the macro \@dblfloatplacement. These macros are defined by the % \floatstyle command. When they are called, \@colht is the % height of the page or column being built. I.e.: % * For single-column page it equals \textheight. % * For double-column page it equals \textheight - height % of double-column figures on page. % % \@topnum : Maximum number of floats allowed on the top of a column. % \@toproom : Maximum amount of top of column devoted to floats-- % excluding \textfloatsep separation below the floats and % \floatsep separation between them. For two-column % output, should be computed as a function of \@colht. % \@botnum, \@botroom % : Analogous to above. % \@colnum,\@colroom % : Analogous to the above, except it applies to all floats, % including in-text ones. % % The macro \@dblfloatchange should also locally define any of the % following parameters that are different for double-column figures than % for single-column ones: % \@floatsep, \@textfloatsep, \@fpmin, \@fpsep, \@fptop, % \@fpbot. % % % CALLING THE OUTPUT ROUTINE % -------------------------- % % The output routine is called either by TeX's normal page-breaking % mechanism, or by a macro putting a penalty < or = -10000 in the output % list. In the latter case, the penalty indicates why the output % routine was called, using the following code. % % penalty reason % ------- ------ % -10000 \pagebreak % \newpage % -10001 \clearpage % -10002 float insertion, called from horizontal mode % -10003 float insertion, called from vertical mode % % % THE OUTPUT ROUTINE % ------------------ % % FUNCTIONS USED IN THE OUTPUT ROUTINE: % % \@outputpage : Produces an output page with the contents of box % \@outputbox as the text part. Also sets % \@colht :=G \textheight. The page style is determined % as follows. % If \outputpenalty = -10001 % then if (@twoside = true and \@dbldeferlist = empty) or % (@twoside = false and \@deferlist = empty) % then use \clearpage style % else use ordinary page style % else if @thispagestyle = true % then use \thispagestyle style % else use ordinary page style. % % \@tryfcolumn\FLIST : Tries to form a box composed of floats from \FLIST, % with the following parameters: % \@colht : height of box % \@fpmin : minimum height of floats in the box % \@fpsep : interfloat space % \@fptop : glue at top of box % \@fpbot : glue at bottom of box. % If it succeeds, then it does the following: % * \@outputbox :=L the composed float box. % * @fcolmade :=L true % * \FLIST :=G \FLIST - floats put in box % * \@freelist :=G \@freelist + floats put in box % If it fails, then: % * @fcolmade :=L false % % \@startnewcolumn\FLIST : Calls \@tryfcolumn\FLIST. If \@tryfcolumn % returns with @fcolmade = false, then: % * Globally sets \@toplist and \@botlist to floats % from \FLIST, deleting them from \FLIST. It does % this using \@colht as the total height, the page % style parameters \@floatsep and \@textfloatsep, and % the float placement parameters \@topnum, \@toproom, % \@botnum, \@botroom, \@colnum and \@colroom. % * Globally sets \@colroom to \@colht minus the height % of the added floats. % % \@combinefloats\TOPLIST\BOTLIST : Combines the text from box % \@outputbox with the floats from \TOPLIST and \BOTLIST, % putting the new box in \@outputbox. It uses \@colht % as the height of the box and \floatsep and \textfloatsep % for the appropriate separations. It puts the elements % of \TOPLIST and \BOTLIST onto \@freelist, and makes % those lists null. % % \@makeupcolumn : Makes the contents of \box255 plus the accumulated % footnotes, plus the floats in \@toplist and \@botlist, % into a single column of width \columnwidth and height % \@colht, which it puts into box \@outputbox. It % uses \@combinefloats. % % \@outputcolumn : Outputs a column whose text is in box \@outputbox. % If @twocolumn = false, then it calls \@outputpage, % sets \@colht :=G \textheight, and calls \@floatplacement. % % If @twocolumn = true, then: % If @firstcolumn = true, then it puts box \@outputbox % into \@leftcolumn sets @firstcolumn :=G false, % and calls \@dblfloatplacement. % % If @firstcolumn = false, then it puts out the % current two-column page, any possible two-column % float pages, determines \@dbltoplist and % \@dblbotlist for the next page, globally sets \@colht, % sets @firstcolumn :=G true, and calls \@dblfloatplacement. % % \@makeflist\FLIST : Sets \@flsucceed to a float list containing the % first float in \FLIST plus as many following floats as % will fit on a page of height \@colht with interfloat % separation \@fpsep. Sets \@flfail to the remaining floats % from \FLIST. Assumes \FLIST has at least one float. % % \@outputcolumn == % BEGIN % if @twocolumn = true % then if @firstcolumn = true % then @firstcolumn :=G false % \@leftcolumn :=G \@outputbox % else @firstcolumn :=G true % \begingroup % \@outputbox := \hbox to \textwidth % {\box\@leftcolumn % \hfil \vrule width \columnseprule \hfil % \@outputbox} % \@dblfloatchange % \@combinefloats\@dbltoplist\@dblbotlist % @fcolmade := true % while @fcolmade = true % do \@outputpage % \@dblfloatplacement % \@startnewcolumn\@dbldeferlist % od % \@colht :=G \@colroom % \endgroup % fi % \@dblfloatplacement % else \@outputpage % \@floatplacement % fi % END % % % \output == % BEGIN % case of \outputpenalty % > or = -10000 -> \@makeupcolumn % \@outputcolumn % \@startnewcolumn\@deferlist % while @fcolmade = true % do \@outputcolumn % \@startnewcolumn\@deferlist % od % -10001 -> if footnote insert nonempty % then \@makeupcolumn % \@outputcolumn % \vbox{} \penalty -10001 % else \@deferlist :=G \@toplist * \@botlist % * \@deferlist % \begingroup % \@floatplacement % \@fpmin :=L 0pt % \@tryfcolumn\@deferlist % while @fcolmade = true % do \@outputcolumn % \@tryfcolumn\@deferlist % od % \endgroup % if @twocolumn % then \@dbldeferlist :=G \@dbltoplist % * \@dblbotlist * \@dbldeferlist % \begingroup % \@dblfloatplacement % \@fpmin :=L 0pt % \@tryfcolumn\@dbldeferlist % while @fcolmade = true % do \@outputpage % \@tryfcolumn\@dbldeferlist % od % \endgroup % fi % fi % -10002 or 3 -> \@addtocurcol % end case % END % % % USER COMMANDS THAT CALL THE OUTPUT ROUTINE % ------------------------------------------ % % \cleardoublepage == % BEGIN % \clearpage % if @twocolumn % then if @firstcol = T % else \vbox{} \newpage % fi % else if \c@page even % then \thispagestyle{clearpage} % \vbox{} \newpage % fi fi % END % % FLOAT-HANDLING MECHANISMS % ------------------------- % % The float environment obtains an insertion number B from the % \@freelist (see below for a description of list manipulation), puts % the float into box B and sets \count B to a FLOAT SPECIFIER. For % a normal (not double-column) float, it then causes a page break % in one of the following two ways: % - In outer hmode: \vadjust{\penalty -10002} % - In vmode : \penalty -10003. % For a double-column float, it puts B onto the \@dbldeferlist. % The float specifier has two components: % * A PLACEMENT SPECIFICATION, describing where the float may % be placed. % * A TYPE, which is a power of two--e.g., figures might be % type 1 floats, tables type 2 floats, programs type 4 floats, etc. % The float specifier is encoded as follows, where bit 0 is the least % significant bit. % % Bit Meaning % --- ------- % 0 1 iff the float may go where it appears in the text. % 1 1 iff the float may go on the top of a page. % 2 1 iff the float may go on the bottom of a page. % 3 1 iff the float may go on a float page. % 4 1 iff a type 1 float % 5 1 iff a type 2 float % etc. % % % MACROS AND DATA STRUCTURES FOR PROCESSING FLOATS % ------------------------------------------------ % % A FLOAT LIST consisting of the floats in boxes b1 ... bN has the form: % \@elt \breg1 ... \@elt \bregN % where \bregI is defined by % \newcount\bregI \bregI = bi . % Normally, \@elt is \let to \relax. A test can be performed on the entire % float list by locally \def'ing \@elt appropriately and executing % the list. This is a lot more efficient than looping through the list. % % The following macros are used for manipulating float lists. % % \@next \CS \LIST {NONEMPTY}{EMPTY} == %% NOTE: ASSUME \@elt = \relax % BEGIN assume that \LIST == T1 T2 ... Tn % if n = 0 % then EMPTY % else \CS :=L T2 % \LIST :=G T3 ... Tn % NONEMPTY % fi % END % % % \@bitor\NUM\LIST : Globally sets switch @test to the disjunction for all I % of bit log2 \NUM of the float specifiers of all the floats in % \LIST. I.e., @test is set to true iff there is at least one % float in \LIST having bit log2 \NUM of its float specifier % equal to 1. % % Note: log2 [(\count I)/16] is the bit number corresponding to the % type of float I. To see if there is any float in \LIST having % the same type as float I, you run \@bitor with \NUM = (\count I)/16. % % \@bitor\NUM\LIST == % BEGIN % @test :=G false % { \@elt \CTR == if \count\CTR / \NUM is odd % then @test := true fi % \LIST % } % END % % % \@cons\LIST\NUM : Globally sets \LIST := \LIST * \@elt \NUM % % \@cons\LIST\NUM == % BEGIN { \@elt == \relax % \LIST :=G \LIST \@elt \NUM % } % % BOX LISTS FOR FLOAT-PLACEMENT ALGORITHMS % % \@freelist : List of empty boxes for placing new floats. % \@toplist : List of floats to go at top of current column. % \@midlist : List of floats in middle of current column. % \@botlist : List of floats to go at bottom of current column. % \@deferlist : List of floats to go after current column. % \@dbltoplist : List of double-col. floats to go at top of current page. % \@dblbotlist : List of double-col. floats to go at bot. of current page. % \@dbldeferlist : List of double-column floats to go on subsequent pages. % % FLOAT-PLACEMENT ALGORITHMS % % \@makeflist\FLIST == %% NOTE: assumes \@elt == \relax % BEGIN % \@gtempa :=G \FLIST % \@next\@tempa\@gtempa{}{} % \@flfail :=G null % { \@tempdima :=L ht of box \@tempa + \@fpsep % \@elt\BOX == BEGIN \@tempcnta :=L \count\BOX / 16 % \@bitor\@tempcnta\flfail % if @test = true % then \@cons\@flfail\BOX % else \@tempdima :=L \@tempdima - \ht \BOX % if \@tempdima > \@colht % then \@tempdima :=L \@tempdima + \ht \BOX % \@cons\@flfail\BOX % else \@tempdima :=L \@tempdima + \@fpsep % \@cons\@succeed\BOX % END % \@gtempa % } % END % % \@addtobot : Tries to put insert \@currbox on \@botlist. Called only when: % * \ht BOX + maximum(\floatsep, \textfloatsep) < \@colroom % * type of \@currbox not on \@deferlist % * \@floatnum > 0 % * \@floatroom > ht of \@currbox % * @insert = false % If it succeeds, then: % * sets @insert true % * decrements \@botroom and \@floatroom by \ht BOX % * decrements \@botnum and \@floatnum by 1 % * decrements \@colroom by \ht BOX + either \floatsep % or \textfloatsep, as appropriate. % % \@addtotoporbot : Tries to put insert \@currbox on \@toplist or \@botlist. % Called only under same conditions as \@addtobot. % If it succeeds, then: % * sets @insert true % * decrements \@floatroom and either \@toproom or % \@botroom by \ht BOX % * decrements \@floatnum and either \@topnum or % \@botnum by 1 % * decrements \@colroom by \ht BOX + either \floatsep % or \textfloatsep, as appropriate. % % \@addtocurcol : Tries to add \@currbox to current column, setting @insert % true if it succeeds, false otherwise. It will add % \@currbox to top only if bit 0 of \count \@currbox is 0, and % to the bottom only if bit 0 = 0 or an earlier float of % the same type is put on the bottom. % % \@addtonextcol : Tries to add \@currbox to the next column, setting @insert % true if it succeeds, false otherwise. % % \@addtobot == % BEGIN % if bit2 of \count \@currbox = 1 % then if \@botnum > 0 % then if \@botroom > \ht \@currbox % then \@botnum := \botnum - 1 % \@botroom := \@botroom - \ht\@currbox % \@floatnum := \floatnum - 1 % \@floatroom := \@floatroom - \ht\@currbox % \@colroom := \@colroom - \ht\@currbox - % if \@botlist empty % then \textfloatsep % else \floatsep % fi % add \@currbox to \@botlist % @insert :=G true % fi fi fi % END % % \@addtotoporbot == % BEGIN % if bit2 of \count \@currbox = 1 % then if \@topnum > 0 % then if \@toproom > \ht \@currbox % then if \@currtype not on \@midlist % then \@topnum := \topnum - 1 % \@toproom := \@toproom - \ht\@currbox % \@floatnum := \floatnum - 1 % \@floatroom := \@floatroom - \ht\@currbox % \@colroom := \@colroom - \ht\@currbox - % if \@toplist empty % then \textfloatsep % else \floatsep % fi % add \@currbox to \@toplist % @insert :=G true % fi fi fi fi % if @insert = false then \@addtobot fi % END % % \@addtocurcol == % BEGIN % @insert := false % \@currtype := type of \@currbox % if \@colroom > \ht \@currbox + \ht255 + \dp255 % maximum(\floatsep, \textfloatsep, \intextsep) % then if \@floatroom > \ht \@currbox % then if \@floatnum > 0 % then if \@currtype not on \@deferlist % then if \@currtype on \@botlist % then \@addtobot % else if bit0 of \count \@currbox = 1 % then decrement \@floatnum and % \@floatroom % put \@currbox on \@midlist % add \@currbox + space to text % decrement \@colroom % else \@addtotoporbot % fi fi fi fi fi fi % if @insert = false % then add \@currbox to \@deferlist % fi % END % % \@addtonextcol == % BEGIN % @insert := false % \@currtype := type of \@currbox % if \@colroom > \ht \@currbox + % maximum(\floatsep, \textfloatsep) % then if \@floatroom > \ht \@currbox % then if \@floatnum > 0 % then if \@currtype not on \@deferlist % then if \@currtype on \@botlist % then \@addtobot % else \@addtotoporbot % fi fi fi fi fi % if @insert = false % then add \@currbox to \@deferlist % fi % END