% LATEX VERSION 2.0 - RELEASE OF 11 Dec 83 % FOR USE WITH TEX VERSION 1.0 % Copyright (C) 1983 by Leslie Lamport \everyjob{\typeout{LaTeX Version 2.0 - Release 11 Dec 83}} \immediate\write10{LaTeX Version 2.0 - Release 11 Dec 83} \immediate\write10{For use with TeX version 1.0} % TABLE OF CONTENTS % COMMAND LIST ....................................... 2 % GENERAL CONVENTIONS .................................. 4 % COUNTERS, ETC. ....................................... 5 % USEFUL HACKS ......................................... 6 % ERROR HANDLING ....................................... 8 % \par AND \everypar ................................... 10 % SPACING / LINE AND PAGE BREAKING ..................... 11 % PROGRAM CONTROL STRUCTURE MACROS ..................... 14 % FILE HANDLING ........................................ 16 % ENVIRONMENT COUNTER MACROS ........................... 18 % PAGE NUMBERING ....................................... 20 % CROSS REFERENCING MACROS ............................ 21 % ENVIRONMENTS ......................................... 22 % MATH ENVIRONMENTS .................................... 24 % CENTER, FLUSHRIGHT, FLUSHLEFT, ETC. .................. 25 % VERBATIM ............................................. 26 % THE LIST ENVIRONMENT ................................. 27 % ITEMIZE AND ENUMERATE ................................ 31 % BOXES ................................................ 33 % THE TABBING ENVIRONMENT .............................. 36 % ARRAY AND TABULAR ENVIRONMENTS ....................... 40 % THE PICTURE ENVIRONMENT .............................. 46 % THEOREM ENVIRONMENTS ................................. 53 % LENGTHS .............................................. 55 % TABLE OF CONTENTS, ETC. .............................. 56 % INDEX COMMANDS ....................................... 57 % BIBLIOGRAPHY ......................................... 58 % FLOATS ............................................... 59 % FOOTNOTES ............................................ 63 % INITIAL DECLARATION COMMANDS ......................... 65 % OUTPUT ............................................... 66 % DEBUGGING AND TEST INITIALIZATIONS .................. 82 \catcode`\~=13 \def~{\penalty\@M \ } \catcode`\@=11 % **************************************** % * COMMAND LIST * % **************************************** % % DECLARATIONS: % PREAMBLE: \nofiles \pagelayout \documentstyle \includeonly % \makeindex \makeglossary % IN DOCUMENT : % FONT SELECTION: % SIZE: \normalsize \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 % verbatim picture float % PAR -> BOX: tabular tabbing % PAR -> MATH: math displaymath equation % MATH -> MATH: array % ANY -> PAR: minipage % 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 \footnotetext % \topnewpage \verb % 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 \skip\footin \intextsep % \columnseprule \oddsidemargin % \columnwidth \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 \shortstack\tabbing % \normalsize \tabular % \float \obeycr \thicklines % \flushleft \pagelayout \thinlines % \flushright \pagenumbering \thispagestyle % \verb, \verbatim % % PARAMETERS : % % \columnsep \footinsertskip \intextsep % \columnseprule \oddsidemargin % \columnwidth \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. % The following definitions save token space. E.g., using \@height % instead of height saves 5 tokens at the cost in time of one macro % expansion. \def\@height{height} \def\@depth{depth} \def\@width{width} % The following implements the LaTeX \{ and \} commands. \def\{{\relax\ifmmode\lbrace\else$\lbrace$\fi} \def\}{\relax\ifmmode\rbrace\else$\rbrace$\fi} % **************************************** % * COUNTERS, ETC. * % **************************************** % % THE FOLLOWING ARE FROM PLAIN: % \z@ : A zero dimen or number. It's more efficient to write % \parindent\z@ than \parindent 0pt. % \@ne : The number 1. % \m@ne : The number -1. % \tw@ : The number 2. % \sixt@@n : The number 16. % \@m : The number 1000. % % THE FOLLOWING ARE NEW TO LaTeX: % \@xxxii : The number 32 % \@M : The number 10000. % \@Mi : The number 10001. % \@Mii : The number 10002. % % \@sss : A skip of 0pt plus 1fill minus 1fill. % \@flushglue : Glue used for \right- & \leftskip to = 0pt plus 1fil \chardef\@xxxii=32 \mathchardef\@Mi=10001 \mathchardef\@Mii=10002 \mathchardef\@Miii=10003 % 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\@tempdima \newdimen\@tempdimb \newbox\@tempboxa \newskip\@sss \@sss = 0pt plus 1fill minus 1fill \newskip\@flushglue \@flushglue = 0pt plus 1fil \newskip\@tempskipa \newtoks\@temptokena % **************************************** % * USEFUL HACKS * % **************************************** % % \@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. % % \@ifstar{YES}{NO} : Gobbles following spaces and then tests if next the % character is a '*'. If it is, then it gobbles the % '*' and expands to YES, otherwise it expands to NO. % % \@dblarg\CS{ARG} : \@dblarg\CS{ARG} expands to \CS [ARG]{ARG}. Used % when \CS takes arguments [ARG1]{ARG2}. % % \@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. Produces an error if \FOO already defined. % % \renewcommand{\FOO}[i]{TEXT} : Same as \newcommand, except it doesn't % check if \FOO already defined. % % \newlist{\CS}{LARG1}{LARG2}{BLIST} : % if \CS is definable, then defines % \CS == \list{LARG1}{LARG2}BLIST\ignorespaces % \endCS == \endlist % \@cons : See description of \output routine. % % \@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 % % \typein[\CS]{MSG} : Same as above, except defines \CS to be the input % instead of executing it. \newwrite\@unused \def\typein{\let\@typein\relax \@ifnextchar[{\@xtypein}{\@xtypein[\@typein]}} \def\@xtypein[#1]#2{\typeout{#2}\read0 to#1\ifx #1\@defpar \def#1{}\else \expandafter\@strip\expandafter #1#1\@@\fi\@typein} \def\@strip#1#2 \@@{\def #1{#2}} \def\@defpar{\par} \def\typeout#1{\immediate\write\@unused{#1}} \def\@warning#1{\typeout{LaTeX Warning: #1.}} \def\@namedef#1{\expandafter\def\csname #1\endcsname} \def\@nameuse#1{\csname #1\endcsname} \def\@cons#1#2{\begingroup\let\@elt\relax\xdef#1{#1\@elt #2}\endgroup} \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\newcommand#1{\@ifnextchar [{\@argdef#1}{\@argdef#1[0]}} \def\renewcommand#1{\@ifnextchar [{\@reargdef#1}{\@reargdef#1[0]}} \def\newlist#1#2#3#4{\expandafter\@ifdefinable \csname #1\endcsname{\expandafter\def\csname #1\endcsname{\list {#2}{#3}#4\ignorespaces}\expandafter\let\csname end#1\endcsname\endlist}} \long\def\@argdef#1[#2]#3{\@ifdefinable #1{\@reargdef#1[#2]{#3}}} \long\def\@reargdef#1[#2]#3{\@tempcnta#2\relax\let#1\relax \edef\@tempa{\long\def#1}\@tempcntb \@ne \let\@tempb\relax\@whilenum\@tempcnta>0 \do{\edef\@tempa{\@tempa\@tempb\the\@tempcntb}\advance\@tempcntb \@ne \advance \@tempcnta \m@ne}\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\@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} % NOTE: the following hacking must precede the definition of \: % as math medium space. \def\:{\let\@sptoken= } \: % this makes \@sptoken a space token \def\:{\@xifnch} \expandafter\def\: {\futurelet\@tempc\@ifnch} \def\@ifstar#1#2{\@ifnextchar *{\def\@tempa*{#1}\@tempa}{#2}} \long\def\@dblarg#1{\@ifnextchar[{#1}{\@xdblarg#1}} \long\def\@xdblarg#1#2{#1[#2]{#2}} % **************************************** % * ERROR HANDLING * % **************************************** % % \@latexerr{MSG}{HLP}: Types a LaTeX error message MSG and gives an error % halt with error help message HLP. % \newlinechar`\^^J \def\@latexerr#1#2{\begingroup \edef\@tempc{#2}\expandafter\errhelp\expandafter{\@tempc}% \typeout{LaTeX error. \space See LaTeX manual for explanation.^^J \space\@spaces\@spaces\@spaces Type \space H \space for immediate help.}\errmessage{#1}\endgroup} \def\@spaces{\space\space\space\space} %% error help message pieces. \def\@eha{Your command was ignored. ^^JType \space I \space to replace it with another command,^^Jor \space \space to continue without it.} \def\@ehb{You've lost some text. \space \@ehc} \def\@ehc{Try typing \space \space to procede.^^JIf that doesn't work, type \space X \space to quit.} \def\@ehd{You're in trouble here. \space\@ehc} % Here are all the error message-generating commands of LaTeX. % % \@notdefinable : Error message generated in \@ifdefinable from calls % by \newcommand, \newlength, \newtheorem specifying an % already-defined command name. % % \@nolnerr : Generated by \newline and \\ when called in vertical mode. % % '\newnumbering of -- illegal' : Generated in \newnumbering. % % \@nocnterr : Generated by \setcounter, \addtocounter or \newnumbering % for undefined counter. % % \@ctrerr : Called when trying to print the value of a counter % numbered by letters that's greater than 26. % % 'Environment --- undefined' : Issued by \begin for undefined environment. % % \@badend : Called by \end that doesn't match its \begin. % % \@badmath : Called by \[, \], \( or \) when used in wrong mode. % % \@toodeep : Called by a list environment nested more than six levels % deep, or an enumerate or itemize nested more than four % levels. % % \@badpoptabs : Called by \endtabbing when not enough \poptabs have % occurred, or by \poptabs when too many have occurred. % % \@badtab : Called by \>, \+ , \- or \< when stepping to an undefined tab. % % 'tab overflow' : Occurs in \= when maximum number of tabs exceeded. % % '\< in mid line' : Occurs in \< when it appears in middle of line. % % \@preamerr : Occurs in array or tabular environment, or in \multicolumn % command, when error in preamble detected. % % \@badlinearg : Occurs in \line and \vector command when a bad slope % argument is encountered. % % \@parmoderr : Occurs in a float environment or a \marginpar when % encountered in inner vertical mode. % % \@fltovf : Occurs in float environment or \marginpar when there % are no more free boxes for storing floats. % % 'Two-column float on one-column page' : Occurs in dblfloat environment. % % \@latexbug : Occurs in output routine. This is bad news. % % 'Float(s) lost' : In output routine, caused by a float environment or % \marginpar occurring in inner vertical mode. % % \@nofonterror : Typeface not available. % % \@badcrerr : A \\ used where it shouldn't be in a centering or flushing % environment. % \def\@notdefinable{\@latexerr{Command name '\@tempa' already used}\@eha} \def\@nolnerr{\@latexerr{There's no line here to end}\@eha} \def\@nocnterr{\@latexerr{No such counter}\@eha} \def\@ctrerr{\@latexerr{Counter too large}\@ehb} \def\@nodocument{\@latexerr{Missing \string\begin{\@currenvir}}\@ehd} \def\@badend#1{\@latexerr{\string\begin{\@currenvir} ended by \string\end{#1}}\@eha} \def\@badmath{\@latexerr{Bad math environment delimiter}\@eha} \def\@toodeep{\@latexerr{Too deeply nested}\@ehd} \def\@badpoptabs{\@latexerr{\string\pushtabs \space and \string\poptabs \space don't match}\@ehd} \def\@badtab{\@latexerr{Undefined tab position}\@ehd} \def\@preamerr#1{\@latexerr{\ifcase #1 Illegal character\or Missing @-exp\or Missing p-arg\fi\space in preamble}\@ehd} \def\@badlinearg{\@latexerr{Bad \string\line\space or \string\vector \space argument}\@ehb} \def\@parmoderr{\@latexerr{Not in outer par mode}\@ehb} \def\@fltovf{\@latexerr{Too many unprocessed floats}\@ehb} \def\@latexbug{\@latexerr{This is a LaTeX bug}{Call for help}} \def\@nofonterror{\@latexerr{Typeface not available}\@eha} \def\@badcrerr {\@latexerr{Bad use of \string\\}\@ehc} % **************************************** % * \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. % % WARNING: Commands that set \everypar null should remember that it % might be supposed to set @nobreak false; they should do the setting % if necessary. \def\@par{\let\par=\@@par\par} \def\@setpar#1{\def\par{#1}\def\@par{#1}} \def\@restorepar{\def\par{\@par}} % ********************************************** % * 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 % Note: \\* adds a \vadjust{\penalty 10000} \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 >\z@ \hskip\@tempskipa\ignorespaces\fi\fi} \def\linebreak{\@ifnextchar[{\@lnbk}{\@lnbk[4]}} \def\@lnbk[#1]{\ifvmode \@nolnerr\else \unskip\penalty -\@getpen{#1}\fi} \def\newline{\ifvmode \@nolnerr \else \unskip\hfil \penalty -\@M\relax\fi} \def\@normalcr{\@ifstar{\vadjust{\penalty\@M}\@xnewline}{\@xnewline}} \def\@xnewline{\@ifnextchar[{\@newline}{\newline}} \def\@newline[#1]{\ifhmode\unskip\fi\vspace{#1}\newline} \let\\=\@normalcr \def\@getpen#1{\ifcase #1\relax 0 \or \@lowpenalty\relax \or \@midpenalty\relax \or \@highpenalty\relax \else \@M \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. % Commands that reset \everypar should globally set it false % if appropriate. % \newif\if@nobreak \@nobreakfalse % \@bsphack ... \@esphack % used by macros such as \index and \begin{@float} ... \end{@float} % 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 % \global\@ignoretrue fi % fi % END % \newdimen\@savsk \newcount\@savsf \def\@bsphack{\@savsk\lastskip \ifhmode\@savsf\spacefactor\fi} \def\@esphack{\relax\ifhmode\spacefactor\@savsf {}\ifdim \@savsk >\z@ \global\@ignoretrue \ignorespaces \fi \fi} % VERTICAL SPACING: % % LaTeX supports the PLAIN TeX commands \smallskip, \medskip and \bigskip. % However, it redefines them using \vspace instead of \vskip. % % The command \addvspace{SKIP} is used to put a vertical skip of SKIP into % the document. \addvspace{S1} \addvspace{S2} is equivalent to % \addvspace{maximum of S1, S2}. \addvspace should be used only in vertical % mode. It does nothing if @nobreak = true % % Note: the argument of \addvspace must be a register--either a skip % or a dimension register--or - a register, as in -\fooreg. % % \addvspace{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\addvspace#1{\if@nobreak\else \ifdim \lastskip =\z@ \vskip #1\relax\else \@xaddvskip{#1}\fi\fi} \def\@xaddvskip#1{\ifdim \lastskip <#1 \vskip-\lastskip\vskip #1\relax\else \ifdim #1<\z@ \ifdim \lastskip <\z@\else \vskip #1\relax\fi\fi\fi} \def\vspace{\@ifstar{\@vspacer}{\@vspace}} \def\@vspace#1{\ifvmode\vskip #1\relax\else \@bsphack\vadjust{\vskip #1}\@esphack\fi} \def\@vspacer#1{\ifvmode\vbox{\vskip #1}\else \@bsphack\vadjust{\vbox{\vskip #1}}\@esphack\fi} \def\smallskip{\vspace\smallskipamount} \def\medskip{\vspace\medskipamount} \def\bigskip{\vspace\bigskipamount} % HORIZONTAL SPACE % % NOTE: \s is a short form for \hspace, with no variant version. % It can be used in an @-expression in an array preamble. \def\hspace{\@ifstar{\@hspacer}{\@hspace}} \def\@hspace#1{\leavevmode\hskip #1} \def\@hspacer#1{\leavevmode\hbox{\hskip #1}} \def\s#1{\hskip #1\relax} % 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 and gets \topsep space above it iff he % leaves a blank line before the environment. If he does not leave % a blank line, then \topsep := \topsepcorrection * \parskip, and that % is the space left above the environment. % If the user leaves a blank line after the end of the paragraph environment, % then the text after the environment starts a new paragraph and gets % the maximum of \topsep and \parskip space above it and a \parindent % indentation. 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. % % Note: the stretch and shrink for \topsep and \parsep comes from % \parskip % % SURPRISE: An environment beginning with a \@beginparenv will leave % an extra \topsep space above it if it comes at the beginning of a % parbox or minipage. % % \@beginparenv == % BEGIN % if horizontal mode % then \topsep :=L \topsepcorrection * \topsep % fi % \@topsepadd := \topsep - \parskip % \par % \addvspace{\@topsepadd} % END % \@endparenv == % BEGIN % if horizontal mode then \par fi % \addvspace{\@topsepadd} % \endgroup %% ends the \begin command's \begingroup % \par == BEGIN % \@restorepar % \everypar{} % \par % \addvspace{0 pt} %% remove any negative skip % END % \everypar == BEGIN \hskip - \parindent \everypar{} END % \begingroup %% to match the \end commands \endgroup % END \def\@beginparenv{\ifhmode \topsep \topsepcorrection\topsep \fi \@topsepadd\topsep \advance\@topsepadd -\parskip \par\addvspace\@topsepadd} \def\@endparenv{\ifhmode\par\fi\addvspace\@topsepadd\endgroup \def\par{\@restorepar\everypar{}\par\addvspace\z@}% \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 \@filesw 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 \@filesw 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. % @filesw : Switch -- set false if no .AUX, .TOC, .IDX etc files are % to be % @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 % \@colht := \@colroom := \textheight % \hsize := \linewidth := \columnwidth % \begingroup % \@input{\jobname.aux} % \endgroup % if \@filesw = T % then open file \@mainaux for writing % write ``\relax''on file \@mainaux % fi % \begin == \@begin % END % % \includeonly{FILELIST} == % BEGIN % \@partsw := T % \@partlist := FILELIST % END % % \include{FILE} == % BEGIN % \clearpage % if \@filesw = 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 \@filesw = T % then \immediate\openout\@partaux{FILE.AUX} % \immediate\write\@partaux{\relax} % fi % \@input{FILE.TEX} % \clearpage % \@writeckpt{FILE} % if @filesw then \closeout \@partaux fi % \@auxout := \@mainaux % else \cp@FILE % fi % END % % \@writeckpt{FILE} == % BEGIN % if \@filesw = T % \immediate\write on file \@partaux: % \gdef\cp@FILE{ %% } % for \@tempa := \cl@@ckpt % do \immediate\write on file \@partaux: % \global\string\setcounter % {eval(\@tempa)}{eval(\c@eval(\@tempa))} % od %% { % \immediate\write on file \@partaux: } % fi % END % % INITIALIZATION % \@tempswa := T \newif\if@filesw \@fileswtrue \newif\if@partsw \@partswfalse \newwrite\@mainaux \newwrite\@partaux \def\document{\@colht\textheight \hsize\columnwidth \linewidth\hsize \@colroom\textheight \vsize\textheight \begingroup\@floatplacement\@dblfloatplacement \makeatletter\let\@writefile\@gobbletwo \@input{\jobname.aux}\endgroup \if@filesw \immediate\openout\@mainaux=\jobname.aux \immediate\write\@mainaux{\relax}\fi\normalsize\everypar{}\let\begin\@begin} \def\@gobbletwo#1#2{} \def\nofiles{\@fileswfalse \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}} \def\include#1{\clearpage \if@filesw \immediate\write\@mainaux{\string\@input{#1.AUX}}\fi \@tempswatrue\if@partsw \@tempswafalse\def\@tempb{#1}\@for \@tempa:=\@partlist\do{\ifx\@tempa\@tempb\@tempswatrue\fi}\fi \if@tempswa \if@filesw \let\@auxout=\@partaux \immediate\openout\@partaux #1.AUX \immediate\write\@partaux{\relax}\fi\@input{#1.TEX}\clearpage \@writeckpt{#1}\if@filesw \immediate\closeout\@partaux \fi \let\@auxout=\@mainaux\else\@nameuse{cp@#1}\fi} \def\@writeckpt#1{\if@filesw \immediate\write\@partaux{\string\global\string\@namedef{cp@#1}\@charlb}% {\let\@elt\@wckptelt \cl@@ckpt}\immediate\write\@partaux{\@charrb}\fi} \def\@wckptelt#1{\immediate\write\@partaux {\string\global\string\setcounter{#1}{\the\@nameuse{c@#1}}}} \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 % \@elt{countera}\@elt{counterb}\@elt{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: % \counter{COUNTER}: The printed value of COUNTER, in currently % defined style. % \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}\@eha}% {\@namedef{co@#1}{#2}}}} \def\@stepcounter#1{\global\expandafter\advance\csname c@#1\endcsname \@ne {\let\@elt\@stpelt \csname cl@#1\endcsname}} \def\@stpelt#1{\global\csname c@#1\endcsname \z@} \def\cl@@ckpt{\@elt{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\@cons\csname cl@#2\endcsname {{#1}}} % Numbering commands for \newnumbering and \list arguments \def\counter#1{\csname co@#1\endcsname} \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} % **************************************** % * 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 the page counter 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-, and \counter{page} can bee % used to generate page numbers in headings, etc. \countdef\c@page=0 \c@page=1 \def\cl@page{} \def\pagenumbering#1{\global\c@page \@ne \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@filesw {\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\@currentlabel{} % 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. % % \@enddocument == % BEGIN % \clearpage % \begingroup % if @filesw = true % then close file @mainaux % \global \@namedef {ARG1}{ARG2} == null % \newlabel{LABEL}{VAL} == % BEGIN % \@tempa == VAL % if def(\@tempa) = def(\r@LABEL) % else @tempswa := true fi % END % \bibcite{LABEL}{VAL} == null % BEGIN % \@tempa == VAL % if def(\@tempa) = def(\g@LABEL) % else @tempswa := true fi % END % @tempswa := false % make @ a letter % \input \jobname.AUX % if @tempswa = true % then LaTeX Warning: 'Label may have changed. % Rerun to get cross-references right.' % fi fi % \endgroup % finish up % END % % \@writefile{EXT}{ENTRY} == % if tf@EXT undefined % else \write\tf@EXT{ENTRY} % fi % \def\@currenvir{document} \newif\if@ignore \def\enddocument{\@enddocument} \def\@enddocument{\clearpage\begingroup \if@filesw \immediate\closeout\@mainaux \def\global\@namedef##1##2{}\def\newlabel{\@testdef r}% \def\bibcite{\@testdef b}\@tempswafalse \makeatletter\input \jobname.aux \if@tempswa \@warning{Label(s) may have changed. Rerun to get cross-references right}\fi\fi\endgroup\deadcycles\z@\@@end} \def\@testdef #1#2#3{\def\@tempa{#3}\expandafter \ifx \csname #1@#2\endcsname \@tempa \else \@tempswatrue \fi} \def\@writefile#1#2{\@ifundefined{tf@#1}{}{\expandafter \immediate\write\csname tf@#1\endcsname{#2}}} \def\stop{\clearpage\deadcycles\z@\@@end} \def\begin#1{\def\@tempa{#1}\ifx\@currenvir\@tempa \@document \else\@nodocument\fi} \def\@document{\def\enddocument{\fi\@enddocument}\document} \everypar{\@nodocument} %% To get an error if text appears before the \nullfont %% \begin{document} \def\@begin#1{\@ifundefined{#1}{\def\@tempa{\@latexerr{Environment #1 undefined}\@eha}}{\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} % ********************************************** % * 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 (...). % % \stackrel{TOP}{BOT} == PLAIN TeX's \buildrel {TOP} \over {BOT} % % \frac{TOP}{BOT} == {TOP \over BOT} % % \sqrt[N]{EXP} produces an Nth root of EXP formula. % % \: == \> (medium space) \def\({\relax\ifmmode\@badmath\else$%%$BRACE MATCH HACK \fi} \def\){\relax\ifmmode\ifinner$\else\@badmath%%$ BRACE MATCH HACK \fi\else \@badmath\fi} \def\[{\relax\ifmmode\@badmath\else$$%%$$ BRACE MATCH HACK \fi} \def\]{\relax\ifmmode\ifinner\@badmath\else$$\fi%%$$ BRACE MATCH HACK \else \@badmath \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} \def\stackrel#1#2{\mathrel{\mathop{#2}\limits^{#1}}} \def\frac#1#2{{#1\over #2}} \let\@@sqrt=\sqrt \def\sqrt{\@ifnextchar[{\@sqrt}{\@@sqrt}} \def\@sqrt[#1]{\root #1\of} \let\:=\> % ************************************************ % * CENTER, FLUSHRIGHT, FLUSHLEFT, ETC. * % ************************************************ % % % \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 % \\* == \par \penalty 10000 \vskip -\parskip % \\*[LEN] == \\* \vskip LENGTH % As with all paragraphing environments, they use \@beginparenv % and \@endparenv. % % \centering, \raggedright and \raggedleft are the declaration analogs % of the above. \def\@centercr{\ifhmode \unskip\else \@badcrerr\fi \par\@ifstar{\penalty \@M\@xcentercr}{\@xcentercr}} \def\@xcentercr{\addvspace{-\parskip}\@ifnextchar [{\@icentercr}{\ignorespaces}} \def\@icentercr[#1]{\vskip #1\ignorespaces} \def\center{\@beginparenv\centering\ignorespaces} \def\centering{\let\\=\@centercr\rightskip\@flushglue\leftskip\@flushglue \parindent\z@\parfillskip\z@} \let\endcenter=\@endparenv \def\flushleft{\@beginparenv\raggedright\ignorespaces} \def\raggedright{\let\\=\@centercr\rightskip\@flushglue\leftskip\z@ \parindent\z@\parfillskip\z@} \let\endflushleft=\@endparenv \def\flushright{\@beginparenv\raggedleft\ignorespaces} \def\raggedleft{\let\\=\@centercr\rightskip\z@\leftskip\@flushglue \parindent\z@\parfillskip\z@} \let\endflushright=\@endparenv % **************************************** % * VERBATIM * % **************************************** % % The verbatim environment uses the fixed-width \tt font, turns blanks into % spaces, starts a new line for each carrige return (or sequence of % consecutive carriage returns), and interprets EVERY character literally. % I.e., all special characters \, {, $, etc. are \catcode'd to 'other'. % % The command \verb produces in-line verbatim text, where the argument % is delimited by any pair of characters. E.g., \verb #...# takes % '...' as its argument, and sets it verbatim in \tt font. % % The *-variants of these commands is the same, except that spaces % print as the TeXbook's space character instead of as blank spaces. {\catcode`\^^M=13 \gdef\@gobblecr{\@ifnextchar {\@gobble}{\ignorespaces}}} {\catcode`\ =\active\gdef\@vobeyspaces{\catcode`\ \active \let \@xobeysp}} \def\@xobeysp{\leavevmode{} } \begingroup \catcode `|=0 \catcode `[= 1 \catcode`]=2 \catcode `\{=12 \catcode `\}=12 \catcode`\\=12 |gdef|@xverbatim#1\end{verbatim}[#1|end[verbatim]] |gdef|@sxverbatim#1\end{verbatim*}[#1|end[verbatim*]] |endgroup \def\@sverbatim{\obeyspaces\@verbatim} \def\@gobble#1{} \def\@verbatim{\@beginparenv \vskip\parskip \leftskip\@totalleftmargin\rightskip\z@ \parindent\z@\parfillskip\@flushglue\parskip\z@ \@tempswafalse \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par} \obeylines \tt \let\do\@makeother \dospecials} \def\verbatim{\@verbatim \frenchspacing\@vobeyspaces \@xverbatim} \let\endverbatim=\@endparenv \@namedef{verbatim*}{\@verbatim\@sxverbatim} \expandafter\let\csname endverbatim*\endcsname =\@endparenv \def\@makeother#1{\catcode`#112\relax} \def\verb{\begingroup \tt \let\do\@makeother \dospecials \@ifstar{\@sverb}{\@verb}} \def\@sverb#1{\def\@tempa ##1#1{##1\endgroup}\@tempa} \def\@verb{\obeyspaces \frenchspacing \@sverb} % **************************************** % * 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. A list counter can be used % with the \arabic, etc. commands to number the items. 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. % \@listdepth : A count for holding current list nesting depth. % 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: % % \topsep : Space between first item and preceding paragraph. % Works the same as for \@beginparenv. % \itemsep : Space between successive items. % \parsep : Space between paragraphs within an item -- the \parskip % for this environment. % \parstretch : A skip of 0 plus stretch to provide the stretch % for the above parameters, which are all dimens. % % 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 : nominal width of box that contains the label. % However, if the natural width of the label % is greater than \labelwidth, then a box of % that natural width is employed. This will cause % an indentation of the text on that line. % \labelsep : space between end of label box and text of % first item. % % DEFAULT VALUES: % % \topsep : If list entered in vertical mode % then current value % else \topsepcorrection * \topsep of enclosing % environment. % \itemsep : \topsep % \parsep : minimum(\parsep of enclosing environment, \topsep) % \leftmargin : For list depth 1: \leftmargini % : For list depth 2: \leftmarginii % : etc. through list depth 6 % \rightmargin : 0 pt % \listparindent : 0 pt % \itemindent : 0 opt % \labelsep : value from enclosing environment % \labelwidth : default \leftmargin - \labelsep % % \list{LABEL}{COMMANDS} == % BEGIN % \@everyitem :=L null % \@saveitem :=L \c@list % if \@listdepth > 5 % then LaTeX error: 'Too deeply nested' % else \@listdepth :=G \@listdepth + 1 % fi % \c@list :=G 0 %%% Set default values: % \topsep :=L if hmode then \topsepcorrection * \topsep fi % \itemsep :=L \topsep % \parsep :=L minimum(\parsep, \topsep) % \leftmargin :=L \eval(leftmargin \romannumeral\the\@listdepth) % \rightmargin :=L 0 pt % \listparindent :=L 0 pt % \itemindent :=L 0pt % \labelwidth :=L \leftmargin - \labelsep % \@itemlabel :=L LABEL % COMMANDS % \@topsepadd :=L \topsep - \parskip % \@topsep :=L \topsep - \parsep % \@itemsep :=L \itemsep - \parsep % if @inlabel = true % then @noparitem :=L true % else if hmode then \unskip fi \par % fi % \leftskip :=L 0pt % Restore paragraphing parameters % \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 + \parstretch % \@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 % \@listdepth :=G \@listdepth -1 % \@endparenv % END % % \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 % \addvspace{\@topsep} % else % \addvspace{\@itemsep} % 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{} } % @nobreak :=G false % if @noitemarg = true % then @noitemarg := false % \c@list :=G \c@list + 1 % \@everyitem % fi % \@tempboxa :=L \hbox{LAB} % \box\@labels :=G \@labels \hskip \itemindent % \hskip - (\labelwidth + \labelsep) % if \wd \@tempboxa > \labelwidth % then \box\@tempboxa % else \hbox to \labelwidth {LAB} % fi % \hskip\labelsep % \ignorespaces %gobble space up to text % END % % % DEFINE \dimen's and \count \newdimen\topsep \newdimen\itemsep \newdimen\@itemsep \newdimen\parsep \newskip\parstretch \newdimen\@topsep \newdimen\@topsepadd \newdimen\leftmargin \newdimen\rightmargin \newdimen\listparindent \newdimen\itemindent \newdimen\labelwidth \newdimen\labelsep \newdimen\linewidth \newdimen\@totalleftmargin \@totalleftmargin=\z@ \newdimen\leftmargini \newdimen\leftmarginii \newdimen\leftmarginiii \newdimen\leftmarginiv \newdimen\leftmarginv \newdimen\leftmarginvi \newcount\c@list \newcount\@saveitem \newcount\@listdepth \@listdepth=0 \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 \ifnum \@listdepth >5\relax \@toodeep \else \global\advance\@listdepth\@ne \fi \ifhmode \topsep \topsepcorrection\topsep \fi \itemsep\topsep \ifdim \topsep <\parsep \parsep\topsep \fi \leftmargin\csname leftmargin\romannumeral\the\@listdepth\endcsname \rightmargin \z@ \listparindent \z@ \itemindent \z@ \labelwidth\leftmargin \advance\labelwidth -\labelsep \def\@itemlabel{#1}#2\relax \@topsep\topsep \advance\@topsep -\parsep \@topsepadd\topsep \advance\@topsepadd -\parskip \@itemsep\itemsep \advance\@itemsep -\parsep \if@inlabel \@noparitemtrue \else \ifhmode \unskip \fi \par \fi \leftskip\z@ \rightskip\z@ \parfillskip\@flushglue \@setpar{\if@newlist\else{\@@par}\fi}% \parskip\parsep \advance\parskip\parstretch \global\@newlisttrue \parindent\listparindent \advance\linewidth -\rightmargin \advance\linewidth -\leftmargin \advance\@totalleftmargin \leftmargin \parshape \@ne \@totalleftmargin \linewidth \ignorespaces} \def\endlist{\global\c@list\@saveitem \global\advance\@listdepth\m@ne\@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 \addvspace\@topsep \else \addvspace\@itemsep \fi \global\@inlabeltrue \fi \everypar{\global\@newlistfalse \if@inlabel\global\@inlabelfalse \hskip -\parindent \box\@labels\fi \everypar{}}\global\@nobreakfalse \if@noitemarg \@noitemargfalse \global\advance\c@list \@ne \@everyitem \fi \setbox\@tempboxa\hbox{#1}% \global\setbox\@labels \hbox{\unhbox\@labels \hskip \itemindent \hskip -\labelwidth \hskip -\labelsep \ifdim \wd\@tempboxa >\labelwidth \box\@tempboxa \else \hbox to\labelwidth {#1\hss}\fi \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 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. The default value of \@enumspacing is null. % % 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$. \@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 % \@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\enumerate{\ifnum \@enumdepth >3 \@toodeep\else \advance\@enumdepth \@ne \edef\@enumctr {enum@\romannumeral\the\@enumdepth}% \edef\@enumitem{\expandafter\noexpand \csname ce@\@enumctr\endcsname}% \setcounter{\@enumctr}0% \list{\hfill \@enumitem}% {\def\@everyitem{\@refstepcounter{\@enumctr}}\@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}} % {\@itemspacing } % fi % END % % \enditemize == \endlist % \newcount\@itemdepth \@itemdepth = 0 \def\itemize{\ifnum \@itemdepth >3 \@toodeep\else \advance\@itemdepth \@ne \edef\@itemitem{item@\romannumeral\the\@itemdepth}% \list{\hfill \@nameuse{\@itemitem}}{\@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. % Sets \hsize := WIDTH and calls \@parboxrestore, which does % the following: % Restores the original definitions of: % \par % \\ % \- \' \` \= % Resets the following parameters: % \parindent = 0pt % \linewidth = \hsize % \@totalleftmargin = 0pt % \leftskip = 0pt % \rightskip = 0pt % \parfillskip = 0pt plus 1fil % \lineskip = \normallineskip % \baselineskip = \normalbaselineskip % Calls \sloppy % % Note: \@arrayparboxrestore same as \@parboxrestore % but it doesn't restore \\. % % \minipage : Similar to parbox, except it also % makes this look like a page by setting % \textwidth == \columnwidth == box width % changes footnotes by redefining: % \@mpfn == mpfootnote % \co@mpfn == \co@mpfootnote % \@footnotetext == \@mpfootnotetext % resets the following list environment parameters % \@listdepth == \@mplistdepth % where \@mplistdepth is initialized to zero, % and executes \@minipagerestore to allow the document % style to reset any other parameters it desires. % % \rule [RAISED]{WIDTH}{HEIGHT} : Makes a WIDTH X HEIGHT rule, raised % RAISED. % % \underline {TEXT} : Makes an underlined hbox with TEXT in it. % % \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{\leavevmode\hbox{#1}} \def\@makebox[#1]{\leavevmode\@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){\leavevmode\@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{\leavevmode\copy #1\relax} \long\def\frame#1{\leavevmode \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{\leavevmode\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{\leavevmode \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{\leavevmode \@pboxswfalse \if #1b\vbox \else \if #1t\vtop \else \ifmmode \vcenter \else \@pboxswtrue $\vcenter \fi \fi \fi{\hsize #2\@parboxrestore #3}\if@pboxsw $\fi} \let\@dischyph=\- \let\@acci=\' \let\@accii=\` \let\@acciii=\= \def\@arrayparboxrestore{\let\par\@@par \let\-\@dischyph \let\'\@acci \let\`\@accii \let\=\@acciii \parindent\z@ \everypar{}\linewidth\hsize \@totalleftmargin\z@ \leftskip\z@ \rightskip\z@ \parfillskip\@flushglue \lineskip\normallineskip \baselineskip\normalbaselineskip\sloppy} \def\@parboxrestore{\@arrayparboxrestore\let\\=\@normalcr} \def\minipage{\@ifnextchar [{\@iminipage}{\@iminipage[c]}} \def\@iminipage[#1]#2{\leavevmode \@pboxswfalse \if #1b\vbox \else \if #1t\vtop \else \ifmmode \vcenter \else \@pboxswtrue $\vcenter \fi \fi \fi\bgroup \hsize #2\textwidth\hsize \columnwidth\hsize \@parboxrestore \def\@mpfn{mpfootnote}\def\co@mpfn{\co@mpfootnote}\c@mpfootnote\z@ \let\@footnotetext\@mpfootnotetext \let\@listdepth\@mplistdepth \@mplistdepth\z@ \@minipagerestore} \let\@minipagerestore=\relax \def\endminipage{\ifvoid\@mpfootins\else\par \vskip\skip\@mpfootins\footnoterule\unvbox\@mpfootins\fi \egroup\if@pboxsw $\fi} \newcount\@mplistdepth \newbox\@mpfootins \long\def\@mpfootnotetext#1#2{\global\setbox\@mpfootins \vbox{\unvbox\@mpfootins \footnotesize \hsize\columnwidth \@parboxrestore \@makefntext{#1}{#2}}\ifhmode\spacefactor\@x@sf\relax\fi} \newif\if@pboxsw \def\rule{\@ifnextchar[{\@rule}{\@rule[\z@]}} \def\@rule[#1]#2#3{\@tempdima#3\advance\@tempdima #1\leavevmode\hbox{\vrule \@width#2 \@height\@tempdima \@depth-#1}} \let\@@underline\underline \def\underline#1{\ifmmode \@@underline\else $\@@underline{\hbox{#1}}$\relax\fi} \def\raisebox#1{\@ifnextchar[{\@argraisebox{#1}}{\@raisebox{#1}}} \long\def\@raisebox#1#2{\setbox\@tempboxa\hbox{#2}\@tempdima\ht\@tempboxa \advance\@tempdima #1\leavevmode\hbox{\vrule \@width\z@ \@height\@tempdima \@depth-#1\raise #1\vbox to\z@{\vss\box\@tempboxa}}} \def\@argraisebox#1[#2]{% \@ifnextchar[{\@iiraisebox{#1}[#2]}{\@iiraisebox{#1}[#2][\z@]}} \long\def\@iiraisebox#1[#2][#3]#4{\leavevmode \hbox{\vrule \@width\z@ \@height#2 \@depth#3\raise #1\vbox to \z@{\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. % % \tabbingsep = distance left by the \' command between the current % position and the field that is ``left-shifted''. % % 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 % \\* == BEGIN \@stopline \penalty 10000 \@startline END % \\*[DIST] == BEGIN \@stopline \penalty 10000 \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 < \@hightab % then \@nxttabmar :=G \@nxttabmar+1 % else error message ``Undefined tab'' % 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 -\tabbingsep % \box\@curfield % \hskip \tabbingsep } % \@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 =\z@} \def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}{\@xtabcr}} \def\@xtabcr{\@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 \z@\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 \@badpoptabs \fi\@endparenv} \def\@rtab{\@stopfield\@addfield\ifnum \@curtab<\@hightab \global\advance\@curtab \@ne \else\@badtab\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 \@ne \else\@latexerr{Tab overflow}\@ehd\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 \m@ne \global\advance\@curtabmar \m@ne \else \@badtab\fi\else \@latexerr{\string\<\space in mid line}\@ehd\fi\ignorespaces} \def\@tabplus {\ifnum \@nxttabmar < \@hightab \global\advance\@nxttabmar \@ne \else \@badtab\fi\ignorespaces} \def\@tabminus{\ifnum\@nxttabmar > \@firsttab \global\advance\@nxttabmar \m@ne \else \@badtab\fi\ignorespaces} \def\@tabrj{\@stopfield\@addfield\global\@rjfieldtrue\@startfield\ignorespaces} \def\@tablab{\@stopfield\setbox\@curline\hbox{\box\@curline \hskip -\wd\@curfield \hskip -\tabbingsep \box\@curfield \hskip \tabbingsep}\@startfield\ignorespaces} \def\pushtabs{\@stopfield\@addfield\global\advance\@tabpush \@ne \begingroup \@contfield} \def\poptabs{\@stopfield\@addfield\ifnum\@tabpush > \z@ \endgroup \global\advance\@tabpush \m@ne \else \@badpoptabs\fi\@contfield} \newdimen\tabbingsep % **************************************** % * 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 == % BEGIN % \end == \@endarray % \@acol == \@arrayacol % \@classz == \@arrayclassz % \@classiv == \@arrayclassiv % \@tabarray % END % %% {{ BRACE MATCHING HACK % \@endarray{NAME} == BEGIN \crcr }} % \@checkend{NAME} \endgroup % END % % \tabular == % BEGIN % \leavevmode % \hbox { $ % \end == \@endtabular % \@acol == \@tabacol % \@classz == \@tabclassz % \@classiv == \@tabclassiv % \@tabarray % END % %%{{ BRACE MATCHING % \@endtabular{NAME} == BEGIN \crcr}} $} % \@checkend{NAME} \endgroup % END % % \@tabarray == if next char = [ then \@array else \@array[c] fi % % \@array[POS]{PREAMBLE} == % BEGIN % \@mkpream{PREAMBLE} % \\ == \@arraycr % \@preamble == \halign{\strut eval{\@preamble}\cr %% } BRACE MATCHING % \@startpbox == \@@startpbox % \@endpbox == \@@endpbox % 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 % % % \@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{\let\end\@endarray \let\@acol\@arrayacol \let\@classz\@arrayclassz \let\@classiv\@arrayclassiv \@tabarray} \def\@endarray#1{\crcr\egroup\egroup\@checkend{#1}\endgroup} \def\tabular{\leavevmode \hbox \bgroup $\let\end\@endtabular%$ MATCHING \let\@acol\@tabacol \let\@classz\@tabclassz \let\@classiv\@tabclassiv \@tabarray} \def\@endtabular#1{\crcr\egroup\egroup $\egroup %$ MATCHING \@checkend{#1}\endgroup} \def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}} \def\@array[#1]#2{\@mkpream{#2}\let\\\@arraycr \edef\@preamble{\halign \bgroup \strut \@preamble \cr}% \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi \bgroup \let\par\relax \let\@sharp##\lineskip\z@\baselineskip\z@\@preamble} \def\@arraycr{{\ifnum0=`}\fi\@ifstar{\@xarraycr}{\@xarraycr}} \def\@xarraycr{\@ifnextchar[{\@argarraycr}{\ifnum0=`{\fi}\cr}} \def\@argarraycr[#1]{\ifnum0=`{\fi}\ifdim #1>\z@ \@xargarraycr{#1}\else \@yargarraycr{#1}\fi} \def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp\strutbox \vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr} \def\@yargarraycr#1{\cr\noalign{\vskip #1}} % \multicolumn{NUMBER}{FORMAT}{ITEM} == % BEGIN % \multispan{NUMBER} % \begingroup % \@addamp == null % \@mkpream{FORMAT} % \@sharp == ITEM % \@startpbox == \@@startpbox % \@endpbox == \@@endpbox % \strut % \@preamble % \endgroup % END \def\multicolumn#1#2#3{\multispan{#1}\begingroup \def\@addamp{}\@mkpream{#2}% \def\@sharp{#3}\let\@startpbox\@@startpbox\let\@endpbox\@@endpbox \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 % % \@mkpream TOKENLIST == % BEGIN % @firstamp := T % \@lastchclass := 6 % \@preamble == null % \@sharp == \relax % \@startpbox == \relax % \@endpbox == \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 % \@endpbox % 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 \m@ne}\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\@mkpream#1{\@firstamptrue\@lastchclass6 \def\@preamble{}\let\@sharp\relax \let\@startpbox\relax\let\@endpbox\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 \@ne\or \@preamerr \tw@\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\@endpbox}} \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=\tw@ 4 \else \ifnum \@lastchclass=3 5 \else \z@ \if #1c\@chnum \z@ \else \if #1l\@chnum \@ne \else \if #1r\@chnum \tw@ \else \@chclass \if #1|\@ne \else \if #1@\tw@ \else \if #1p3 \else \z@ \@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} % \@endpbox == \par \vskip \dp\strutbox\egroup \def\@startpbox#1{\vtop\bgroup \hsize #1\@arrayparboxrestore} \def\@endpbox{\par\vskip\dp\strutbox\egroup} \let\@@startpbox=\@startpbox \let\@@endpbox=\@endpbox % **************************************** % * THE PICTURE ENVIRONMENT * % **************************************** % % \unitlength = value of dimension argument % \@wholewidth = current line width % \@halfwidth = half of current line width % \@linefnt = font for drawing lines % \@circlefnt = font for drawing circles % % \picturelines{DIM} : Sets the width of horizontal and vertical lines % in a picture to DIM. Does not change width of slanted lines % or circles. Width of all lines reset by \thinlines and % \thicklines % % \picture(XSIZE,YSIZE)(XORG,YORG) % BEGIN % \@picht :=L YSIZE * \unitlength % box \@picbox := % \hbox to XSIZE * \unitlength % {\hskip -XORG * \unitlength % \lower YORG * \unitlength % \hbox{ % END % % \endpicture == % BEGIN % } \hss } % heigth of \@picbox := \@picht % depth of \@picbox := 0 % leavevmode % \box\@picbox % 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 \unitlength =1pt \newbox\@picbox \newdimen\@picht \def\picture(#1,#2){\@ifnextchar({\@picture(#1,#2)}{\@picture(#1,#2)(0,0)}} \def\@picture(#1,#2)(#3,#4){\@picht #2\unitlength \setbox\@picbox\hbox to #1\unitlength\bgroup \hskip -#3\unitlength \lower #4\unitlength \hbox\bgroup} \def\endpicture{\egroup\hss\egroup\ht\@picbox\@picht \dp\@picbox\z@\leavevmode\box\@picbox} \long\def\put(#1,#2)#3{\@killglue\raise#2\unitlength\hbox to \z@{\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 \z@{\hskip \@xdim #6\hss}\advance\@multicnt \m@ne\advance\@xdim #3\unitlength\advance\@ydim #4\unitlength}\ignorespaces} \def\@killglue{\unskip\@whiledim \lastskip >\z@\do{\unskip}} \def\thinlines{\let\@linefnt\tenln \let\@circlefnt\tencirc \@halfwidth .2pt\@wholewidth .4pt} \def\thicklines{\let\@linefnt\tenlnw \let\@circlefnt\tencircw \@wholewidth .77pt \@halfwidth .5\@wholewidth} \def\linethickness#1{\@wholewidth #1\relax \@halfwidth .5\@wholewidth} \def\picturelines#1{\@wholewidth #1\relax \@halfwidth .5\@wholewidth} \newdimen\@halfwidth \newdimen\@wholewidth \def\shortstack{\@ifnextchar[{\@shortstack}{\@shortstack[c]}} \def\@shortstack[#1]{\leavevmode \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{\@ifstar{\@ixstackcr}{\@ixstackcr}} \def\@ixstackcr{\@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 % \@clnht := 0 % else \@upordown = \lower % \@clnht := height of \box\@linechar % fi % \@clnwd := 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 \@clnwd < \@linelen % do \@upordown \@clnht \copy\@linechar % \@tempa % \@clnht := \@clnht + ht of \box\@linechar % \@clnwd := \@clnwd + width of \box\@linechar % od % % %% Put out last segment % \@clnht := \@clnht - height of \box\@linechar % \@clnwd := \@clnwd - width of \box\@linechar % \@tempdima := \@linelen - \@clnwd % \@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 % \@clnht := \@clnht + \@tempdima % if \@linelen < width of box\@linechar % then \hskip width of box\@linechar % else \hbox{\@upordown \@clnht \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 \@clnht \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 \@clnht\z@ \else\let\@upordown\lower \@clnht \ht\@linechar\fi \@clnwd=\wd\@linechar \if@negarg \hskip -\wd\@linechar \def\@tempa{\hskip -2\wd\@linechar}\else \let\@tempa\relax \fi \@whiledim \@clnwd <\@linelen \do {\@upordown\@clnht\copy\@linechar \@tempa \advance\@clnht \ht\@linechar \advance\@clnwd \wd\@linechar}% \advance\@clnht -\ht\@linechar \advance\@clnwd -\wd\@linechar \@tempdima\@linelen\advance\@tempdima -\@clnwd \@tempdimb\@tempdima\advance\@tempdimb -\wd\@linechar \if@negarg \hskip -\@tempdimb \else \hskip \@tempdimb \fi \multiply\@tempdima \@m \@tempcnta \@tempdima \@tempdima \wd\@linechar \divide\@tempcnta \@tempdima \@tempdima \ht\@linechar \multiply\@tempdima \@tempcnta \divide\@tempdima \@m \advance\@clnht \@tempdima \ifdim \@linelen <\wd\@linechar \hskip \wd\@linechar \else\@upordown\@clnht\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\@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\@clnht \hbox{\@linefnt \if@negarg \@getlarrow(\@xarg,\@yyarg) \else \@getrarrow(\@xarg,\@yyarg) \fi}% \else\@badlinearg\fi} \def\@getlarrow(#1,#2){\ifnum #2 =\z@ \@tempcnta='33\else \@tempcnta=#1\relax\multiply\@tempcnta \sixt@@n \advance\@tempcnta -9 \@tempcntb=#2\relax\multiply\@tempcntb \tw@ \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 \sixt@@n \advance\@tempcnta -\tw@ \else \@tempcnta=#1\relax\multiply\@tempcnta \sixt@@n \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 \z@{\hskip -\@halfwidth \vrule \@width \@wholewidth \@height \@linelen \@depth \z@\hss}} \def\@downline{\hbox to \z@{\hskip -\@halfwidth \vrule \@width \@wholewidth \@height \z@ \@depth \@linelen \hss}} \def\@upvector{\@upline\setbox\@tempboxa\hbox{\@linefnt\char'66}\raise \@linelen \hbox to\z@{\lower \ht\@tempboxa\box\@tempboxa\hss}} \def\@downvector{\@downline\lower \@linelen \hbox to \z@{\@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){\leavevmode\hbox to \z@{\baselineskip \z@% \lineskip \z@% \@dashdim=#2\unitlength% \@dashcnt=\@dashdim \advance\@dashcnt 200 \@dashdim=#1\unitlength\divide\@dashcnt \@dashdim \ifodd\@dashcnt\@dashdim=\z@% \advance\@dashcnt \@ne \divide\@dashcnt \tw@ \else \divide\@dashdim \tw@ \divide\@dashcnt \tw@ \advance\@dashcnt \m@ne \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{\copy\@dashbox\advance\@tempcnta \@ne }}\@tempcnta=0 \put(0,#3){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt \do{\copy\@dashbox\advance\@tempcnta \@ne }}% \@dashdim=#3\unitlength% \@dashcnt=\@dashdim \advance\@dashcnt 200 \@dashdim=#1\unitlength\divide\@dashcnt \@dashdim \ifodd\@dashcnt \@dashdim=\z@% \advance\@dashcnt \@ne \divide\@dashcnt \tw@ \else \divide\@dashdim \tw@ \divide\@dashcnt \tw@ \advance\@dashcnt \m@ne \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 \@ne }% \vskip\@dashdim}}\@tempcnta0 \put(#2,0){\hskip -\@halfwidth \vbox{\@whilenum \@tempcnta< \@dashcnt \relax\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta \@ne }% \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 center. % % \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. % % \@getcirc {DIAM} : Sets \@tempcnta to the character number % of the top-right quarter circle with the largest % diameter less than or equal to DIAM. Sets % \@tempdima to the diameter of that circle. % % \@getcirc {DIAM} == % BEGIN % \@tempcnta := integer coercion of DIAM % \@tempcnta := \@tempcnta / integer coercion of 4pt % \@tempdima := 4pt % if \@tempcnta > 10 % then \@tempcnta := 10 fi % \@tempdima := \@tempcnta * \@tempdima % if \@tempcnta > 0 % then \@tempcnta := \@tempcnta-1 % else LaTeX Warning: Oval too small. % fi % \@tempcnta := 4 * \@tempcnta % END % % \@put{X}{Y}{OBJ} == % BEGIN % \raise Y \hbox to 0pt{\hskip X OBJ \hss} % END % % \@oval(X,Y)[POS] == % BEGIN % \begingroup % @ovt := @ovb := @ovl := @ovr := true % for all E in POS % do @ovE := false od % \@ovx := X * \unitlength % \@ovy := Y * \unitlength % \@tempdimb := min(\@ovx,@ovy) % \@getcirc{\@tempdimb} % \@ovx := \@ovx/2 % \@ovy := \@ovy/2 % \@tempdima := \@tempdima/2 % \@ovdx := \@ovx - \@tempdima % \@ovdy := \@ovy - \@tempdima % \@circlefnt % if @ovb % then if @ovl % then \@put{\@ovdx}{\@ovdy}{\char\@tempcnta} % \@put{0}{\@ovy}{\vrule height \@halfwidth % depth \@halfwidth width \@ovdx} % \@put{\@ovx}{0}{\hskip -\@halfwidth % \vrule ht \@ovdy dp 0 wd \@wholewidth} % fi fi % \@tempcnta := \@tempcnta + 1 % if @ovt % then if @ovl % then \@put{\@ovdx}{-\@ovdy}{\char\@tempcnta} % \@put{0}{-\@ovy}{\vrule height \@halfwidth % depth \@halfwidth width \@ovdx} % \@put{\@ovx}{0}{\hskip -\@halfwidth % \vrule ht 0 dp \@ovdy wd \@wholewidth} % fi fi % \@tempcnta := \@tempcnta + 1 % if @ovt % then if @ovr % then \@put{-\@ovdx}{-\@ovdy}{\char\@tempcnta} % \@put{-\@ovdx}{-\@ovy}{\vrule height \@halfwidth % depth \@halfwidth width \@ovdx} % \@put{-\@ovx}{0}{\hskip -\@halfwidth % \vrule ht 0 dp \@ovdy wd \@wholewidth} % fi fi % \@tempcnta := \@tempcnta + 1 % if @ovb % then if @ovr % then \@put{-\@ovdx}{\@ovdy}{\char\@tempcnta} % \@put{-\@ovdx}{\@ovy}{\vrule height \@halfwidth % depth \@halfwidth width \@ovdx} % \@put{-\@ovx}{0}{\hskip -\@halfwidth % \vrule ht \@ovdy dp 0 wd \@wholewidth} % fi fi % \endgroup % END % % \circle{DIAM} == % BEGIN % \@tempdimb := DIAM *\unitlength % if \@tempdimb > 15.5pt % then \@getcirc{\@tempdimb} % \@circlefnt % \char's \@tempcnta ... \@tempcnta+3 % else % \@circ{\@tempdimb}{96} % fi % END % % \circle*{DIAM} == \@dot{DIAM} == \@circ{DIAM*\unitlength}{112} % % \@circ{DIAM}{CHAR} == % BEGIN % \@tempcnta := integer coercion of (DIAM + .5pt)/1pt. % if \@tempcnta > 15 then \@tempcnta := 15 fi % if \@tempcnta > 1 then \@tempcnta := \@tempcnta - 1 fi % \@tempcnta := \@tempcnta + CHAR % \@circlefnt % \char \@tempcnta % END % \newif\if@ovt \newif\if@ovb \newif\if@ovl \newif\if@ovr \newdimen\@ovx \newdimen\@ovy \newdimen\@ovdx \newdimen\@ovdy \def\@getcirc#1{\@tempdima #1\relax \@tempcnta\@tempdima \@tempdima 4pt\relax \divide\@tempcnta\@tempdima \ifnum \@tempcnta > 10\relax \@tempcnta 10\relax\fi \multiply\@tempdima\@tempcnta \ifnum \@tempcnta >\z@ \advance\@tempcnta\m@ne \else \@warning{Oval too small}\fi \multiply\@tempcnta 4\relax} \def\@put#1#2#3{\raise #2\hbox to \z@{\hskip #1#3\hss}} \def\oval(#1,#2){\@ifnextchar[{\@oval(#1,#2)}{\@oval(#1,#2)[]}} \def\@oval(#1,#2)[#3]{\begingroup \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue \@tfor\@tempa :=#3\do{\csname @ov\@tempa false\endcsname}\@ovx #1\unitlength \@ovy #2\unitlength \@tempdimb \ifdim \@ovy >\@ovx \@ovx\else \@ovy \fi \@getcirc \@tempdimb \divide\@ovx\tw@ \divide\@ovy\tw@ \divide\@tempdima\tw@ \@ovdx\@ovx \advance\@ovdx -\@tempdima \@ovdy\@ovy \advance\@ovdy -\@tempdima \@circlefnt \if@ovb \if@ovl \@put\@ovdx\@ovdy{\char\@tempcnta}\@put\z@\@ovy{\vrule \@height\@halfwidth \@depth\@halfwidth \@width\@ovdx}\@put\@ovx\z@{\hskip -\@halfwidth \vrule \@height\@ovdy \@width \@wholewidth}\fi\fi \advance\@tempcnta\@ne \if@ovt \if@ovl \@put\@ovdx{-\@ovdy}{\char\@tempcnta}\@put\z@{-\@ovy}{\vrule \@height\@halfwidth \@depth\@halfwidth \@width\@ovdx}\@put\@ovx\z@{\hskip -\@halfwidth \vrule \@height\z@ \@depth\@ovdy \@width \@wholewidth}\fi\fi \advance\@tempcnta\@ne \if@ovt \if@ovr \@put{-\@ovdx}{-\@ovdy}{\char\@tempcnta}\@put{-\@ovdx}{-\@ovy}{\vrule \@height\@halfwidth \@depth\@halfwidth \@width\@ovdx}\@put{-\@ovx}\z@{\hskip -\@halfwidth \vrule \@height\z@ \@depth\@ovdy \@width \@wholewidth}\fi\fi \advance\@tempcnta\@ne \if@ovb \if@ovr \@put{-\@ovdx}\@ovdy{\char\@tempcnta}\@put{-\@ovdx}\@ovy{\vrule \@height\@halfwidth \@depth\@halfwidth \@width\@ovdx}\@put{-\@ovx}\z@{\hskip -\@halfwidth \vrule \@height\@ovdy \@width \@wholewidth}\fi\fi \endgroup} \def\circle{\@ifstar{\@dot}{\@circle}} \def\@circle#1{\@tempdimb #1\unitlength \ifdim \@tempdimb >15.5pt\relax \@getcirc\@tempdimb \@circlefnt \char\@tempcnta \advance\@tempcnta\@ne \char\@tempcnta \advance\@tempcnta\@ne \char\@tempcnta \advance\@tempcnta\@ne \char\@tempcnta \else \@circ\@tempdimb{96}\fi} \def\@dot#1{\@tempdimb #1\unitlength \@circ\@tempdimb{112}} \def\@circ#1#2{\@tempdima #1\relax \advance\@tempdima .5pt\relax \@tempcnta\@tempdima \@tempdima 1pt\relax \divide\@tempcnta\@tempdima \ifnum\@tempcnta > 15\relax \@tempcnta 15\relax \fi \ifnum \@tempcnta >\z@ \advance\@tempcnta\m@ne\fi \advance\@tempcnta #2\relax \@circlefnt \char\@tempcnta} %INITIALIZATION \thinlines \newcount\@xarg \newcount\@yarg \newcount\@yyarg \newcount\@multicnt \newdimen\@xdim \newdimen\@ydim \newbox\@linechar \newdimen\@linelen \newdimen\@clnwd \newdimen\@clnht \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 theorem number is % produced as an \item. When \@thmlistcmd is called, % \labelwidth has been set to 0pt and \itemindent has been % set to -\labelsep, which makes the theorem number % flush with the left margin. If \labelsep is changed, % then \itemindent must also be changed to keep the % number flush with 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 == \@thm{NAME}{TEXT} % \endNAME == \endlist % else error % fi % END % % \newtheorem{NAME}[OLDNAME]{TEXT}== % BEGIN % if \NAME is definable % then \co@NAME == \co@OLDNAME % \NAME == \@thm{OLDNAME}{TEXT} % \endNAME == \endlist % else error % fi % END % % \@thm{NAME}{TEXT} == % BEGIN % \@refstepcounter{NAME} % \list{}{\labelwidth := 0pt % \leftmargin := 0pt % \itemindent := \labelsep % \@thmlistcmd } % \item[\@makethmnumber{TEXT}{\co@NAME}] % END \def\newtheorem#1{\@ifnextchar[{\@othm{#1}}{\@nthm{#1}}} \def\@nthm#1#2{% \@ifnextchar[{\@xnthm{#1}{#2}}{\@ynthm{#1}{#2}}} \def\@xnthm#1#2[#3]{\expandafter\@ifdefinable\csname #1\endcsname {\@definecounter{#1}\@addtoreset{#1}{#3}% \expandafter\xdef\csname co@#1\endcsname{\expandafter\noexpand \csname co@#3\endcsname \@thmcountersep \@thmcounter{#1}}% \global\@namedef{#1}{\@thm{#1}{#2}}\global\@namedef{end#1}{\endlist}}} \def\@ynthm#1#2{\expandafter\@ifdefinable\csname #1\endcsname {\@definecounter{#1}% \expandafter\xdef\csname co@#1\endcsname{\@thmcounter{#1}}% \global\@namedef{#1}{\@thm{#1}{#2}}\global\@namedef{end#1}{\endlist}}} \def\@othm#1[#2]#3{\expandafter\@ifdefinable\csname #1\endcsname {\global\@namedef{co@#1}{\@nameuse{co@#2}}% \global\@namedef{#1}{\@thm{#2}{#3}}% \global\@namedef{end#1}{\endlist}}} \def\@thm#1#2{\@refstepcounter{#1}\list{}{\labelwidth\z@ \leftmargin\z@ \itemindent\labelsep \@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\relax} \def\addtolength#1#2{\advance#1 #2\relax} \def\settowidth#1#2{\setbox\@tempboxa\hbox{#2}#1\wd\@tempboxa} % ***************************************** % * TABLE OF CONTENTS, ETC. * % ***************************************** % % CONVENTIONS: % \tf@foo = file number for output for table foo. The file is % opened only if @filesw = true. % % \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. % % \addcontentsline{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}{TEXT} : Adds TEXT to the .TABLE file, with no % page number. % % SURPRISE: \index and \label are no-ops inside an \addcontentsline % or \addtocontents command argument. This could cause a problem if % the user puts an \index or \label into one of the commands he writes, % or into the optional 'short version' argument of a \section or % \caption command. % % \addcontentsline{TABLE}{TYPE}{ENTRY} == % BEGIN % if @filesw = true % then \begingroup % \index == \label == \@gobble % \@temptokena := \co@page % \@tempa == write \string\contentsline % {TYPE}{ENTRY}{\the\@temptokena} % \@tempa % \endgroup % fi % END % % \writecommand{\FOO} == \string\string\string\FOO % % Here's how you define a \tableofcontents or similar command: % \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@filesw % \newwrite\tf@toc % Define the file \tf@toc % \openout\tf@toc=\jobname.toc % \fi} \def\addcontentsline#1#2#3{\if@filesw \begingroup \let\label\@gobble \let\index\@gobble \@temptokena{\co@page}% \edef\@tempa{\write \@auxout{\string\@writefile{#1}{\writecommand \contentsline{#2}{#3}{\the\@temptokena}}}}\@tempa\endgroup\fi} \def\addtocontents#1#2{\if@filesw \begingroup \let\label\@gobble \let\index\@gobble \edef\@tempa{\write \@auxout {\string\@writefile{#1}{#2}}}\@tempa \endgroup\fi} \def\contentsline#1{\csname l@#1\endcsname} \def\writecommand#1{\string\string\string#1} % **************************************** % * INDEX COMMANDS * % **************************************** % % \makeindex == % BEGIN % if \@filesw = 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@filesw \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@filesw \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. With % BIBTeX, the following commands will be used. % % \bibliography{FILE1,FILE2, ... ,FILEn} : specifies % the bibdata files. Writes a \bibdata entry on the .aux file % and tries to read in mainfile.BBL. % % \bibliographystyle{STYLE} : Writes a \bibstyle entry on the .aux file. % % The thebibliography 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 thebibliography 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 \thebibliography command must begin a list % environment, which the \endthebibliography 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 \@bibnum 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 \thebibliography definition would be % \def\thebibliography#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@filesw \immediate\write\@auxout {\string\bibcite{#2}{#1}}\fi\ignorespaces} \def\@bibitem#1{\item\if@filesw \immediate\write\@auxout {\string\bibcite{#1}{\@bibnum}}\fi\ignorespaces} \def\bibcite#1#2{\global\@namedef{b@#1}{#2}} \let\citation\@gobble \def\cite#1{\if@filesw\immediate\write\@auxout{\string\citation{#1}}\fi \def\@citea{}\@cite{\@for\@citeb:=#1\do {\@citea\def\@citea{,}\@ifundefined {b@\@citeb}{{\bf ?}\@warning {Citation `\@citeb' on page \co@page \space undefined}}% {\csname b@\@citeb\endcsname}}}} \let\bibdata=\@gobble \let\bibstyle=\@gobble \def\bibliography#1{\if@filesw\immediate\write\@auxout{\string\bibdata{#1}}\fi \@input{\jobname.bbl}} \def\bibliographystyle#1{\if@filesw\immediate\write\@auxout {\string\bibstyle{#1}}\fi} %DEFAULT DEFINITIONS \def\@cite#1{[#1]} \def\@bibnum{\arabic{list}} \let\@biblabel=\@cite % **************************************** % * FLOATS * % **************************************** % % The different types of floats are identified by a TYPE name, which is % the name of the counter for that kind of float. For example, figures % are of type 'figure' and tables are of type 'table'. Each TYPE has % associated a positive TYPE NUMBER, which is a power of two. E.g., % figures might be have type number 1, tables type number 2, programs % type number 4, etc. % % The locations where a float can go are specified by a PLACEMENT % SPECIFIER, which is a list of the possible locations, each denoted % by a letter as follows: % h : here - at the current location in the text. % t : top - at the top of a text page. % b : bottom - at the bottom of a text page. % p : page - on a separate float page. % For example, 'pht' specifies that the float can appear in any of three % locations: page, here or top. % % Where floats may appear on a page, and how many may appear there % are specified by the following float placement parameters. The % numbers are named like counters so the user can set them with % the ordinary counter-setting commands. % % \c@topnumber : Number of floats allowed at the top of a column. % \topfraction : Fraction of column that can be devoted to floats. % \c@dbltopnumber, \dbltopfraction : Same as above, but for double-column % floats. % \c@bottomnumber, \bottomfraction : Same as above for bottom of page. % \c@totalnumber : Number of floats allowed in a single column, % including in-text floats. % \textfraction : Minimum fraction of column that must contain text. % \floatpagefraction : Minimum fraction of page that must be taken % up by float page. % \dblfloatpagefraction : Same as above, for double-column floats. % % The document style must define the following. % % \fps@TYPE : The default placement specifier for floats of type TYPE. % % \ftype@TYPE : The type number for floats of type TYPE. % % \fnum@TYPE : A macro to generate the figure number for a caption. % For example, \fnum@TYPE == Figure \co@figure. % % \ext@TYPE : The file extension indicating the file on which the % contents list for float type TYPE is stored. For example, % \ext@figure = 'lof'. % % \@caption{TYPE}[STEXT]{TEXT} : A macro defined by the document style that % creates the caption. TEXT is the caption to appear with the figure, % and STEXT is to appear in the list of figures. (Default is TEXT.) % This macro should NOT step the counter, but it should % create a contents entry on file \ext@TYPE. It can assume that it is % called inside a \parbox with the right \hsize, but and with the % font size and style of the surrounding figure environment. % % \@float{TYPE}[PLACEMENT] : Macro to begin a float environment for a % single-column float of type TYPE with PLACEMENT as the placement % specifier. The default value of PLACEMENT is defined by \fps@TYPE. % The environment is ended by \end@float. % E.g., \figure == \@float{figure}, \endfigure == \end@float. % % \caption == % BEGIN % \@refstepcounter{\@captype} % \@caption{\@captype} % END % % \@float{TYPE}[PLACEMENT] == % BEGIN % if hmode then \@bsphack % \@floatpenalty := -10002 % else \@floatpenalty := -10003 % fi % \@captype ==L TYPE % if inner % then LaTeX Error: 'Not in outer paragraph mode.' % \@floatpenalty := 0 % else if \@freelist nonempty % then \@currbox :=L head of \@freelist % \@freelist :=G tail of \@freelist % \count\@currbox :=G 32*\ftype@TYPE + 16 + % bits determined by PLACEMENT % else \@floatpenalty := 0 % LaTeX Error: 'Too many unprocessed floats' % fi % fi % \@currbox :=G \vbox{ % \boxmaxdepth :=L 0pt %% to make a 0 depth box % \hsize = \columnwidth % \@parboxrestore % END % % \end@float == % BEGIN % } % if \@floatpenalty < 0 % then add \@currbox to \@currlist % if \ht\@currbox > \textheight % then \ht\@currbox :=G \textheight fi % @outputdone := false % if \@floatpenalty < -10002 % then \penalty \@floatpenalty % if @outputdone = false % then @outputdone :=G true % \vbox{} \penalty \@floatpenalty % fi % else \vadjust{\penalty \@floatpenalty} % \@esphack % fi fi % END % % \@dblfloat{TYPE}[PLACEMENT] : Macro to begin a float environment for a % double-column float of type TYPE with PLACEMENT as the placement % specifier. The default value of PLACEMENT is 'tp' % The environment is ended by \end@dblfloat. % E.g., \figure* == \@dblfloat{figure}, \endfigure* == \end@dblfloat. % % \@dblfloat{TYPE}[PLACEMENT] == % Identical to \@float{TYPE}[PLACEMENT] except \hsize and \linewidth % are set to \textwidth. % % \end@dblfloat == % BEGIN %%% { BRACE MATCHING % } % if \@floatpenalty < 0 % then \@dbldeferlist :=G \@dbldeferlist * \@currbox % fi % if \@floatpenalty = -10002 then \@esphack fi % END % \newcount\@floatpenalty \def\caption{\@refstepcounter\@captype \@caption\@captype} \def\@float#1{\@ifnextchar[{\@xfloat{#1}}{\edef\@tempa{\noexpand\@xfloat {#1}[\csname fps@#1\endcsname]}\@tempa}} \def\@xfloat#1[#2]{\ifhmode \@bsphack\@floatpenalty -\@Mii\else \@floatpenalty-\@Miii\fi\def\@captype{#1}\ifinner \@parmoderr\@floatpenalty\z@ \else\@next\@currbox\@freelist{\@tempcnta\csname ftype@#1\endcsname \multiply\@tempcnta\@xxxii\advance\@tempcnta\sixt@@n \@tfor \@tempa :=#2\do {\if\@tempa h\advance\@tempcnta \@ne\fi \if\@tempa t\advance\@tempcnta \tw@\fi \if\@tempa b\advance\@tempcnta 4\relax\fi \if\@tempa p\advance\@tempcnta 8\relax\fi }\global\count\@currbox\@tempcnta}\@fltovf\fi \global\setbox\@currbox\vbox\bgroup \boxmaxdepth\z@ \hsize\columnwidth \@parboxrestore} \def\end@float{\egroup \ifnum\@floatpenalty <\z@ \@cons\@currlist\@currbox \ifdim \ht\@currbox >\textheight \ht\@currbox\textheight \fi \global\@outputdonefalse \ifnum\@floatpenalty < -\@Mii \penalty\@floatpenalty \if@outputdone\else\global\@outputdonetrue \vbox{}\penalty\@floatpenalty\fi \else \vadjust{\penalty \@floatpenalty}\@esphack\fi\fi} \def\@dblfloat#1{\if@twocolumn\else\@latexerr{Two-column float on one-column page}\@ehd\fi \@ifnextchar[{\@xdblfloat{#1}}{\@xdblfloat{#1}[tp]}} \def\@xdblfloat#1[#2]{\@xfloat{#1}[#2]\hsize\textwidth\linewidth\textwidth} \def\end@dblfloat{\egroup \ifnum\@floatpenalty <\z@ \@cons\@dbldeferlist\@currbox\fi \ifnum \@floatpenalty =-\@Mii \@esphack\fi} \newcount\c@topnumber \newcount\c@dbltopnumber \newcount\c@bottomnumber \newcount\c@totalnumber \def\@floatplacement{\global\@topnum\c@topnumber \global\@toproom \topfraction\@colht \global\@botnum \c@bottomnumber \global\@botroom \bottomfraction\@colht \global\@colnum \c@totalnumber \@textmin \textfraction\@colht \@fpmin \floatpagefraction\@colht} \def\@dblfloatplacement{\global\@dbltopnum\c@dbltopnumber \global\@dbltoproom \dbltopfraction\@colht \@fpmin \dblfloatpagefraction\textheight \@fptop \@dblfptop \@fpsep \@dblfpsep \@fpbot \@dblfpbot} % MARGINAL NOTES: % % Marginal notes use the same mechanism as floats to communicate % with the \output routine. Marginal notes are distinguished from % floats by having a negative placement specification. The command % \marginpar [LTEXT]{RTEXT} generates a marginal note in a parbox, % using LTEXT if it's on the left and RTEXT if it's on the right. % (Default is RTEXT = LTEXT.) It uses the following parameters. % % \marginparwidth : Width of marginal notes. % \marginparsep : Distance between marginal note and text. % the page layout to determine how to move the marginal % note into the margin. E.g., \@leftmarginskip == % \hskip -\marginparwidth \hskip -\marginparsep . % \marginparpush : Minimum vertical separation between \marginpar's % % Marginal notes are normally put on the outside of the page % for two-sided output, and on the right for one-sided output. % The command \reversemarginpar reverses the side where they % are put. \normalmarginpar undoes \reversemarginpar. % These commands have no effect for two-column output. % % SURPRISE: if two marginal notes appear on the same line of % text, then the second one could appear on the next page, in % a funny position. % % % \marginpar [LTEXT]{RTEXT} == % BEGIN % if hmode then \@bsphack % \@floatpenalty := -10002 % else \@floatpenalty := -10003 % fi % if inner % then LaTeX Error: 'Not in outer paragraph mode.' % \@floatpenalty := 0 % else if \@freelist has two elements: % then get \@marbox, \@currbox from \@freelist % \count\@marbox :=G -1 % else \@floatpenalty := 0 % LaTeX Error: 'Too many unprocessed floats' % \@currbox, \@marbox := \@tempboxa %%use \def % fi % fi % if optional argument % then %% \@xmpar == % \@savemarbox\@marbox{LTEXT} % \@savemarbox\@currbox{RTEXT} % else %% \@ympar == % \@savemarbox\@marbox{RTEXT} % \box\@currbox :=G \box\@marbox % fi % %% \@xympar == % if \@floatpenalty < 0 then add \@marbox to \@currlist fi % { \end@float %%%% BRACE MATCHING} % END % % \@savemarbox\BOX{TEXT} == % BEGIN % \BOX :=G \vtop{ \hsize = \marginparwidth % \@parboxrestore % TEXT % } % END % % \reversemarginpar == BEGIN \@mparbottom :=G 0 % @reversemargin :=G true % END % % \normalmarginpar == BEGIN \@mparbottom :=G 0 % @reversemargin :=G false % END % \def\marginpar{\ifhmode \@bsphack\@floatpenalty -\@Mii\else \@floatpenalty-\@Miii\fi\ifinner \@parmoderr\@floatpenalty\z@ \else\@next\@currbox\@freelist{}{}\@next\@marbox\@freelist{\global \count\@marbox\m@ne}{\@floatpenalty\z@ \@fltovf\def\@currbox{\@tempboxa }\def\@marbox{\@tempboxa}}\fi \@ifnextchar [{\@xmpar}{\@ympar}} \def\@xmpar[#1]#2{\@savemarbox\@marbox{#1}\@savemarbox\@currbox {#2}\@xympar} \def\@ympar#1{\@savemarbox\@marbox{#1}\global\setbox\@currbox \copy\@marbox\@xympar} \def\@savemarbox#1#2{\global\setbox#1\vtop{\hsize\marginparwidth \@parboxrestore #2}} \def\@xympar{\ifnum\@floatpenalty <\z@\@cons\@currlist\@marbox\fi \bgroup\end@float\@esphack} \def\reversemarginpar{\global\@mparbottom\z@ \@reversemargintrue} \def\normalmarginpar{\global\@mparbottom\z@ \@reversemarginfalse} % **************************************** % * FOOTNOTES * % **************************************** % % \footnote{NOTE} : User command to insert a footnote. % % \footnote[NUM]{NOTE} : User command to insert a footnote numbered % NUM, where NUM is a number -- 1, 2, % etc. For example, if footnotes are numbered % *, **, etc. within pages, then \footnote[2]{...} % produces footnote '**'. This command does not % step the footnote counter. % % \footnotemark[NUM] : Command to produce just the footnote mark in % the text, but no footnote. With no argument, % it steps the footnote counter before generating % the mark. % % \footnotetext[NUM]{TEXT} : Command to produce the footnote but no % mark. \footnote is equivalent to % \footnotemark \footnotetext . % % As in PLAIN, footnotes use \insert\footins, and the following parameters: % % \footnotesize : Size-changing command for footnotes. % % \footnotesep : The height of a strut placed at the beginning of % every footnote. % \skip\footins : Space between main text and footnotes. The rule % separating footnotes from text occurs in this space. % This space lies above the strut of height \footnotesep % which is at the beginning of the first footnote. % \footnoterule : Macro to draw the rule separating footnotes from text. % It should take zero vertical space--i.e., it should to % a negative skip to compensate for any positive space % it occupies. (See PLAIN.TEX.) % % \interfootnotelinepenalty : Interline penalty for footnotes. % % \@footnotenumber : A macro to generate the mark symbol from a number. % In particular, % \co@footnote == \@footnotenumber{\c@footnote} % Typically, \@footnotenumber == \@arabic % % \@mpfnnumber : A macro that generates the numbers for \footnote % and \footnotemark commands. It == \@footnotenumber % outside a minipage environment, but can be changed % inside to generate numbers for \footnote's. % % \@makefnmark{MARK} : A macro to generate the footnote marker from % a symbol. E.g., might be \hbox{$^{MARK}$}. % % \@makefntext{MARK}{NOTE} : % Must produce the actual footnote, where MARK is the ``number'' % of the footnote and NOTE is the text. It is called when effectively % inside a \parbox, with \hsize = \columnwidth. For example, it might % be as simple as % $^{MARK}$\vrule height \footnotesep width 0pt % Note that it must include a strut of height \footnotesep in % the first line. % % The footnote counter is defined like an ordinary counter, except % with \co@footnote defined in terms of \@footnotenumber. If footnotes % are to be numbered within pages, then the document style file must % include an \@addtoreset command to cause the footnote counter to be % reset when the page counter is stepped. % % In a minipage environment, \footnote and \footnotetext are redefined % so that % (a) they use the counter mpfootnote % (b) the footnotes they produce go at the bottom of the minipage. % The switch is accomplished by letting \@mpfn == footnote or mpfootnote % and \co@mpfn == \co@footnote or \co@mpfootnote, and by redefining % \@footnotetext to be \@mpfootnotetext in the minipage. % % \footnote{NOTE} == % BEGIN % \@stepcounter{\@mpfn} % \@footnote{\co@mpfn}{NOTE} % END % % \footnote[NUM]{NOTE} == \@footnote{\@mpfnnumber{NUM}}{NOTE} % % \@footnote{MARK} == % BEGIN % \@x@sf := \the\spacefactor % \@makefnmark{MARK} % put number in main text % \@footnotetext{MARK} % END % % \@footnotetext{MARK}{NOTE} == % BEGIN % \insert into \footins % {\footnotesize % \interlinepenalty :=L \interfootnotelinepenalty % \splittopskip :=L \footnotesep % \splitmaxdepth :=L \dp\strutbox % \floatingpenalty :=L 20000 % \hsize :=L \columnwidth % \@parboxrestore % \@makefntext{MARK}{NOTE} % } % \spacefactor := \@x@sf % END % % \footnotemark == \@footnotemark{\co@footnote} % % \footnotemark[NUM] == BEGIN \@stepcounter{footnote} % \@footnotemark{\@footnotenumber{NUM}} END % % \@footnotemark{MARK} == % BEGIN % \@x@sf := \the\spacefactor % \@makefnmark{MARK} % put number in main text % \spacefactor := \@x@sf % END % % \footnotetext == BEGIN \@x@sf := \the\spacefactor % \@footnotetext{\co@mpfn} END % % \footnotetext[NUM] == BEGIN \@x@sf := \the\spacefactor % \@footnotetext{\@mpfnnumber{NUM}} END % \@definecounter{footnote} \def\co@footnote{\@footnotenumber\c@footnote} \@definecounter{mpfootnote} \def\co@mpfootnote{\@mpfnnumber\c@mpfootnote} \newdimen\footnotesep \def\footnote{\@ifnextchar[{\@xfootnote}{\@stepcounter {\@mpfn}\@footnote{\co@mpfn}}} \def\@xfootnote[#1]{\@footnote{\@mpfnnumber{#1}}} \def\@footnote#1{\ifhmode\edef\@x@sf{\the \spacefactor}\fi\@makefnmark{#1}\@footnotetext{#1}} \long\def\@footnotetext#1#2{\insert\footins{\footnotesize \interlinepenalty\interfootnotelinepenalty \splittopskip\footnotesep \splitmaxdepth \dp\strutbox \floatingpenalty \@MM \hsize\columnwidth \@parboxrestore \@makefntext{#1}{#2}}\ifhmode\spacefactor\@x@sf\relax\fi} \def\footnotemark{\ifhmode \edef\@x@sf{\the\spacefactor}\fi\@ifnextchar[{\@xfootnotemark }{\@stepcounter{footnote}\@makefnmark{\co@footnote}\ifhmode\spacefactor \@x@sf\relax\fi}} \def\@xfootnotemark[#1]{\@makefnmark{\@footnotenumber{#1}}\ifhmode \spacefactor\@x@sf\relax\fi} \def\footnotetext{\ifhmode\edef\@x@sf{\the\spacefactor}\fi\@ifnextchar [{\@xfootnotenext}{\@footnotetext{\co@mpfn}}} \def\@xfootnotenext[#1]{\@footnotetext{\@mpfnnumber{#1}}} \def\@mpfn{footnote} \def\co@mpfn{\co@footnote} \def\@mpfnnumber{\@footnotenumber} % **************************************** % * 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 \@tempa := ARGLIST % do if \pl@[eval(\@tempa)] undefined % then \input [eval(\@tempa)].PLO % else \pl@[eval(\@tempa)] % od % END % % \documentstyle{ARGLIST} == % BEGIN % for \@tempa := ARGLIST % do if \ds@[eval(\@tempa)] undefined % then \input [eval(\@tempa)].STY % else \ds@[eval(\@tempa)] % od % END % % PAGE STYLE COMMANDS % ------------------- % \pagestyle{STYLE} : sets the page style of the current and succeeding % pages to STYLE % % \thispagestyle{STYLE} : sets the page style of the current page only % to STYLE % % To define a page style STYLE, you must define \ps@STYLE % to set the page style parameters. % % % OTHER % ----- % % \sloppy : Resets TeX's parameters so it accepts worse line and page % breaks, and slightly more overfull boxes. % % \fussy : Resets TeX's parameters to their normal finnicky values. % \def\pagelayout#1{\@for\@tempa:=#1\do {\@ifundefined{pl@\@tempa}{\@@input \@tempa.plo\relax}{\@nameuse{pl@\@tempa}}}} \def\documentstyle#1{\@for\@tempa:=#1\do {\@ifundefined{ds@\@tempa}{\@@input \@tempa.sty\relax}{\@nameuse{ds@\@tempa}}}} \def\pagestyle#1{\@nameuse{ps@#1}} \def\thispagestyle#1{\global\@specialpagetrue\gdef\@specialstyle{#1}} % Default definitions \def\sloppy{\tolerance 2000 \hfuzz .5\p@ \vfuzz .5\p@} \def\fussy{\tolerance 200 \hfuzz .1\p@ \vfuzz .1\p@} % LaTeX default is no overfull box rule. Changed by document % style option \overfullrule 0pt % **************************************** % * 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 % \footskip : distance separation between baseline of last % line of text and baseline of foot. % Note difference between \footSKIP and \headSEP. % \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 layout must also initialize \@colht and \@colroom to \textheight. % % 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. % \@maxsep : The maximum of \floatsep, \textfloatsep and \intextsep % \dblfloatsep : Space between double-column floats. % \dbltextfloatsep : Space between top or bottom double-column floats % and text. % \@dblmaxsep : The maximum of \dblfloatsep and \dbltexfloatsep % \@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. % % FOOTNOTES: As in PLAIN, footnotes use \insert\footins. % % 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. % @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. % % % FLOAT PLACEMENT PARAMETERS % % The following parameters are set by the macro \@floatplacement, which is % defined by the \floatstyle command. When \@floatplacement is 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 floats on page. % Note that some are set globally and some locally: % \@topnum :=G Maximum number of floats allowed on the top of a column. % \@toproom :=G 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 :=G Maximum number of floats allowed in a column, including % in-text floats. % \@textmin :=L Minimum amount of text (excluding footnotes) that must % appear on a text page. % \@fpmin :=L Minimum height of floats in a float column. % % The macro \@dblfloatplacement sets the following parameters. This macro % is also defined by the \floatstyle command. % \@dbltopnum :=G Maximum number of double-column floats allowed at the % top of a two-column page. % \@dbltoproom :=G Maximum height of double-column floats allowed at % top of two-column page. % \@fpmin :=L Minimum height of floats in a float column. % It should also perform the following local assignments where necessary % -- i.e., where the new value differs from the old one: % \@fptop :=L \@dblfptop % \@fpsep :=L \@dblfpsep % \@fpbot :=L \@dblfpbot % % OUTPUT ROUTINE VARIABLES % % \@colht : The total height of the current column. In single column % style, it equals \textheight. In two-column style, it is % \textheight minus the height of the double-column floats % on the current page. MUST BE INITIALIZED TO \textheight. % % \@colroom : The height available in the current column for text and % footnotes. It equals \@colht minus the height of all % floats committed to the top and bottom of the current % column. % % \footins : Footnote insertion number. % % \@maxdepth : Saved value of TeX's \maxdepth. Must be set % when any routine sets \maxdepth. % % 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 (called with \penalty -10000 \vbox{} \penalty -10001 % -10002 float insertion, called from horizontal mode % -10003 float insertion, called from vertical mode. In this case, % the normal interaction is for the float placement algorithm to % call the output routine with if @outputdone = false, and for % the output routine to set @outputdone to true. If the float % placement finds @outputdone still false, then the penalty % was thrown away, so it tries again with a dummy box in % the output list and @outputdone = true. % % WARNING: If the user puts a \penalty -10000 in the vertical list % right before one of the communication penalties -- i.e., % with a \pagebreak command -- then the communicating penalty % will be lost. Therefore, a \pagebreak should not immediately % precede a \begin{figure}. % % 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 @thispagestyle = true % THEN use \thispagestyle style % ELSE use ordinary page style. % % \@tryfcolumn\FLIST : Tries to form a float column composed of floats from % \FLIST with 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 % NOTE: BIT MUST BE A SINGLE TOKEN! % % \@makefcolumn \FLIST : Same as \@tryfcolumn except that it % fails to make a float column only if \FLIST is empty. % Otherwise, it makes a float column containing at least % the first box in \FLIST, disregarding \@fpmin. % % \@startcolumn : % Calls \@tryfcolumn\@deferlist{8}. If \@tryfcolumn returns with % @fcolmade = false, then: % * Globally sets \@toplist and \@botlist to floats % from \@deferlist to go at top and bottom of column, % deleting them from \@deferlist. 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 \@textmin. % * Globally sets \@colroom to \@colht minus the height % of the added floats. % % \@startdblcolumn : % Calls \@tryfcolumn\@dbldeferlist{8}. If \@tryfcolumn returns % with @fcolmade = false, then: % * Globally sets \@dbltoplist to floats from \@dbldeferlist % to go at top and bottom of column, deleting them from % \@dbldeferlist. It does this using \textheight as the % total height, and the parameters \@dblfloatsep, etc. % * Globally sets \@colht to \textheight minus the height % of the added floats. % % \@combinefloats : Combines the text from box % \@outputbox with the floats from \@toplist and \@botlist, % putting the new box in \@outputbox. It uses \floatsep and % \textfloatsep for the appropriate separations. It puts the % elements of \TOPLIST and \BOTLIST onto \@freelist, and makes % those lists null. % % \@makecol : Makes the contents of \box255 plus the accumulated % footnotes, plus the floats in \@toplist and \@botlist, % into a single column of height \@colht, which it puts % into box \@outputbox. It puts boxes in \@midlist back % onto \@freelist and restores \maxdepth. % % \@opcol : 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 and sets @firstcolumn :=G false. % % If @firstcolumn = false, then it puts out the current % two-column page, any possible two-column float pages, % and determines \@dbltoplist for the next page. % % \@opcol == % BEGIN % \@mparbottom :=G 0pt % if @twocolumn = true % then %% \@outputdblcol == % if @firstcolumn = true % then @firstcolumn :=G false % \@leftcolumn :=G \@outputbox % else @firstcolumn :=G true % \@outputbox := \vbox{ % \hbox to \textwidth{ % \hbox to\columnwidth{\box\@leftcolumn % \hss} % \hfil \vrule width \columnseprule \hfil % \hbox to\columnwidth{\box\@outputbox} % \hss} } % \@combinedblfloats % \@outputpage % \begingroup % \@dblfloatplacement % \@startdblcolumn % while @fcolmade = true % do \@outputpage % \@startdblcolumn od % \endgroup % fi % else % \@outputpage % \@colht :=G \textheight % fi % END % % \@makecol == % BEGIN % ifvoid \insert\footins % then \@outputbox := \box255 % else \@outputbox := \vbox {\unvbox255 % \vskip \skip\footins % \footnoterule % \unvbox\@footinsert % } % fi % \@freelist :=G \@freelist * \@midlist % \@midlist :=G empty % \@combinefloats % \@outputbox := \vbox to \@colht{\boxmaxdepth := \maxdepth % \unvbox\@outputbox} % \maxdepth :=G \@maxdepth % END % % \@outputpage == % BEGIN % \catcode`\ := 10 %%make sure space is really a space % if @specialpage = T % then @specialpage :=G F % execute \@ps@[eval(\@specialstyle)] fi % if \@twoside = T % then if \count0 odd % else \@oddhead ==L \@evenhead % \@oddfoot ==L \@evenfoot % \oddsidemargin :=L \evensidemargin fi fi % \shipout\vbox % {\normalsize % set fonts size for head and foot % \baselineskip :=L \lineskip :=L 0pt % \vskip \topmargin % \moveright\oddsidemargin\vbox % { \vbox to \headheight{\vfil % \hbox to \textwidth % {\@oddhead}} % \vskip \headsep % \box\@outputbox % \baselineskip\footskip % \hbox to \textwidth{\@oddfoot} % } % } % \@colht :=G \textheight % \@stepcounter{page} % END % % \@startcolumn == % BEGIN % \@colroom :=G \@colht % if \@deferlist is empty % then @fcolmade := false % else \@tryfcolumn\@deferlist %% else clause == \@xstartcol % if @fcolmade = false % then \begingroup % \@tempb :=L \@deferlist % \@deferlist :=G empty % \@elt \BOX == BEGIN \@currbox == \BOX % use \gdef % \@addtonextcol % END == \@scolelt % \@tempb % \endgroup % fi fi % END % % \@startdblcolumn == % BEGIN % \@colht :=G \textheight % \@tryfcolumn\@dbldeferlist %% else clause == \@xstartcol % if @fcolmade = false % then \begingroup % \@tempb :=L \@dbldeferlist % \@dbldeferlist :=G empty % \@elt \BOX == BEGIN \@currbox == \BOX % use \gdef % \@addtodblcol % END == \@sdblcolelt % \@tempb % \endgroup % fi fi % END % % \output == % BEGIN % case of \outputpenalty % > -10001 -> \@makecol % \@opcol % \@floatplacement % \@startcolumn % while @fcolmade = true % do \@opcol % \@startcolumn % od % % %%% \@specialoutput == % % -10001 -> %% \@doclearpage == % if there are no footnote insertions % then throw away \box255 % \@deferlist :=G \@toplist * \@botlist % * \@deferlist % \@toplist :=G \@botlist :=G empty % if \@currlist not empty % then LaTeX error: float(s) lost % \@currlist :=G empty % fi % \@makefcolumn\@deferlist % while @fcolmade = true % do \@opcol % \@makefcolumn\@deferlist % od % if @twocolumn % then % if @firstcolumn = true % then \@dbldeferlist :=G \@dbltoplist * % \@dbldeferlist % \@dbltoplist :=G empty % \begingroup % \@dblfloatplacement % \@makefcolumn\@dbldeferlist % while @fcolmade = true % do \@outputpage % \@makefcolumn\@dbldeferlist % od % \endgroup % else \vbox{} \clearpage % fi fi % else \box255 := \vbox{\box255\vfil} % \@makecol % \@opcol % \vbox{} \penalty -10001 % fi % < -10001 -> \@pagedp :=L natural depth of box255 % \@pageht :=L natural ht of box255 % if @outputdone = true and \outputpenalty = -10003 % then throw away box 255 % else \unvbox255 %% put text back % @outputdone :=G true % fi % if there are footnote insertions % then advance \@pageht and \@pagedp and % reinsert footnotes fi % if \@currlist nonempty % then \@currbox :=L head of \@currlist % \@currlist :=G tail of \@currlist % if \count\@currbox > 0 % then \@addtocurcol %% this is a float % else \@addmarginpar %% this is a marginal note % fi % else THIS SHOULDN'T HAPPEN % fi % if \outputpenalty < 0 %% TO PERMIT PAGE BREAK % then \penalty 0 fi %% IF \@addtocurcol DIDN'T % %% INSERT A PENALTY % end case % \vsize :=G \@colroom % END % % \@combinefloats == % BEGIN % if \@toplist nonempty % then %%\@cfla == % \@elt\BOX == BEGIN \@tempbox := \vbox{\unvbox\@tempbox % \box\BOX % \vskip \floatsep} % END == \@comflelt % \@tempbox := null % \@toplist % \@outputbox := \vbox{\unvbox\@tempbox % \vskip \textfloatsep - \floatsep % \unvbox\@outputbox } % \@elt == \relax % \@freelist :=G \@freelist * \@toplist % \@toplist :=G null % fi % if \@botlist nonempty % then %%\@cflb == % \@elt == \@comflelt % \@tempbox := null % \@botlist % \@outputbox := \vbox{ \unvbox\@outputbox % \vskip \textfloatsep % \unvbox\@tempbox % \vskip - \floatsep } % \@elt == \relax % \@freelist :=G \@freelist * \@botlist % \@botlist :=G null % fi % END % % \@combinedblfloats == % BEGIN % if \@dbltoplist nonempty % then \@elt == \@comdblflelt % \@tempbox := null % \@dbltoplist % \@outputbox := \vbox to \textheight % {\boxmaxdepth :=L \maxdepth % \unvbox\@tempbox % \vskip \dbltextfloatsep - \dblfloatsep % \box\@outputbox } % \@elt == \relax % \@freelist :=G \@freelist * \@dbltoplist % \@dbltoplist :=G null % fi % END % % % USER COMMANDS THAT CALL OR AFFECT THE OUTPUT ROUTINE % ---------------------------------------------------- % % \newpage == BEGIN \par\vfil\penalty -10000 END % % \clearpage == BEGIN \newpage \vbox{} \penalty -10001 % % \cleardoublepage == BEGIN \clearpage % if @twoside = true and c@page is even % then \hbox{} \newpage fi % END % % \twocolumn == % BEGIN % \clearpage % \columnwidth :=G .5(\textwidth - \columnsep) % \hsize :=G \columnwidth % @twoside :=G true % @firstcolumn :=G true % \@dblfloatplacement % END % % \onecolumn == % BEGIN % \clearpage % \columnwidth :=G \textwidth % \hsize :=G \columnwidth % @twoside :=G false % \@floatplacement % END % % % \topnewpage{BOX} : starts a new page and puts BOX in a parbox of width % \textwidth across the top. Useful for full-width titles for % double-column pages. % SURPRISE: The stretch from \@dbltextfloatsep will be inserted % between the BOX and the top of the two columns. % % \topnewpage{BOX} == % BEGIN % \clearpage % Take \@currbox from \@freelist % \box\@currbox :=G \parbox{BOX \par % \vskip - \@dbltextfloatsep} % \count\@currbox :=G 2 % \@dbltopnum :=G 1 % \@dbltoproom :=G maxdimension % \@addtodblcol % \vsize :=G \@colht % \@colroom :=G \@colht % 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 always 1 % 5 1 iff a type 1 float % 6 1 iff a type 2 float % etc. % % A negative float specifier is used to indicate a marginal note. % % MACROS AND DATA STRUCTURES FOR PROCESSING FLOATS % ------------------------------------------------ % % A FLOAT LIST consisting of the floats in boxes \boxa ... \boxN has the form: % \@elt \boxa ... \@elt \boxN % where \boxI is defined by % \newinsert\boxI % 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 == \@elt \B1 ... \@elt \Bn % if n = 0 % then EMPTY % else \CS :=L \B1 % \LIST :=G \@elt \B2 ... \@elt \Bn % 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)/32] 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)/32] * 32. % % \@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. % \@dbldeferlist : List of double-column floats to go on subsequent pages. % % FLOAT-PLACEMENT ALGORITHMS % % \@tryfcolumn \FLIST == % BEGIN % @fcolmade :=G false % \@trylist :=G \FLIST % \@failedlist :=G empty % \begingroup % \@elt == \@xtryfc % \@trylist % \endgroup % if @fcolmade = true % then \@vtryfc \FLIST % fi % END % % \@vtryfc == % BEGIN % \@outputbox :=G \vbox{} % \@elt\BOX == BEGIN % \@outputbox :=L \vbox{ \unvbox \@outputbox % \vskip \@fpsep % \box\BOX } % END == \@wtryfc % \@flsucceed % \@outputbox :=G \vbox to \@colht{ \vskip \@fptop % \vskip -\@fpsep % \unvbox \@outputbox % \vskip \@fpbot } % \@elt == \relax % \@freelist :=G \@freelist * \@flsucceed % \FLIST :=G \@failedlist * \@flfail % END % % \@xtryfc \BOX == % BEGIN % remove first element from \@trylist % \@currtype := (\count\BOX / 32) * 32 % \@bitor \@currtype \@failedlist % @test := true if type on list % \@testfp \BOX % @test := true if no p-option % if ht of \BOX > \@colht % then @test :=G true % fi % if @test = true % then add \BOX to \@failedlist % else \@ytryfc \BOX % fi % END % % \@ytryfc == % BEGIN % \begingroup % \@flsucceed :=G \@elt\BOX % \@flfail :=G empty % \@tempdima := \ht\BOX % \@elt == \@ztryfc % \@trylist % if \@tempdima > \@fpmin % then @fcolmade :=G true % else add \BOX to \@failedlist % fi % \endgroup % if @fcolmade = true then \@elt == \@gobble fi % END % % \@ztryfc \BOX == % BEGIN % \@tempcnta := (\count\BOX / 32) * 32 % \@bitor \@tempcnta {\@failedlist \@flfail} % @test := true if on a list % \@testfp \BOX % @test := true if not p-option % \@tempdimb := \@tempdima + ht of \BOX + \@fpsep % if \@tempdimb > \@colht % then @test :=G true % fi % if @test = true % then add \BOX to \@flfail % else add \BOX to \@flsucceed % \@tempdima := \@tempdimb % fi % END % % \@testfp \BOX == BEGIN if bit 3 of \count\BOX = 0 % then @test :=G true fi % END % % \@makefcolumn \FLIST == % BEGIN % \begingroup % \@fpmin =:L 0 % \@testfp == \@gobble % \@tryfcolumn \FLIST % \endgroup % END % % \@addtobot : Tries to put insert \@currbox on \@botlist. Called only when: % * \ht BOX + \@maxsep < \@colroom % * type of \@currbox not on \@deferlist % * \@colnum > 0 % * @insert = false % If it succeeds, then: % * sets @insert true % * decrements \@botroom by \ht BOX % * decrements \@botnum and \@colnum by 1 % * decrements \@colroom by \ht BOX + either \floatsep % or \textfloatsep, as appropriate. % * sets \maxdepth to 0pt % % \@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 either \@toproom or \@botroom by \ht BOX % * decrements \@colnum 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. % If the float is put in the text, then \penalty 0 is put % right after the float, before the following \vskip, and % \outputpenalty :=L 0. % % \@addtonextcol : Tries to add \@currbox to the next column, setting @insert % true if it succeeds, false otherwise. % % \@addtodblcol : Tries to add \@currbox to the next double-column page, % adding it to \@dbltoplist if it succeeds and \@dbldeferlist % if it fails. % % \@addtobot == % BEGIN % if bit 2 of \count \@currbox = 1 % then if \@botnum > 0 % then if \@botroom > \ht \@currbox % then \@botnum :=G \botnum - 1 % \@colnum :=G \@colnum - 1 % \@tempdima :=L - \ht\@currbox - % if \@botlist empty % then \textfloatsep % else \floatsep % fi % \@botroom :=G \@botroom + \@tempdima % \@colroom :=G \@colroom + \@tempdima % add \@currbox to \@botlist % \maxdepth :=G 0pt % @insert :=L true % fi fi fi % END % % \@addtotoporbot == % BEGIN % if bit 1 of \count \@currbox = 1 % then if \@topnum > 0 % then if \@toproom > \ht \@currbox % then if \@currtype not on \@midlist or \@botlist % then \@topnum :=G \topnum - 1 % \@colnum :=G \@colnum - 1 % \@tempdima :=L - \ht\@currbox - % if \@toplist empty % then \textfloatsep % else \floatsep % fi % \@toproom :=G \@toproom + \@tempdima % \@colroom :=G \@colroom + \@tempdima % add \@currbox to \@toplist % @insert :=L true % fi fi fi fi % if @insert = false then \@addtobot fi % END % % \@addtocurcol == % BEGIN % @insert :=L false % if \@colroom > \ht \@currbox + max(\@pageht+\@pagedp, \@textmin) % + \@maxsep % then if \@colnum > 0 % then \@currtype := type of \@currbox % if \@currtype not on \@deferlist % then if \@currtype on \@botlist % then \@addtobot % else if bit0 of \count \@currbox = 1 % then decrement \@colnum % put \@currbox on \@midlist % add \@currbox + space % + a \penalty 0 to text % \outputpenalty :=L 0 % @insert := true % else \@addtotoporbot % fi fi fi fi fi % if @insert = false % then add \@currbox to \@deferlist % fi % END % % \@addtonextcol == % BEGIN % @insert :=L false % if \@colroom > \ht \@currbox + \@textmin + \@maxsep % then if \@colnum > 0 % \@currtype := type of \@currbox % then if \@currtype not on \@deferlist % then \@addtotoporbot % fi fi fi % if @insert = false % then add \@currbox to \@deferlist % fi % END % % \@addtodblcol == % BEGIN % @insert :=L false % if bit 1 of \count \@currbox = 1 % then if \@dbltopnum > 0 % then if \@dbltoproom > \ht \@currbox % then if type of \@currbox not on \@dbldeferlist % then \@dbltopnum :=G \@dbltopnum - 1 % \@tempdima := -\ht\@currbox - % if \@dbltoplist empty % then \dbltextfloatsep % else \dblfloatsep % fi % \@dbltoproom :=G \@dbltoproom+\@tempdima % \@colht :=G \@colht+\@tempdima % add \@currbox to \@dbltoplist % @insert :=L true % fi fi fi fi % if @insert = false then add \@currbox to \@dbldeferlist % END % % \@addmarginpar == % BEGIN % if \@currlist nonempty % then remove \@marbox from \@currlist %% NOTE: \@currbox = left box % add \@marbox and \@currbox to \@freelist % else LaTeX error: ? %% shouldn't happen % fi % \@tempcnta := 1 %% 1 = right, -1 = left % if @twocolumn = true % then if @firstcolumn = true % then \@tempcnta := -1 % fi % else if @twoside = true % then if count0 odd % else \@tempcnta := -1 % fi % fi % if @reversemargin = true % then \@tempcnta := -\@tempcnta % fi % fi % if \@tempcnta < 0 then \box\@marbox :=G \box\@currbox fi % \@tempdima :=L maximum(\@mparbottom - \@pageht + ht of \@marbox, 0) % if \@tempdima > 0 then LaTeX warning: 'marginpar moved' fi % \@mparbottom :=G \@pageht + \@tempdima + depth of \@marbox % + \marginparpush % \@tempdima :=L \@tempdima - ht of \@marbox % height of \@marbox :=G depth of \@marbox :=G 0 % \vskip -\@pagedp % \vskip \@tempdima % \nointerlineskip % \hbox{ if @tempcnta > 0 then \hskip \columnwidth % \hskip \marginparsep % else \hskip -\marginparsep % \hskip -\marginparwidth % fi % \box\@marbox % \hss % } % \vskip -\@tempdima % \nointerlineskip % \hbox{\vrule height 0 width 0 depth \@pagedp} % END \maxdeadcycles = 100 % floats and \marginpar's add a lot of dead cycles \let\@elt\relax \def\@next#1#2#3#4{\ifx#2\@empty #4\else \expandafter\@xnext #2\@@#1#2#3\fi} \def\@xnext \@elt #1#2\@@#3#4{\def#3{#1}\gdef#4{#2}} \newif\if@test \def\@bitor#1#2{\global\@testfalse {\let\@elt\@xbitor \@tempcnta #1\relax #2}} \def\@xbitor #1{\@tempcntb \count#1\divide\@tempcntb\@tempcnta \ifodd\@tempcntb \global\@testtrue\fi} % DEFINITION OF FLOAT BOXES: \newinsert\@fboxA \newinsert\@fboxB \newinsert\@fboxC \newinsert\@fboxD \newinsert\@fboxE \newinsert\@fboxF \newinsert\@fboxG \newinsert\@fboxH \newinsert\@fboxI \newinsert\@fboxJ \newinsert\@fboxK \newinsert\@fboxL \newinsert\@fboxM \newinsert\@fboxN \newinsert\@fboxO \newinsert\@fboxP \newinsert\@fboxQ \newinsert\@fboxR \gdef\@freelist{\@elt\@fboxA\@elt\@fboxB\@elt\@fboxC\@elt\@fboxD\@elt\@fboxE \@elt\@fboxF\@elt\@fboxG\@elt\@fboxH\@elt\@fboxI\@elt\@fboxJ \@elt\@fboxK\@elt\@fboxL\@elt\@fboxM\@elt\@fboxN \@elt\@fboxO\@elt\@fboxP\@elt\@fboxQ\@elt\@fboxR} \gdef\@toplist{} \gdef\@botlist{} \gdef\@midlist{} \gdef\@currlist{} \gdef\@deferlist{} \gdef\@dbltoplist{} \gdef\@dbldeferlist{} % PAGE LAYOUT PARAMETERS \newdimen\topmargin \newdimen\oddsidemargin \newdimen\evensidemargin \newdimen\headheight \newdimen\headsep \newdimen\footheight \newdimen\footskip \newdimen\textheight \newdimen\textwidth \newdimen\columnwidth \newdimen\columnsep \newdimen\columnseprule \newdimen\@maxdepth \@maxdepth = \maxdepth \newdimen\marginparwidth \newdimen\marginparsep \newdimen\marginparpush % PAGE STYLE PARAMETERS \newskip\floatsep \newskip\textfloatsep \newskip\intextsep \newdimen\@maxsep \newskip\dblfloatsep \newskip\dbltextfloatsep \newdimen\@dblmaxsep \newskip\@fptop \newskip\@fpsep \newskip\@fpbot \newskip\@dblfptop \newskip\@dblfpsep \newskip\@dblfpbot % INTERNAL REGISTERS \newcount\@topnum \newdimen\@toproom \newcount\@dbltopnum \newdimen\@dbltoproom \newcount\@botnum \newdimen\@botroom \newcount\@colnum \newdimen\@textmin \newdimen\@fpmin \newdimen\@colht \newdimen\@colroom \newdimen\@pageht \newdimen\@pagedp \newdimen\@mparbottom \@mparbottom\z@ \newcount\@currtype \newbox\@outputbox \newbox\@leftcolumn \newif\if@insert \newif\if@fcolmade \newif\if@specialpage \@specialpagefalse \newif\if@twoside \@twosidefalse \newif\if@firstcolumn \@firstcolumntrue \newif\if@twocolumn \@twocolumnfalse \newif\if@outputdone \@outputdonefalse \newif\if@reversemargin \@reversemarginfalse \def\newpage{\par\vfil\penalty -\@M} \def\clearpage{\newpage \vbox{}\penalty -\@Mi} \def\cleardoublepage{\clearpage\if@twoside \ifodd\c@page\else \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\fi} \def\twocolumn{\clearpage \global\columnwidth\textwidth \global\advance\columnwidth -\columnsep \global\divide\columnwidth\tw@ \global\hsize\columnwidth \global\@twocolumntrue \global\@firstcolumntrue \@dblfloatplacement\@ifnextchar[{\@topnewpage}{}} \def\onecolumn{\clearpage\global\columnwidth\textwidth \global\hsize\columnwidth \global\@twocolumnfalse \@floatplacement} \long\def\@topnewpage[#1]{\@next\@currbox\@freelist{}{} \global\setbox\@currbox\vbox{\hsize\textwidth \@parboxrestore #1\par\vskip -\dbltextfloatsep}\global\count\@currbox\tw@ \global\@dbltopnum\@ne \global\@dbltoproom\maxdimen\@addtodblcol \vsize\@colht \@colroom\@colht} \output{\ifnum\outputpenalty <-\@M\@specialoutput\else \@makecol\@opcol\@floatplacement\@startcolumn \@whilesw\if@fcolmade \fi{\@opcol\@startcolumn}\fi \global\vsize\@colroom} \def\@specialoutput{\ifnum\outputpenalty > -\@Mii \@doclearpage \else \setbox\@tempboxa\vbox{\unvbox\@cclv}\@pagedp\dp\@tempboxa \@pageht\ht\@tempboxa \ifnum\outputpenalty =-\@Mii \global\@outputdonefalse\fi \if@outputdone \else \unvbox\@tempboxa \global\@outputdonetrue \fi \ifvoid\footins\else\advance\@pageht\ht\footins \advance\@pageht\skip\footins \advance\@pagedp\dp\footins \insert\footins{\unvbox\footins}\fi \@next\@currbox\@currlist{\ifnum\count\@currbox >\z@ \@addtocurcol\else\@addmarginpar\fi}\@latexbug \ifnum \outputpenalty <\z@ \penalty \z@ \fi \fi} \def\@doclearpage{\ifvoid\footins \setbox\@tempboxa\box\@cclv \xdef\@deferlist{\@toplist\@botlist \@deferlist}\gdef\@toplist{}\gdef\@botlist{}\ifx\@currlist \@empty\else\@latexerr{Float(s) lost}\@ehb\gdef\@currlist{}\fi \@makefcolumn\@deferlist \@whilesw\if@fcolmade \fi{\@opcol \@makefcolumn\@deferlist}\if@twocolumn \if@firstcolumn \xdef\@dbldeferlist{\@dbltoplist \@dbldeferlist}\gdef\@dbltoplist{}\begingroup \@dblfloatplacement \@makefcolumn\@dbldeferlist \@whilesw\if@fcolmade \fi{\@outputpage \@makefcolumn\@dbldeferlist}\endgroup \else \vbox{}\clearpage \fi\fi \else\setbox\@cclv\vbox{\box\@cclv\vfil}\@makecol\@opcol \vbox{}\penalty -\@Mi \fi} \def\@opcol{\global\@mparbottom\z@\if@twocolumn\@outputdblcol\else \@outputpage \@colht\textheight \fi} \def\@outputdblcol{\if@firstcolumn \global\@firstcolumnfalse \global\setbox\@leftcolumn\box\@outputbox \else \global\@firstcolumntrue \setbox\@outputbox\vbox{\hbox to\textwidth{\hbox to\columnwidth {\box\@leftcolumn \hss}\hfil \vrule width\columnseprule\hfil \hbox to\columnwidth{\box\@outputbox \hss}}}\@combinedblfloats \@outputpage \begingroup \@dblfloatplacement \@startdblcolumn \@whilesw\if@fcolmade \fi{\@outputpage\@startdblcolumn}\endgroup \fi} \def\@makecol{\ifvoid\footins \setbox\@outputbox\box\@cclv \else\setbox\@outputbox \vbox{\unvbox\@cclv\vskip\skip\footins\footnoterule\unvbox\footins}\fi \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth \unvbox\@outputbox}\global\maxdepth\@maxdepth} \def\@outputpage{\catcode`\ =10 \if@specialpage \global\@specialpagefalse\@nameuse{ps@\@specialstyle}\fi \if@twoside \ifodd\count\z@ \else \let\@oddhead\@evenhead \let\@oddfoot\@evenfoot \oddsidemargin\evensidemargin \fi\fi \shipout \vbox{\normalsize \baselineskip\z@ \lineskip\z@ \vskip \topmargin \moveright\oddsidemargin \vbox{\vbox to\headheight{\vfil \hbox to\textwidth{\@oddhead}} \vskip \headsep \box\@outputbox \baselineskip\footskip \hbox to\textwidth{\@oddfoot}}}\global\@colht\textheight \@stepcounter{page}} \def\@combinefloats{\ifx\@toplist\@empty\else\@cfla\fi \ifx\@botlist\@empty\else\@cflb\fi} \def\@cfla{\let\@elt\@comflelt \setbox\@tempboxa\vbox{}\@toplist \setbox\@outputbox\vbox{\unvbox\@tempboxa\vskip-\floatsep \vskip\textfloatsep \unvbox\@outputbox}\let\@elt\relax \xdef\@freelist{\@freelist\@toplist}\gdef\@toplist{}} \def\@cflb{\let\@elt\@comflelt \setbox\@tempboxa\vbox{}\@botlist \setbox\@outputbox\vbox{\unvbox\@outputbox \vskip\textfloatsep \unvbox\@tempboxa \vskip-\floatsep}\let\@elt\relax \xdef\@freelist{\@freelist\@botlist}\gdef\@botlist{}} \def\@comflelt#1{\setbox\@tempboxa \vbox{\unvbox\@tempboxa\box #1\vskip\floatsep}} \def\@combinedblfloats{\ifx\@dbltoplist\@empty\else \let\@elt\@comdblflelt \setbox\@tempboxa\vbox{}\@dbltoplist \setbox\@outputbox\vbox to\textheight {\boxmaxdepth\maxdepth \unvbox\@tempboxa\vskip-\dblfloatsep \vskip\dbltextfloatsep \box\@outputbox}\let\@elt\relax \xdef\@freelist{\@freelist\@dbltoplist}\gdef\@dbltoplist{}\fi} \def\@comdblflelt#1{\setbox\@tempboxa \vbox{\unvbox\@tempboxa\box #1\vskip\dblfloatsep}} \def\@startcolumn{\global\@colroom\@colht \ifx\@deferlist\@empty\global\@fcolmadefalse\else\@xstartcol\fi} \def\@xstartcol{\@tryfcolumn\@deferlist \if@fcolmade\else \begingroup\edef\@tempb{\@deferlist}\gdef\@deferlist{}\let\@elt\@scolelt \@tempb\endgroup\fi} \def\@scolelt#1{\def\@currbox{#1}\@addtonextcol} \def\@startdblcolumn{\global\@colht\textheight \@tryfcolumn\@dbldeferlist \if@fcolmade\else \begingroup \edef\@tempb{\@dbldeferlist}\gdef\@dbldeferlist{}\let\@elt\@sdblcolelt \@tempb\endgroup\fi} \def\@sdblcolelt#1{\def\@currbox{#1}\@addtodblcol} \def\@tryfcolumn #1{\global\@fcolmadefalse \xdef\@trylist{#1}\xdef\@failedlist {}\begingroup \let\@elt\@xtryfc \@trylist \endgroup \if@fcolmade \@vtryfc #1\fi} \def\@vtryfc #1{\global\setbox\@outputbox\vbox{}\let\@elt\@wtryfc \@flsucceed \global\setbox\@outputbox\vbox to\@colht{\vskip \@fptop \vskip -\@fpsep \unvbox \@outputbox \vskip \@fpbot}\let\@elt\relax \xdef #1{\@failedlist\@flfail}\xdef\@freelist{\@freelist\@flsucceed}} \def\@wtryfc #1{\global\setbox\@outputbox\vbox{\unvbox\@outputbox \vskip\@fpsep\box #1}} \def\@xtryfc #1{\@next\@tempa\@trylist{}{}\@currtype \count #1\divide\@currtype\@xxxii \multiply\@currtype\@xxxii \@bitor \@currtype \@failedlist \@testfp #1\ifdim \ht #1>\@colht \global\@testtrue\fi \if@test \@cons\@failedlist #1\else \@ytryfc #1\fi} \def\@ytryfc #1{\begingroup \gdef\@flsucceed{\@elt #1}\gdef\@flfail {}\@tempdima\ht #1\let\@elt\@ztryfc \@trylist \ifdim \@tempdima >\@fpmin \global\@fcolmadetrue \else \@cons\@failedlist #1\fi \endgroup \if@fcolmade \let\@elt\@gobble \fi} \def\@ztryfc #1{\@tempcnta\count #1\divide\@tempcnta\@xxxii \multiply\@tempcnta\@xxxii \@bitor \@tempcnta {\@failedlist \@flfail}\@testfp #1\@tempdimb\@tempdima \advance\@tempdimb\ht #1\advance \@tempdimb\@fpsep \ifdim \@tempdimb >\@colht \global\@testtrue\fi \if@test \@cons\@flfail #1\else \@cons\@flsucceed #1\@tempdima\@tempdimb \fi} \def\@testfp #1{\@tempcnta\count #1\divide\@tempcnta 8\relax \ifodd\@tempcnta \else \global\@testtrue\fi} \def\@makefcolumn #1{\begingroup \@fpmin\z@ \let\@testfp\@gobble \@tryfcolumn #1\endgroup} \def\@addtobot{\@tempcnta\count\@currbox\divide\@tempcnta4 \ifodd\@tempcnta \ifnum \@botnum >\z@ \ifdim \@botroom >\ht\@currbox \global\advance\@botnum\m@ne \global\advance\@colnum\m@ne \@tempdima -\ht\@currbox \advance\@tempdima -\ifx\@botlist\@empty \textfloatsep \else\floatsep\fi \global\advance\@botroom \@tempdima \global\advance\@colroom \@tempdima \@cons\@botlist\@currbox \global\maxdepth\z@ \@inserttrue\fi\fi\fi} \def\@addtotoporbot{\@tempcnta\count\@currbox \divide\@tempcnta\tw@ \ifodd\@tempcnta \ifnum \@topnum >\z@ \ifdim\@toproom >\ht\@currbox \@bitor\@currtype{\@midlist\@botlist}\if@test\else \global\advance\@topnum\m@ne \global\advance\@colnum\m@ne \@tempdima-\ht\@currbox \advance\@tempdima -\ifx\@toplist\@empty \textfloatsep \else\floatsep\fi \global\advance\@toproom \@tempdima \global\advance\@colroom \@tempdima \@cons\@toplist\@currbox \@inserttrue \fi\fi\fi\fi \if@insert\else\@addtobot \fi} \def\@addtonextcol{\@insertfalse\@tempdima\ht\@currbox \advance\@tempdima\@textmin\advance\@tempdima\@maxsep \ifdim\@colroom >\@tempdima \ifnum\@colnum >\z@ \@currtype\count\@currbox \divide\@currtype\@xxxii \multiply\@currtype\@xxxii \@bitor\@currtype\@deferlist \if@test\else \@addtotoporbot \fi\fi\fi \if@insert\else \@cons\@deferlist\@currbox\fi} \def\@addtodblcol{\@insertfalse \@tempcnta\count\@currbox \divide\@tempcnta\tw@ \ifodd\@tempcnta \ifnum\@dbltopnum >\z@ \ifdim\@dbltoproom >\ht\@currbox \@currtype\count\@currbox \divide\@currtype\@xxxii \multiply\@currtype\@xxxii \@bitor\@currtype\@dbldeferlist \if@test\else \global\advance\@dbltopnum\m@ne \@tempdima -\ht\@currbox \advance\@tempdima -\ifx\@dbltoplist\@empty \dbltextfloatsep\else\dblfloatsep\fi \global\advance\@dbltoproom \@tempdima \global\advance\@colht \@tempdima \@cons\@dbltoplist\@currbox \@inserttrue \fi\fi\fi\fi \if@insert\else \@cons\@dbldeferlist\@currbox \fi} \def\@addtocurcol{\@insertfalse \@tempdima\@pageht \advance\@tempdima\@pagedp \ifdim \@textmin > \@tempdima \@tempdima\@textmin \fi \advance\@tempdima\ht\@currbox \advance\@tempdima\@maxsep \ifdim\@colroom >\@tempdima \ifnum\@colnum >\z@ \@currtype\count\@currbox \divide\@currtype\@xxxii \multiply\@currtype\@xxxii \@bitor\@currtype\@deferlist \if@test\else \@bitor\@currtype\@botlist \if@test \@addtobot \else \ifodd\count\@currbox \global\advance\@colnum\m@ne \@cons\@midlist\@currbox \vskip\intextsep \box\@currbox \penalty\z@ \vskip\intextsep \ifnum\outputpenalty <-\@Mii \vskip -\parskip\fi \outputpenalty\z@ \@inserttrue \else \@addtotoporbot \fi\fi\fi\fi\fi \if@insert\else\@cons\@deferlist\@currbox\fi} \def\@addmarginpar{\@next\@marbox\@currlist{\@cons\@freelist\@marbox \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne \if@twocolumn \if@firstcolumn \@tempcnta\m@ne \fi \else \if@twoside \ifodd\c@page \else\@tempcnta\m@ne \fi \fi \if@reversemargin \@tempcnta -\@tempcnta \fi \fi \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi \@tempdima\@mparbottom \advance\@tempdima -\@pageht \advance\@tempdima\ht\@marbox \ifdim\@tempdima >\z@ \@warning{Marginpar on page \co@page\space moved}\else\@tempdima\z@ \fi \global\@mparbottom\@pageht \global\advance\@mparbottom\@tempdima \global\advance\@mparbottom\dp\@marbox \global\advance\@mparbottom\marginparpush \advance\@tempdima -\ht\@marbox \global\ht\@marbox\z@ \global\dp\@marbox\z@ \vskip -\@pagedp \vskip\@tempdima\nointerlineskip \hbox to\columnwidth {\ifnum \@tempcnta >\z@ \hskip\columnwidth \hskip\marginparsep \else \hskip -\marginparsep \hskip -\marginparwidth \fi \box\@marbox \hss} \vskip -\@tempdima \nointerlineskip \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp}} % **************************************** % * 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\relax} \def\makeatother{\catcode`\@=12\relax} \def\@lowpenalty{51} \def\@midpenalty{151} \def\@highpenalty{301} % LIST % ENUMERATION % ITEMIZE % ARRAY AND TABULAR % THE PICTURE ENVIRONMENT \unitlength = 1pt \fboxsep = 3pt \fboxrule = .4pt %% FOOTNOTES %\def\footnoterule{} % INITIALIZED BY PLAIN %\skip\footins{} % INITIALIZED BY PLAIN %\interfootnotelinepenalty % INITIALIZED BY PLAIN \@maxdepth = \maxdepth