%
CHARACTER CODES
%
Catcodes:
\catcode`\{=1 % left brace is begin-group character
\catcode`\}=2 % right brace is end-group character
\message{catcodes ...}
% We had to define the \catcodes right away, before the message line,
% since \message uses the { and } characters.
% When INITEX (the TeX initializer) starts up,
% it has defined the following \catcode values:
% \catcode`\^^@=9 % ascii null is ignored
% \catcode`\^^M=5 % ascii return is end-line
% \catcode`\\=0 % backslash is TeX escape character
% \catcode`\%=14 % percent sign is comment character
% \catcode`\ =10 % ascii space is blank space
% \catcode`\^^?=15 % ascii delete is invalid
% \catcode`\A=11 ... \catcode`\Z=11 % uppercase letters
% \catcode`\a=11 ... \catcode`\z=11 % lowercase letters
% all others are type 12 (other)
\chardef\active=13 % \active is a mnemonic for category 13 (active)
\catcode`\$=3 % dollar sign ('044) is math shift
\catcode`\&=4 % ampersand ('046) is alignment tab
\catcode`\#=6 % hash mark ('043) is macro parameter character
\catcode`\^=7 % circumflex ('136) is for superscripts
\catcode`\←=8 % underline ('137) is for subscripts
\catcode'011=10 % ascii tab is a blank space
\catcode'176=\active % ascii tilde (~) is active
\catcode`\^^L=\active
\outer\def^^L{\par} % ascii form-feed ('014) is "\outer\par"
% We make @ signs act like letters, temporarily, to avoid conflict
% between user names and internal control sequences of plain format.
\catcode`@=11
% We also cause <returns> to be ignored, temporarily, to avoid them being
% included in replacement texts of definitions.
\endlinechar=-1
\let\bgroup={ \let\egroup=}
%
REGISTER ALLOCATION TOOLS
\message{allocation ...}
% Here are macros for the automatic allocation of \count, \box, \dimen,
% \glue (\skip), \muglue (\muskip), and \toks registers,
% as well as \read and \write
% stream numbers, \fam codes, and \insert numbers.
%
Notes on register usage
% When a register is used only temporarily, it need not be allocated;
% grouping can be used, making the value previously in the register return
% after the close of the group. The main use of these macros is for
% registers that are defined by one macro and used by others, possibly at
% different nesting levels. All such registers should be defined through
% these macros; otherwise conflicts may occur, especially when two or more
% more macro packages are being used at once.
% The following counters are reserved:
% 0 to 9 page numbering
% 10 count allocation
% 11 dimen allocation
% 12 glue allocation
% 13 muglue allocation
% 14 box allocation
% 15 toks allocation
% 16 read file allocation
% 17 write file allocation
% 18 math family allocation
% 19 insert allocation
% 20 the most recently allocated number
% 21 constant -1
% New counters are allocated starting with 22, 23, etc. Other registers are
% allocated starting with 10. This leaves 0 through 9 for the user to play
% with safely, except that counts 0 to 9 are considered to be the page and
% subpage numbers (since they are displayed during output). In this scheme,
% \count 10 always contains the number of the highest-numbered counter that
% has been allocated, \count 14 the highest-numbered box, etc.
% Inserts are given numbers 254, 253, etc., since they require a \count,
% \dimen, \glue, and \box all with the same number; \count 19 contains the
% lowest-numbered insert that has been allocated. Of course, \box255 is
% reserved for \output; \count255, \dimen255, and \glue255 can be used freely.
% It is recommends that macro designers always use
% \global assignments with respect to registers numbered 1, 3, 5, 7, 9, and
% always non-\global assignments with respect to registers 0, 2, 4, 6, 8, 255.
% This will prevent ``save stack buildup'' that might otherwise occur.
%
Internal registers used by the allocator
\count10=21 % allocates \count registers 22, 23, ...
\count11=9 % allocates \dimen registers 10, 11, ...
\count12=9 % allocates \glue registers 10, 11, ...
\count13=9 % allocates \muglue registers 10, 11, ...
\count14=9 % allocates \box registers 10, 11, ...
\count15=9 % allocates \toks registers 10, 11, ...
\count16=-1 % allocates input streams 0, 1, ...
\count17=-1 % allocates output streams 0, 1, ...
\count18=3 % allocates math families 4, 5, ...
\count19=255 % allocates insertions 254, 253, ...
\countdef\insc@unt=19 % the insertion counter
\countdef\allocationnumber=20 % the most recent allocation
\countdef\m@ne=21 \m@ne=-1 % a handy constant
\def\wlog{\immediate\write\m@ne} % write on log file (only)
%
Internal names for some scratch registers that don't need to be allocated
\countdef\count@=255
\dimendef\dimen@=0
\dimendef\dimen@i=1 % global only
\dimendef\dimen@ii=2
\gluedef\glue@=0
\toksdef\toks@=0
%
Register allocation macros
% Now, we define \newcount, \newbox, etc. so that you can say \newcount\foo
% and \foo will be defined (with \countdef) to be the next counter.
% To find out which counter \foo is, you can look at \allocationnumber.
% Since there's no \boxdef command, \chardef is used to define a \newbox,
% \newinsert, \newfam, and so on.
\outer\def\newcount{\alloc@0\count\countdef\insc@unt}
\outer\def\newdimen{\alloc@1\dimen\dimendef\insc@unt}
\outer\def\newglue{\alloc@2\glue\gluedef\insc@unt}
\outer\def\newmuglue{\alloc@3\muglue\mugluedef\@cclvi}
\outer\def\newbox{\alloc@4\box\chardef\insc@unt}
\outer\def\newhelp#1#2{\newtoks#1#1\expandafter{\csname#2\endcsname}}
\outer\def\newtoks{\alloc@5\toks\toksdef\@cclvi}
\outer\def\newread{\alloc@6\read\chardef\sixt@@n}
\outer\def\newwrite{\alloc@7\write\chardef\sixt@@n}
\outer\def\newfam{\alloc@8\fam\chardef\sixt@@n}
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
\ch@ck#1#4#2% make sure there's still room
\allocationnumber=\count1#1%
\global#3#5=\allocationnumber
\wlog{\string#5=\string#2\the\allocationnumber}}
\def\ch@ck#1#2#3{\ifnum\count1#1<#2%
\else\errmessage{No room for a new #3}\fi}
%
Allocation of insertion categories
\outer\def\newinsert#1{\global\advance\insc@unt by\m@ne
\ch@ck0\insc@unt\count
\ch@ck1\insc@unt\dimen
\ch@ck2\insc@unt\glue
\ch@ck4\insc@unt\box
\allocationnumber=\insc@unt
\global\chardef#1=\allocationnumber
\wlog{\string#1=\string\insert\the\allocationnumber}}
%
If statement allocation:
% For example, \newif\iffoo creates \footrue, \foofalse to go with \iffoo.
\outer\def\newif#1{\count@\escapechar \escapechar\m@ne
\expandafter\expandafter\expandafter
\edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}%
\expandafter\expandafter\expandafter
\edef\@if#1{false}{\let\noexpand#1=\noexpand\iffalse}%
\@if#1{false}\escapechar\count@} % the condition starts out false
\def\@if#1#2{\csname\expandafter\if@\string#1#2\endcsname}
{\uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}} % `if' is required
%
Macro to extend definitions:
% For example, \appendef\foo{\baz bar gee} will redefine \foo
% as being its old replacement text followed by "\baz bar gee ".
% Works only for parameterless macros, though...
\def\appendef#1#2{\toks0=\expandafter{#1} \toks2={#2}
\edef#1{\the\toks0 \the\toks2}}
%
GENERAL-PURPOSE DIMENSIONS, GLUES, PENALTIES
\message{registers ...}
%
Some private registers:
\newdimen\p@ \p@=1pt % this saves macro space and time
\newdimen\z@ \z@=0pt % can be used both for 0pt and 0
\newglue\z@glue \z@glue=0pt plus0pt minus0pt
\newbox\voidb@x % permanently void box register
%
Other useful definitions:
\def\empty{}
\def\null{\hbox{}}
\newdimen\maxdimen
\maxdimen=16383.99999pt % the largest legal <dimen>
%
Standard math families
% If you say \fam=\XXX, this will set the standard family for math to \XXX
% This will affect all characters whose math class (first digit of
% mathcode) is 7, usually letters and greek letters.
% If \fam is not defined, TeX will use the character's default family,
% that is the second digit of the character's mathcode. Note that \fam is
% set to -1 (undefined) whenever math mode is entered.
% Characters whose class is not 7 get always the family specified in their
% mathcode.
\chardef\rmfam=\z@ % Roman fonts
\chardef\ifam=\@ne % Math italic fonts
\chardef\syfam=\tw@ % Symbol fonts
\chardef\exfam=\thr@@ % Symbol fonts
\newfam\itfam % Text italic fonts
\newfam\ttfam % typewriter fonts
%
Magnification factors:
% \mag=1000 % INITEX does this
\def\magstephalf{1095 }
\def\magstep#1{\ifcase#1 \@m\or 1200\or 1440\or 1728\or 2074\or 2488\fi\relax}
%
Useful penalties (to follow \hbreak, \vbreak, or similar)
\def\forbidden{\penalty \@M}
\def\allowed{\penalty \z@}
\def\suggested{\penalty -200 }
\def\preferred{\penalty -500 }
\def\required{\penalty-\@M}
%
DEBUGGING
\message{debugging ...}
%
Set TeX's trace parameters
% \pausing=0
% \tracingonline=0
% \tracingmacros=0
% \tracingstats=0
% \tracingparagraphs=0
% \tracingpages=0
% \tracingoutput=0
\tracinglostchars=1
% \tracingcommands=0
% \tracingrestores=0
% \globaldefs=0
% \maxdeadcycles=25 % INITEX does this
\showboxbreadth=5
\showboxdepth=3
\hfuzz=0.1pt
\vfuzz=0.1pt
\overfullrule=5pt
\def\tracingall{\tracingonline\@ne\tracingcommands\tw@
\tracingstats\tw@\tracingpages\@ne\tracingoutput\@ne
\tracinglostchars\@ne\tracingmacros\@ne\tracingparagraphs\@ne
\tracingrestores\@ne\showboxbreadth\maxdimen
\showboxdepth\maxdimen\errorstopmode}
\def\showhyphens#1{\setbox0\vbox{
\parfillglue\z@glue\hsize\maxdimen\tenrm
\pretolerance\m@ne\tolerance\m@ne\hbadness0\showboxdepth0\ #1}}
%
Show box boundaries.
% Usage: \tracebox<box> is basically the same as <box>,
% but will put a thin border just inside it
\def\tracebox#1{\vbox
{\hrule height0.2pt\kern-0.2pt
\hbox{\vrule width0.2pt\kern-0.2pt #1 \kern-0.2pt\vrule width0.2pt}
\kern-0.2pt\hrule height0.2pt}}
%
Bug mark.
% Usage: As seen in figure 3.\bug, ...
% The \bug macro is also useful for flagging TEX errors in
% the press file; just answer i\bug<CR> to error messages.
\newbox\bugb@x % to be set by the font-loading file
\def\bug{{\copy\bugb@x}}
\def\scream{\errmessage{bug here!}\bug{}}
%
ORDINARY TEXT
\message{text ...}
%
Non-dimensional parameters affecting line breaking and page building:
\pretolerance=100
\tolerance=200 % INITEX sets this to 10000
\hbadness=1000
\vbadness=1000
\linepenalty=10
\hyphenpenalty=50
\exhyphenpenalty=50
\binoppenalty=700
\relpenalty=500
% \outputpenalty=0, set before TeX enters \output
\doublehyphendemerits=10000
\finalhyphendemerits=5000
\adjdemerits=10000
% \looseness=0, cleared by TeX after each paragraph
% \hangafter=1 % INITEX does this, also TeX after each paragraph
\defaulthyphenchar=`\-
\defaultskewchar=-1
\newlinechar=-1
%
Character spacing factors:
% INITEX sets \sfcode x=1000 for all x, except that \sfcode`X=999
% for uppercase letters. The following changes are needed:
\sfcode`\)=0 \sfcode`\'=0 \sfcode`\]=0
\def\frenchspacing{\sfcode`\.\@m \sfcode`\?\@m \sfcode`\!\@m
\sfcode`\:\@m \sfcode`\;\@m \sfcode`\,\@m}
\def\nonfrenchspacing{\sfcode`\.3000\sfcode`\?3000\sfcode`\!3000%
\sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 }
\def\slash{/\penalty\exhyphenpenalty} % a `/' that acts like a `-'
%
standard horizontal glues and skips (values to be defined externally)
\def\thinspace{\kern .16667em }
\def\negthinspace{\kern-.16667em }
\def\enspace{\kern.5em }
\def\space{ }
\def~{\penalty\@M \ } % `tying space'
\def\enskip{\hskip.5em\relax}
\def\quad{\hskip1em\relax}
\let\emskip=\quad
\def\qquad{\hskip2em\relax}
%
Type faces:
% These macros change both the current math family and the current text
% font. Note that \textfont\rmfam is almost required to be a standard
% TeX font., but \rmfont may be different from \textfont\rmfam.
% Same for other styles.
\def\rm{\fam=\rmfam\rmfont}
\def\it{\fam=\itfam\itfont}
\def\mit{\fam=\ifam\ifont}
\def\tt{\fam=\ttfam\ttfont}
\def\sy{\fam=\syfam\syfont}
%
Start horizontal mode:
\def\hmode{\unhbox\voidb@x} % begins a paragraph, if necessary
%
Line breaks:
\def\hbreak{} % Allows us to say \hbreak\forbidden, \hbreak\suggested, etc
% Poor man's \par (forces line break w/o parindent or parsep)
\def\brk{\hskip\parfillglue\hbreak\required}
\let\endgraf=\par \let\endline=\cr
%
Special meanings of <return>:
% In \obeylines, we say `\let^^M=\par' instead of `\def^^M{\par}'
% since this allows, for example, `\let\par=\cr \obeylines \halign{...'
\def\^^M{\ } % control <return> = control <space>
\def\^^I{\ } % same for <tab>
% In \obeylines, we say `\let^^M=#1' instead of `\def^^M{#1}'
% since this allows, for example, `\let\par=\cr \obeylines \halign{...'
{\catcode`\^^M=\active % these lines must end with %
\gdef\obeylines{\catcode`\^^M\active \let^^M=\par}}%
{\catcode`\^^M=\active \global\let^^M=\par}% in case ^^M appears in a \write
%
Obey spaces:
\def\obeyspaces{\catcode`\ \active}
{\obeyspaces\global\let =\space}
%
Uppercase/lowercase mapping:
% INITEX sets \uccode`x=`X and \uccode `X=`X for all letters x,
% and \lccode`x=`x, \lccode`X=`x; all other values are zero.
% No changes to those tables are needed in plain TeX format.
%
Underlining (text)
\def\underbar#1{$\setbox\z@\hbox{#1}\@dp\z@=\z@
\m@th \underline{\box\z@}$}
%
Alignment macros for overstriking and accenting
% \rlap{foo} will write foo and backspace by its width
% \llap{foo} will backspace by the width of foo and write it
\def\rlap#1{\hbox to\z@{#1\hss}}
\def\llap#1{\hbox to\z@{\hss#1}}
% \overlap{foo\crcr baz} will put foo and baz on boxes of the same length
% and superimpose the two boxes so that the origins coincide.
% Normally they will be aligned by their left edge,
% but centering and other justifications can be obtained with \hfil, \hidewidth, etc.
\def\overlap#1{\hmode\vtop{\linesep\z@glue\lineseplimit-\maxdimen
\putalign{#1}}}
% \putatop{foo \crcr baz} will put foo on top of baz
% \putbeneath{baz \crcr foo} put foo under baz
% The spacing between foo and baz can be specified by setting \linesep
% and \lineseplimit before calling the macros
\def\putabove#1{\hmode\vbox{\putalign{#1}}}
\def\putbelow#1{\hmode\vtop{\putalign{#1}}}
\def\putalign#1{\baselinesep\z@glue\tabglue\z@glue
\halign{##\crcr#1\crcr}}
%
Special characters and accents:
% Transforms a math hex code into a text-mode character
\def\mathhexbox#1#2#3{\hmode\hbox{$\m@th \mathchar"#1#2#3$}}
\def\dots{\relax\ifmmode\ldots\else$\m@th\ldots\,$\fi}
%
Internal notes (from author to self).
% Usage:
% \note{Fix figure numbers below!}
% \move{Blah blah blah}
% \fix{We know that $\pi=\sqrt{10}$, so...}
% \junk{Blah blah}
\def\note#1{{{\bf [note:} #1{\bf ]}}} % for annotations to manuscript
\def\move#1{{{\bf [move this:} #1{\bf ]}}} % things to be moved
\def\fix#1{{{\bf [fix this:} #1{\bf ]}}} % things to be fixed
\def\junk#1{{{\bf [JUNK:} #1{\bf ]}}} % garbage kept just in case
%
BOX TWIDDLING AND ALIGNMENT
\message{box twiddling ...}
%
Synonym of \dp for compatibility:
\let\@dp=\dp % replace back \@dp by \dp some day...
%
Macros for special alignment entries: \multispan, \hidewidth
\newglue\hideglue \hideglue=-1000pt plus 1fill %
\def\hidewidth{\hskip\hideglue}
\newcount\mscount
\def\multispan#1{\omit \mscount#1
\loop\ifnum\mscount>\@ne \sp@n\repeat}
\def\sp@n{\span\omit\advance\mscount\m@ne}
%
Tabs
\newif\ifus@ \newif\if@cr
\newbox\tabs \newbox\tabsyet \newbox\tabsdone
\def\cleartabs{\global\setbox\tabsyet\null \setbox\tabs\null}
\outer\def\settabs{\setbox\tabs\null \futurelet\next\sett@b}
\def\sett@b{\ifx\next\+\let\next\relax
\def\next{\afterassignment\s@tt@b\let\next}%
\else\let\next\s@tcols\fi\next}
\def\s@tt@b{\let\next\relax\us@false\m@ketabbox}
\def\tabalign{\us@true\m@ketabbox} % non-\outer version of \+
\outer\def\+{\tabalign}
\def\s@tcols#1\columns{\count@#1 \dimen@\hsize
\loop\ifnum\count@>\z@ \@nother \repeat}
\def\@nother{\dimen@ii\dimen@ \divide\dimen@ii\count@
\setbox\tabs\hbox{\hbox to\dimen@ii{}\unhbox\tabs}%
\advance\dimen@-\dimen@ii \advance\count@\m@ne}
\def\m@ketabbox{\begingroup
\global\setbox\tabsyet\copy\tabs
\global\setbox\tabsdone\null
\def\cr{\@crtrue\crcr\egroup\egroup
\ifus@\unvbox\z@\lastbox\fi\endgroup
\setbox\tabs\hbox{\unhbox\tabsyet\unhbox\tabsdone}}%
\setbox\z@\vbox\bgroup\@crfalse
\ialign\bgroup&\t@bbox##\t@bb@x\crcr}
\def\t@bbox{\setbox\z@\hbox\bgroup}
\def\t@bb@x{\if@cr\egroup % now \box\z@ holds the column
\else\hss\egroup \global\setbox\tabsyet\hbox{\unhbox\tabsyet
\global\setbox\@ne\lastbox}% now \box\@ne holds its size
\ifvoid\@ne\global\setbox\@ne\hbox to\wd\z@{}%
\else\setbox\z@\hbox to\wd\@ne{\unhbox\z@}\fi
\global\setbox\tabsdone\hbox{\box\@ne\unhbox\tabsdone}\fi
\box\z@}
%
VERTICAL MODE GOODIES
\message{vertical mode ...}
%
Strut
% The following box should be set by \smallsize or \normalsize
% (or \largesize, if available) to an \hbox containing a \vrule of
% zero width, whose height and depth are slightly larger than
% those of the of the current \rm font.
\newbox\strutbox
\def\strut{\relax\ifmmode\copy\strutbox\else\unhcopy\strutbox\fi}
%
Standard vertical glues and skips (values to be defined externally)
\def\smallvglue{\baselinesep}
\def\medvglue{1.5\baselinesep}
\def\bigvglue{\tw@\baselinesep}
\def\smallvskip{\vskip\smallvglue}
\def\medvskip{\vskip\medvglue}
\def\bigvskip{\vskip\bigvglue}
\def\unvskip{\ifdim\lastglue=\z@\else\vskip-\lastglue\fi}
%
Page breaks
\def\vbreak{\par} % page breaks are automatic in vertical mode
\def\eject{\vbreak\required}
\def\goodbreak{\vbreak\preferred} % encourage break
\def\supereject{\vbreak\penalty-\@MM}
\def\filbreak{\par\vfil\penalty-200\vfilneg}
\def\smallvbreak{\par\glue@=\smallvglue\ifdim\lastglue<\glue@
\unvskip\penalty-50\vskip\glue@\fi}
\def\medvbreak{\par\glue@=\medvglue\ifdim\lastglue<\glue@
\unvskip\penalty-100\vskip\glue@\fi}
\def\bigvbreak{\par\glue@=\bigvglue\ifdim\lastglue<\glue@
\unvskip\penalty-200\vskip\glue@\fi}
%
Non-dimensional parameters affecting page building/breaking
\clubpenalty=150
% \postdisplaypenalty=0
% \interlinepenalty=0
% \floatingpenalty=0, set during \insert
\widowpenalty=150
\displaywidowpenalty=50
\brokenpenalty=100
\predisplaypenalty=10000
%
Interline glue options
\def\nointerlineskip{\prevdepth-1000\p@} % no interline skip here
\def\offinterlineskip{\baselinesep=-1000\p@
\linesep=\z@ \lineseplimit\maxdimen} % turn off all interline skip
%
Full-width lines
\def\line{\hbox to\hsize}
\def\leftline#1{\line{#1\hss}}
\def\rightline#1{\line{\hss#1}}
\def\centerline#1{\line{\hss#1\hss}}
%
Ragged and centered paragraphs
% The following should be specified in vertical mode
% (including \vboxes) after \hsize is set.
% Spacing will not be as fancy as in Knuth's macros, but I will worry
% about it if and when that becomes a problem.
\def\raggedright{\rightglue=0pt plus 0.7\hsize\leftglue=0pt
\parfillglue=0pt }
\def\raggedleft{\leftglue=0pt plus 0.7\hsize\rightglue=0pt
\parfillglue=0pt\parindent=0pt }
\def\centered{\leftglue=0pt plus 0.6\hsize
\rightglue=0pt plus 0.6\hsize
\parfillglue=0pt\parindent=0pt }
%
FONT-INDEPENDENT MATH MACROS
\message{math ...}
%
Math glues, skips, and special boxes:
\thinmuglue=3mu
\medmuglue=4mu plus 2mu minus 4mu
\thickmuglue=5mu plus 5mu
\def\,{\mskip\thinmuglue}
\def\>{\mskip\medmuglue}
\def\;{\mskip\thickmuglue}
\def\!{\mskip-\thinmuglue}
% Turns off \mathsurrond:
\def\m@th{\mathsurround=\z@}
%
Generic alignment macros:
% \ialign is like \halign, preceded by \tabglue=0
\def\ialign{\tabglue\z@glue\halign} % initialized \halign
\def\buildrel#1\over#2{\mathrel{\mathop{#2}\limits^{#1}}}
%
Alternatives:
\def\cases#1{\left\{\,\vcenter{\resetlinesep\m@th
\ialign{$##\hfil$&\quad##\hfil\crcr#1\crcr}}\right.}
%
Matrices:
\def\matrix#1{\,\vcenter{\resetlinesep\m@th
\ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr
\mathstrut\crcr\noalign{\kern-\baselinesep}
#1\crcr\mathstrut\crcr\noalign{\kern-\baselinesep}}}\,}
\def\pmatrix#1{\left(\matrix{#1}\right)}
\newdimen\p@renwd % must set this to width of the big left (
\def\bordermatrix#1{\begingroup \m@th %
\setbox\z@\vbox{ %
\def\cr{\crcr\noalign{\kern2\p@\global\let\cr\endline}}%
\ialign{$##$\hfil\kern2\p@\kern\p@renwd&\thinspace\hfil$##$\hfil
&&\quad\hfil$##$\hfil\crcr%
\omit\strut\hfil\crcr\noalign{\kern-\baselinesep}%
#1\crcr\omit\strut\cr}}%
\setbox\tw@\vbox{\unvcopy\z@\global\setbox\@ne\lastbox}%
\setbox\tw@\hbox{\unhbox\@ne\unskip\global\setbox\@ne\lastbox}%
\setbox\tw@\hbox{$\kern\wd\@ne\kern-\p@renwd\left(\kern-\wd\@ne
\global\setbox\@ne\vbox{\box\@ne\kern2\p@}%
\vcenter{\kern-\ht\@ne\unvbox\z@\kern-\baselinesep}\,\right)$}%
\;\vbox{\kern\ht\@ne\box\tw@}\endgroup}
%
Macros for opening up lines:
\newdimen\jot % Unit of space for use with \openup
% Increases all interline spacings by a given amount:
\def\openup{\afterassignment\@penup\dimen@=}
\def\@penup{\advance\linesep\dimen@
\advance\baselinesep\dimen@
\advance\lineseplimit\dimen@}
% Similar one for use just before \haligns in displays:
\newcount\interdisplaylinepenalty
\interdisplaylinepenalty=100
\def\openalign{\openup\jot\vskip-\jot
\interlinepenalty\interdisplaylinepenalty}
%
Additional inter-line spacing for \halign and co(use after \cr)
% Usage: \halign{ ... \cr\vsk7 ...} for 7 \jots of extra space
\def\vsk#1{\afterassignment\vsk@\count@=}
\def\vsk@{\noalign{\vskip \count@\jot plus\count@\jot}}
%
Equation alignment (\eqalign, \eqaligno, \leqaligno):
% Justification macros for \halign templates:
\newglue\centerglue \centerglue=0pt plus 1000pt minus 1000pt
\def\lft#1{#1\hskip\centerglue} % left-justified entry
\def\ctr#1{\hskip\centerglue #1\hskip\centerglue} % centered entry
\def\rt#1{\hskip\centerglue #1} % right-justified entry
\def\eqalign#1{\,\vcenter{\openup\jot\m@th
\ialign{\strut\hfil$\displaystyle{##}$&$\displaystyle{{}##}$\hfil
\crcr#1\crcr}}\,}
\def\eqalignno#1{\openalign\tabglue\centerglue
\halign to\displaywidth{\hfil$\displaystyle{##}$\tabglue\z@glue
&$\displaystyle{{}##}$\hfil\tabglue\centerglue
&\llap{$##$}\tabglue\z@glue\crcr
#1\crcr}}
\def\leqalignno#1{\openalign\tabglue\centerglue
\halign to\displaywidth{\hfil$\displaystyle{##}$\tabglue\z@glue
&$\displaystyle{{}##}$\hfil\tabglue\centerglue
&\kern-\displaywidth\rlap{$##$}\tabglue\displaywidth\crcr
#1\crcr}}
%
Multiple display lines:
\def\displaylines#1{\openalign
\halign{\hbox to\displaywidth
{$\hfil\displaystyle##\hfil$}\crcr #1\crcr}}
%
Operators in roman font:
\def\log{\mathop{\rm log}\nolimits}
\def\lg{\mathop{\rm lg}\nolimits}
\def\ln{\mathop{\rm ln}\nolimits}
\def\lim{\mathop{\rm lim}}
\def\limsup{\mathop{\rm lim\,sup}}
\def\liminf{\mathop{\rm lim\,inf}}
\def\sin{\mathop{\rm sin}\nolimits}
\def\arcsin{\mathop{\rm arcsin}\nolimits}
\def\sinh{\mathop{\rm sinh}\nolimits}
\def\cos{\mathop{\rm cos}\nolimits}
\def\arccos{\mathop{\rm arccos}\nolimits}
\def\cosh{\mathop{\rm cosh}\nolimits}
\def\tan{\mathop{\rm tan}\nolimits}
\def\arctan{\mathop{\rm arctan}\nolimits}
\def\tanh{\mathop{\rm tanh}\nolimits}
\def\cot{\mathop{\rm cot}\nolimits}
\def\coth{\mathop{\rm coth}\nolimits}
\def\sec{\mathop{\rm sec}\nolimits}
\def\csc{\mathop{\rm csc}\nolimits}
\def\max{\mathop{\rm max}}
\def\min{\mathop{\rm min}}
\def\sup{\mathop{\rm sup}}
\def\inf{\mathop{\rm inf}}
\def\arg{\mathop{\rm arg}\nolimits}
\def\ker{\mathop{\rm ker}\nolimits}
\def\dim{\mathop{\rm dim}\nolimits}
\def\hom{\mathop{\rm hom}\nolimits}
\def\det{\mathop{\rm det}}
\def\exp{\mathop{\rm exp}\nolimits}
\def\Pr{\mathop{\rm Pr}}
\def\gcd{\mathop{\rm gcd}}
\def\bmod{\mskip-\medmuglue\mskip5mu
\mathbin{\rm mod}\penalty900\mskip5mu\mskip-\medmuglue}
\def\pmod#1{\allow\mkern18mu({\rm mod}\,\,#1)}
%
Logical connectives in text roman font
\def\rmiff{\,\mathrel{\rm iff}\,} % "iff" in text font
\def\rmif{\,\mathrel{\rm if}\,} % "if" in text font
\def\rmand{\,\mathrel{\rm and}\,} % "and" in text font
\def\rmor{\,\mathrel{\rm or}\,} % "or" in text font
%
Polymorphic math constructs (\mathpalette):
% To use, let \foo be a two parameter macro, <baz> be any argument.
% Then \mathpalette\foo<baz> is same as \foo\displaystyle{<baz>} in
% displaystyle, \foo\textstyle{<baz>} in \textstyle, etc.
\def\mathpalette#1#2{\mathchoice
{#1\displaystyle{#2}}
{#1\textstyle{#2}}
{#1\scriptstyle{#2}}
{#1\scriptscriptstyle{#2}}}
%
Macros to get/change sizes of formulas
% (\phantom,\vphantom,\hphantom) make empty boxes
% with (dimensions, height&depth, width) of argument
\newif\ifv@ \newif\ifh@
\def\phantom{\v@true\h@true\ph@nt}
\def\vphantom{\v@true\h@false\ph@nt}
\def\hphantom{\v@false\h@true\ph@nt}
\def\ph@nt{\ifmmode\def\next{\mathpalette\mathph@nt}%
\else\let\next\makeph@nt\fi\next}
\def\makeph@nt#1{\setbox\z@\hbox{#1}\finph@nt}
\def\mathph@nt#1#2{\setbox\z@\hbox{$\m@th#1{#2}$}\finph@nt}
\def\finph@nt{\setbox\tw@\null
\ifv@ \ht\tw@\ht\z@ \@dp\tw@\@dp\z@\fi
\ifh@ \wd\tw@\wd\z@\fi \box\tw@}
% Smash reduces height and depth of argument to zero.
\def\smash{\relax % \relax, in case this comes first in \halign
\ifmmode\def\next{\mathpalette\mathsm@sh}
\else\let\next\makesm@sh
\fi\next}
\def\makesm@sh#1{\setbox\z@\hbox{#1}\finsm@sh}
\def\mathsm@sh#1#2{\setbox\z@\hbox{$\m@th#1{#2}$}\finsm@sh}
\def\finsm@sh{\ht\z@\z@ \@dp\z@\z@ \box\z@}
% Mathstrut is a strut for one-line math formulas:
\def\mathstrut{\vphantom(}