%%% ==================================================================== %%% @LaTeX-file{ %%% filename = "amstex.dtx", %%% version = "1.2beta", %%% date = "1994/12/13", %%% time = "11:36:57 EST", %%% author = "American Mathematical Society", %%% copyright = "Copyright (C) 1994 American Mathematical Society, %%% all rights reserved. Copying of this file is %%% authorized only if either: %%% (1) you make absolutely no changes to your copy, %%% including name; OR %%% (2) if you do make changes, you first rename it %%% to some other name.", %%% address = "American Mathematical Society, %%% Technical Support, %%% Electronic Products and Services, %%% P. O. Box 6248, %%% Providence, RI 02940, %%% USA", %%% telephone = "401-455-4080 or (in the USA and Canada) %%% 800-321-4AMS (321-4267)", %%% FAX = "401-331-3842", %%% checksum = "58812 3821 13288 133719", %%% email = "tech-support@math.ams.org (Internet)", %%% codetable = "ISO/ASCII", %%% keywords = "latex, amslatex, ams-latex, math, amstex, ams-tex", %%% supported = "yes", %%% abstract = "This is part of the AMS-\LaTeX{} distribution. It %%% provides a variety of extra mathematical features, %%% largely derived from AMS-\TeX{}.", %%% docstring = "The checksum field above contains a CRC-16 checksum %%% as the first value, followed by the equivalent of %%% the standard UNIX wc (word count) utility output of %%% lines, words, and characters. This is produced by %%% Robert Solovay's checksum utility.", %%% } %%% ==================================================================== % %\iffalse %<*driver> \documentclass{amsdtx} \begin{document} \title{The \pkg{amstex} package} \author{Frank Mittelbach\and Rainer Sch\"opf\and Michael Downes\and David M. Jones} \date{Version \fileversion, \filedate} \hDocInput{amstex.dtx} \end{document} % %\fi % % \maketitle % % \section{Introduction} % % The \pkg{amstex} package is an adaptation of \fn{amstex.tex} for % use as a \latex/ package. For technical and historical notes on the % conversion see \fn{amst-hst.tex}. The work was done in 1988--1989 % by Frank Mittelbach and Rainer Sch\"opf. Some later maintenance % work has been done by Michael Downes. David M. Jones added the % support for the \opt{fleqn} option in 1994. % %^^A% ADD MORE DOCUMENTATION HERE [mjd,2-Sep-1994] % % \StopEventually{} % % Standard file identification: % \begin{macrocode} \ProvidesPackage{amstex}[1994/10/27 v1.2beta AMS extra math features] % \end{macrocode} % % \section{Declare some options} % % The `noamsfonts' option means to avoid declaring math alphabets or % symbol fonts for the extra math fonts in the AMSFonts package. If % these fonts are declared, it means that the corresponding .tfm % files are required even for documents that do not use any symbols % from those fonts. So we allow optionally to not declare them, for % convenience of users who don't have those fonts declared and don't % want to use them. % % But we still load the amsfonts package because it contains some % other needed items, eg mathstrut stuff and \cn{big} stuff. % \begin{macrocode} \DeclareOption{noamsfonts}{% \PassOptionsToPackage{noamsfonts}{amsfonts}} % \end{macrocode} % The `psamsfonts' option, passed on the amsfonts package, means that % alternative \fn{.fd} files should be used that do not refer to % \fn{.tfm} files for sizes 6,8,9 (which are not present in the % PostScript AMS fonts set from Y\&Y/Blue Sky Research). % \begin{macrocode} \DeclareOption{psamsfonts}{% \PassOptionsToPackage{psamsfonts}{amsfonts}} % \end{macrocode} % % Handling of limits on integrals, sums, operatornames. % \begin{macrocode} \DeclareOption{intlimits}{\let\ilimits@\displaylimits} \DeclareOption{nointlimits}{\let\ilimits@\nolimits} \DeclareOption{sumlimits}{\let\slimits@\displaylimits} \DeclareOption{nosumlimits}{\let\slimits@\nolimits} \DeclareOption{namelimits}{\let\nlimits@\displaylimits} \DeclareOption{nonamelimits}{\let\nlimits@\nolimits} % \end{macrocode} % The following two switches might have been defined already by the % documentclass, but it doesn't hurt to re-execute the \cs{newif}'s. % \begin{macrocode} \newif\ifctagsplit@ \newif\iftagsleft@ % \end{macrocode} % % Right or left placement of equation numbers. % \begin{macrocode} \DeclareOption{leqno}{\tagsleft@true} \DeclareOption{reqno}{\tagsleft@false} \DeclareOption{centertags}{\ctagsplit@true} \DeclareOption{tbtags}{\ctagsplit@false} % \end{macrocode} % % DMJ: Flushleft equations. % % DMJ: The left margin of math enviroments is controlled by % \cs{@mathmargin}. This can be set to \cs{@centering} to % implement the default behaviour, i.e., centered equations, and to % something else to implement the flushleft style. % % DMJ: In theory, all that's needed to activate the flushleft mode % in the AMS document classes is something like this: % \begin{verbatim} % \DeclareOption{fleqn}{% % \AtBeginDocument{\@mathmargin30pt}% % } % \end{verbatim} % DMJ: (In fact, unless the document class wants to specify the % \cs{@mathmargin}, it doesn't need to do anything with the fleqn % option.) % \begin{macrocode} \newif\if@fleqn \newskip\@mathmargin \@mathmargin\@centering \DeclareOption{fleqn}{% \@fleqntrue \@mathmargin = -1sp \AtBeginDocument{% \ifdim\@mathmargin= -1sp \@mathmargin\leftmargini \fi }% } % \end{macrocode} % % DMJ: This ensures that \cs{@mathmargin} is given some sort of % sensible default if the class doesn't specify one, while still % allowing a user to override the default value in their document % preamble. (Incidentally, I'm initializing \cs{@mathmargin} to % \cs{leftmargini} for compatibility with \fn{fleqn.clo}, but I'm % not at all convinced that's the right thing to do.) % % DMJ: The next question is what happens when amstex is used with % one of the standard classes. Unfortunately, \LaTeX\ implements % \opt{fleqn} somewhat clumsily; instead of paramaterizing the % definitions of the math structures (as I've attempted to do % here), \fn{fleqn.clo} declares a dimen \cn{mathindent} that is % much like my \cs{@mathmargin} and then redefines \cn\[, \cn\], % \cn{equation}, and \cn{eqnarray}. This means that things could % get rather messy in 2.09 compatibility mode, since \fn{fleqn.clo} % might be loaded after \fn{amstex.sty}, which could cause a real % mess. (This won't be a problem in 2e native mode, since % \fn{amstex}.sty would always be loaded after \fn{fleqn.clo}, so % the only question is whether \fn{amstex.sty} should try to make % sure that \cs{eqnarray} gets indented by the same amount as all % the \AMS\ structures by, for example, saying % \verb+\let\mathindent\@mathmargin+.) I really don't know what to % do in compatibility mode, though. Maybe bind \cn{mathindent} to % \cs{@mathmargin} if it's defined and do something like this if % it's not: % \begin{verbatim} % \@ifundefined{mathindent}% % {\AtBeginDocument{% % \@ifundefined{mathindent}{}% % {warning about loading fleqn.clo after amstex.sty}}% % } % {\let\mathindent\@mathmargin} % \end{verbatim} % This would at least detect when \fn{fleqn.clo} is loaded after % \fn{amstex.sty}. % % % \begin{macrocode} \ExecuteOptions{nointlimits,sumlimits,namelimits} \ProcessOptions % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Call some other packages} % % \begin{macrocode} \RequirePackage{amstext}[1994/09/01] % \text \RequirePackage{amsfonts}[1994/09/01] % \newsymbol, msam, msbm, eufm \RequirePackage{amsbsy}[1994/09/01] % \boldsymbol % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Miscellaneous} % % \begin{macro}{\AmSTeX} % \begin{macro}{\AmS} % The |\AmS| prefix can be used to construct the combination % |\AmS-\LaTeX|. We call cmsy directly in lieu of trying to access it % through the math fonts setup (e.g. |\the\textfont2|) because math % fonts can't be relied on to be properly set up if we are not inside % a math formula. This means that if this command is used in a % document where CM fonts are not wanted, then a font substitution % will need to be declared, e.g.: % \begin{verbatim} % \DeclareFontShape{OMS}{cmsy}{m}{n}{ <-> sub * xxx/m/n }{} % \end{verbatim} % where \verb'xxx' is some alternate font family. % \begin{macrocode} \def\AmSTeX{\protect\AmS-\protect\TeX{}} \def\AmS{{\protect\AmSfont A\kern-.1667em\lower.5ex\hbox{M}\kern-.125emS}} % \end{macrocode} % Taking the first letter of \cs{f@series} will produce |b| or |m| % for the most common values (|b,bx,m|). It may produce nonsense for % more unusual values of \cs{f@series}, so for safety's sake we have % an additional \cs{if} test. We want to avoid setting the series to % |bx| because in a standard \latex/ installation the combination % |cmsy/bx/n| does not have a font definition, and the user % would get a font substitution warning on screen. % \begin{macrocode} \def\AmSfont{% \usefont{OMS}{cmsy}{\if\@xp\@car\f@series\@nil bb\else m\fi}{n}} % \end{macrocode} % \end{macro} % \end{macro} % % We redefine |\prim@s}| and |\pr@m@s| to use |\@let@token| instead % of |\next|. % \begin{macrocode} \def\prim@s{\prime\futurelet\@let@token\pr@m@s} % \def\pr@m@s{% \ifx\@let@token'\DN@##1{\prim@s}\else\let\next@\egroup\fi\next@} % \end{macrocode} % We redefine |\prime| to add a leading null kern so that something % like |^{\mathcal{A}\prime}| will not erroneously cause the skewchar % kern for the letter $\mathcal{A}$ to be inserted. (In the original % \tex/ font layout for \fn{cmsy10} the prime character serves as the % |\skewchar| of the font.) The extra braces allow \verb"^\prime" to % work. (Rule of thumb: the user should be allowed to type a `simple % symbol' superscript without the braces if they wish.) % \begin{macrocode} \let\@prime=\prime \renewcommand{\prime}{{\kern\z@\@prime}} % \end{macrocode} % % Fill in some gaps in the set of spacing commands, and make them % all work equally well in or out of math. Maybe also (or instead?) % users should be told how to use |\mkern| or |\mskip| for any % unusual spacing in math. % % We want all these commands to be robust but declaring them all % with |\DeclareRobustCommand| uses up an control sequence name per % command; to avoid this, we define a common command |\mspace| % which carries the robustness burden for all of them. The standard % |\relax| before the |\ifmmode| is not necessary because of the % |\protect| added by |\DeclareRobustCommand|. % \begin{macrocode} \DeclareRobustCommand{\mspace}[3]{% \ifmmode\mskip#1#2\else\kern#1#3\fi\relax} \renewcommand{\,}{\mspace+\thinmuskip{.1667em}} \let\thinspace\, \renewcommand{\!}{\mspace-\thinmuskip{.1667em}} \let\negthinspace\! \renewcommand{\:}{\mspace+\medmuskip{.2222em}} \let\medspace\: \newcommand{\negmedspace}{\mspace-\medmuskip{.2222em}} \renewcommand{\;}{\mspace+\thickmuskip{.2777em}} \let\thickspace\; \newcommand{\negthickspace}{\mspace-\thickmuskip{.2777em}} % \end{macrocode} % % \begin{macrocode} \def\implies{\DOTSB\;\Longrightarrow\;} \def\impliedby{\DOTSB\;\Longleftarrow\;} % \end{macrocode} % % \begin{macrocode} \begingroup \catcode`\"=12 % in case activated by a preceding package \gdef\And{\DOTSB\;\mathchar"3026 \;} % \end{macrocode} % % Add left/right specific versions of \cn{vert}, \cn{Vert} % \begin{macrocode} \gdef\lvert{\delimiter"426A30C } \gdef\rvert{\delimiter"526A30C } \gdef\lVert{\delimiter"426B30D } \gdef\rVert{\delimiter"526B30D } \endgroup % restore " % \end{macrocode} % % The square-bracket options of \verb+\frac+ and % \verb+\fracwithdelims+ replace the commands \verb+\thickfrac+ and % \verb+\thickfracwithdelims+ of original \amstex/. For convenient % carryover to \cn{dfrac} and \cn{tfrac}, the auxiliary function for % \cn{frac} is called \cn{frfrac} (`fragile frac') rather than the % usual name for an optional-arg function (\cn{\\frac}). % \begin{macrocode} \DeclareRobustCommand{\frac}{\new@ifnextchar[{\frfrac{}}{\frfrac{}[]}} \def\frfrac#1[#2]#3#4{\def\next@{#2}% \ifx\next@\@empty \def\next@{#1{#3\over#4}}% \else \def\next@{#1{#3\above#2\relax#4}}% \fi \next@} % \end{macrocode} % % The [] option for setting the rule width is not % currently available with \cn{dfrac} and \cn{tfrac}, % I don't think that such a thing is needed often enough to justify % the extra overhead. [mjd,1994/10/04] % \begin{macrocode} \def\dfrac{\protect\frfrac\displaystyle[]} \def\tfrac{\protect\frfrac\textstyle[]} % \end{macrocode} % Like \cn{frac}, \cn{binom} calls an auxiliary function \cn{frbinom} % where `fr' stands for `fragile'. % \begin{macrocode} \DeclareRobustCommand{\binom}{\frbinom{}} \def\frbinom#1#2#3{#1{#2\atopwithdelims()#3}} \def\dbinom{\protect\frbinom\displaystyle} \def\tbinom{\protect\frbinom\textstyle} % \end{macrocode} % % |\colon| is for a colon in math that resembles a text colon: small % space on the left, larger space on the right. The |:| character % by itself is treated as a |\mathrel| i.e. large, equal spacing on % both sides. % \begin{macrocode} \def\colon{\nobreak\mskip2mu\mathpunct{}\nonscript \mkern-\thinmuskip{:}\mskip6muplus1mu\relax} % \end{macrocode} % % Default value for sum limits is |\displaylimits|, see option % `nosumlimits'. % % We redefine all the cumulative operator symbols to add a |\DOTSB| % token in their expansion so that |\dots| can choose the proper % alternative if such a symbol follows. % \begin{macrocode} \DeclareMathSymbol{\coprod@}{\mathop}{largesymbols}{"60} \def\coprod{\DOTSB\coprod@\slimits@} \DeclareMathSymbol{\bigvee@}{\mathop}{largesymbols}{"57} \def\bigvee{\DOTSB\bigvee@\slimits@} \DeclareMathSymbol{\bigwedge@}{\mathop}{largesymbols}{"56} \def\bigwedge{\DOTSB\bigwedge@\slimits@} \DeclareMathSymbol{\biguplus@}{\mathop}{largesymbols}{"55} \def\biguplus{\DOTSB\biguplus@\slimits@} \DeclareMathSymbol{\bigcap@}{\mathop}{largesymbols}{"54} \def\bigcap{\DOTSB\bigcap@\slimits@} \DeclareMathSymbol{\bigcup@}{\mathop}{largesymbols}{"53} \def\bigcup{\DOTSB\bigcup@\slimits@} \DeclareMathSymbol{\prod@}{\mathop}{largesymbols}{"51} \def\prod{\DOTSB\prod@\slimits@} \DeclareMathSymbol{\sum@}{\mathop}{largesymbols}{"50} \def\sum{\DOTSB\sum@\slimits@} \DeclareMathSymbol{\bigotimes@}{\mathop}{largesymbols}{"4E} \def\bigotimes{\DOTSB\bigotimes@\slimits@} \DeclareMathSymbol{\bigoplus@}{\mathop}{largesymbols}{"4C} \def\bigoplus{\DOTSB\bigoplus@\slimits@} \DeclareMathSymbol{\bigodot@}{\mathop}{largesymbols}{"4A} \def\bigodot{\DOTSB\bigodot@\slimits@} \DeclareMathSymbol{\bigsqcup@}{\mathop}{largesymbols}{"46} \def\bigsqcup{\DOTSB\bigsqcup@\slimits@} % \end{macrocode} % Triple and quadruple dot accents. % \begin{macrocode} \def\dddot#1{{\mathop{#1}\limits^{\vbox to-1.4\ex@{\kern-\tw@\ex@ \hbox{\normalfont ...}\vss}}}} \def\ddddot#1{{\mathop{#1}\limits^{\vbox to-1.4\ex@{\kern-\tw@\ex@ \hbox{\normalfont....}\vss}}}} % \end{macrocode} % % Change the definition of \verb"~" to automatically remove a % preceding space as well as a following space, if present. % \begin{macrocode} \def~{\nobreakspace} \DeclareRobustCommand{\nobreakspace}{\unskip\nobreak\ \ignorespaces} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Integral signs} % % The straightforward |\ifinner| test to see if the current math % context is non-display, fails if, for instance, we are typesetting % a multiline display within an |\halign|, with the pieces going % into constructions like % \begin{verbatim} % $\displaystyle...$ % \end{verbatim} % So we need a better test to find out if we are `in a display'. We % therefore create |\if@display|. % % \begin{macrocode} \newif\if@display \everydisplay\expandafter{\the\everydisplay \@displaytrue} % \end{macrocode} % % Default value for integral limits is |\nolimits|, see the % definition of the `nointlimits' option. % \begin{macrocode} \def\int{\DOTSI\intop\ilimits@} \def\oint{\DOTSI\ointop\ilimits@} \def\intkern@{\mkern-6mu\mathchoice{\mkern-3mu}{}{}{}} \def\intdots@{\mathchoice{\@cdots}% {{\cdotp}\mkern1.5mu{\cdotp}\mkern1.5mu{\cdotp}}% {{\cdotp}\mkern1mu{\cdotp}\mkern1mu{\cdotp}}% {{\cdotp}\mkern1mu{\cdotp}\mkern1mu{\cdotp}}} \def\iint{\DOTSI\protect\ints@\tw@} \def\iiint{\DOTSI\protect\ints@\thr@@} \def\iiiint{\DOTSI\protect\ints@{4}} \def\idotsint{\DOTSI\protect\ints@\z@} % #1 = multiplicity \def\ints@#1{% \mkern-7mu\mathchoice{\mkern-2mu}{}{}{}% \mathop{\mkern7mu\mathchoice{\mkern2mu}{}{}{}% \intop\ifnum#1=\z@\intdots@ \else\intkern@\fi \ifnum#1>\tw@\intop\intkern@\fi \ifnum#1>\thr@@\intop\intkern@\fi \intop }\ilimits@ } % \end{macrocode} % % The definition of \verb+\nolimits@+ shows a standard \AmSTeX{} % construction. We want to find out what the next token is going % to be, so we use \verb+\futurelet\@let@token\next@+; the % \verb+\@let@token+ is assigned the value of the next token and % then we must define \verb+\next@+ to look at \verb+\@let@token+ % and decide what to do. We could name \verb+\next@+ to be % \verb+\nolimits@@+ or something, but by always using % \verb+\next@+ in similar constructions we cut down on the number % of control sequence names that we use. But this means that % \verb+\nolimits@+ must incorporate the appropriate definition of % \verb+\next@+. Notice that \verb+\next@+ turns around and % redefines itself again; once more this is to save a control % sequence name. % % What \verb+\nolimits@+ does is keep a \verb+\limits+ typed by the % user from having any effect. This is used for operatornames whose % standard usage is never to have limits. % \begin{macrocode} \def\nolimits@{% \DN@{\nolimits\ifx\@let@token\limits\expandafter\@gobble\fi}% \FN@\next@} % \end{macrocode} % % In operator names, it is sometimes desired to have text-mode % punctuation such as |'| |*| |-| |/| |:|. Because the body of an % operator name is set in math mode, these few punctuation % characters will not come out right (wrong symbol/and or wrong % spacing). The purpose of |\newmcodes@| is to make them act like % their normal text versions. % % Where practical, we use decimal numbers to cut down main mem % usage (|"| not needed). % \begin{macrocode} \begingroup \catcode`\"=12 \gdef\newmcodes@{\mathcode`\'39\mathcode`\*42\mathcode`\."613A% \mathcode`\-45\mathcode`\/47\mathcode`\:"603A\relax} \endgroup % \end{macrocode} % % The command |\operatorname| prints its argument as a `math % operator' like |\sin| or |\det|, with proper font and spacing. % \begin{macrocode} \DeclareRobustCommand{\operatorname}{% \@ifstar{\qopname\newmcodes@ n}% {\qopname\newmcodes@{no}}}% \DeclareRobustCommand{\qopname}[3]{\mathop{#1\operator@font#3}% \csname #2limits@\endcsname} \def\arccos{\qopname\relax{no}{arccos}} \def\arcsin{\qopname\relax{no}{arcsin}} \def\arctan{\qopname\relax{no}{arctan}} \def\arg{\qopname\relax{no}{arg}} \def\cos{\qopname\relax{no}{cos}} \def\cosh{\qopname\relax{no}{cosh}} \def\cot{\qopname\relax{no}{cot}} \def\coth{\qopname\relax{no}{coth}} \def\csc{\qopname\relax{no}{csc}} \def\deg{\qopname\relax{no}{deg}} \def\det{\qopname\relax n{det}} \def\dim{\qopname\relax{no}{dim}} \def\exp{\qopname\relax{no}{exp}} \def\gcd{\qopname\relax n{gcd}} \def\hom{\qopname\relax{no}{hom}} \def\inf{\qopname\relax n{inf}} \def\injlim{\qopname\relax n{inj\,lim}} \def\ker{\qopname\relax{no}{ker}} \def\lg{\qopname\relax{no}{lg}} \def\lim{\qopname\relax n{lim}} \def\liminf{\qopname\relax n{lim\,inf}} \def\limsup{\qopname\relax n{lim\,sup}} \def\ln{\qopname\relax{no}{ln}} \def\log{\qopname\relax{no}{log}} \def\max{\qopname\relax n{max}} \def\min{\qopname\relax n{min}} \def\Pr{\qopname\relax n{Pr}} \def\projlim{\qopname\relax n{proj\,lim}} \def\sec{\qopname\relax{no}{sec}} \def\sin{\qopname\relax{no}{sin}} \def\sinh{\qopname\relax{no}{sinh}} \def\sup{\qopname\relax n{sup}} \def\tan{\qopname\relax{no}{tan}} \def\tanh{\qopname\relax{no}{tanh}} % \end{macrocode} % % \begin{macro}{\operator@font} % This command is provided to allow the document styles to decide in % which way math operators like `max' or `log' are typeset. The % default is to set them in \meta{math group} zero of the current % math version. % \begin{macrocode} \def\operator@font{\mathgroup\symoperators} % \end{macrocode} % \end{macro} % % For backwards compatibility we keep this old command name for the % time being: % \begin{macrocode} \def\operatornamewithlimits{\operatorname*} % \end{macrocode} % % These macros use \verb+\mathpalette+s % so that they will change size in script and scriptscript styles, % though it's hard to imagine they will ever be used there (the % arrows, particularly, look bad in subscript sizes). % Notice that the use of \verb+\ex@+ means that the vertical spacing % may not be optimal in script and scriptscript sizes. % Unfortunately \tex/ provides no easy way to do math mode % vertical spacing that varies with current math style like mu % units. % \begin{macrocode} \def\varlim@#1#2{\mathop{\vtop{\ialign{##\crcr \hfil$#1\m@th\operator@font lim$\hfil\crcr \noalign{\nointerlineskip\kern\ex@}#2#1\crcr \noalign{\nointerlineskip\kern-\ex@}\crcr}}}} \def\varinjlim{\mathpalette\varlim@\rightarrowfill@} \def\varprojlim{\mathpalette\varlim@\leftarrowfill@} \def\varliminf{\mathpalette\varliminf@{}} \def\varliminf@#1{\mathop{\@@underline{\vrule\@depth.2\ex@\@width\z@ \hbox{$#1\m@th\operator@font lim$}}}} \def\varlimsup{\mathpalette\varlimsup@{}} \def\varlimsup@#1{\mathop{\@@overline {\hbox{$#1\m@th\operator@font lim$}}}} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \section{Equation numbering} % Provide a convenient way to specify that equations should be % numbered within sections. % \begin{macrocode} \def\numberwithin#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}{% \@ifundefined{c@#2}{\@nocnterr{#2}}{% \@addtoreset{#1}{#2}% \toks@\expandafter\expandafter\expandafter{\csname the#1\endcsname}% \expandafter\xdef\csname the#1\endcsname {\expandafter\noexpand\csname the#2\endcsname .\the\toks@}}}} % \end{macrocode} % % To make references to equation numbers easier, we provide % \cw{eqref}. We almost don't need \cw{textup}, except that % \cw{tagform@} doesn't supply the italic correction. % \begin{macrocode} \def\eqref#1{\textup{\tagform@{\ref{#1}}}} % \end{macrocode} % % The commands |\bmod|, |\pmod|, |\pod|, |\mod| aren't currently % robust. [mjd,5-Sep-1994] % \begin{macrocode} \def\bmod{\mskip-\medmuskip\mkern5mu\mathbin {\operator@font mod}\penalty900 \mkern5mu\mskip-\medmuskip} \def\pod#1{\allowbreak\if@display\mkern18mu\else\mkern8mu\fi(#1)} \def\pmod#1{\pod{{\operator@font mod}\mkern6mu#1}} \def\mod#1{\allowbreak\if@display\mkern18mu \else\mkern12mu\fi{\operator@font mod}\,\,#1} % \end{macrocode} % % Continued fractions. The optional arg l or r controls horizontal % placement of the numerators. % The \verb+\kern-\nulldelimiterspace+ is needed in the definition % if we want the right-hand sides of the fraction rules to line % up. The \verb+\strut+ keeps the numerator of a subsidiary cfrac % from coming too close to the fraction rule above it. % % \begin{macrocode} \newcommand{\cfrac}[3][c]{{\displaystyle\frac{% \strut\ifx r#1\hfill\fi#2\ifx l#1\hfill\fi}{#3}}% \kern-\nulldelimiterspace} % \end{macrocode} % Old command names \cn{lcfrac}, \cn{rcfrac} are retained for the % time being. % \begin{macrocode} \def\lcfrac{\@subst@obsolete\lcfrac{\cfrac[l]}} \def\rcfrac{\@subst@obsolete\rcfrac{\cfrac[r]}} % \end{macrocode} % % |\overset| and |\underset| put symbols above, respectively below, % a symbol that is not a |\mathop| and therefore does not naturally % accept limits. |\binrel@@| uses information collected by % |\binrel@| to make the resulting construction be of type mathrel % or mathbin if the base symbol is either of those types. % \begin{macrocode} \def\overset#1#2{\binrel@{#2}% \binrel@@{\mathop{\kern\z@#2}\limits^{#1}}} % \end{macrocode} % % \begin{macrocode} \def\underset#1#2{\binrel@{#2}% \binrel@@{\mathop{\kern\z@#2}\limits_{#1}}} % \end{macrocode} % % |\sideset| allows placing % `adscript' symbols at the four corners of a |\mathop|, \emph{in % addition to} limits. Left-side adscripts go into arg |#1|, in the % form |_{...}^{...}|, and right-side adscripts go into arg |#2|. % \begin{macrocode} \def\sideset#1#2#3{% \setbox\z@\hbox{$\displaystyle{\vphantom{#3}}#1{#3}\m@th$}% \setbox\tw@\hbox{$\displaystyle{#3}#2\m@th$}% \hskip\wd\z@\hskip-\wd\tw@\mathop{\hskip\wd\tw@\hskip-\wd\z@ {\vphantom{#3}}#1{#3}#2}} % \end{macrocode} % % \begin{macro}{\smash} % We add to the \verb+\smash+ command an optional argument % denoting the part of the formula to be smashed. % \begin{macrocode} \renewcommand{\smash}[2][tb]{% % \end{macrocode} % Here we save the value of the optional argument in \verb+\smash@+ % for later use in \verb+\finsm@sh+. % \begin{macrocode} \def\smash@{#1}% \ifmmode\expandafter\mathpalette\expandafter\mathsm@sh\else \expandafter\makesm@sh\fi{#2}} % \end{macrocode} % When we come to this part of the code \verb+\mathsm@sh+ or % \verb+\makesm@sh+ have stored their argument in box zero. % Depending on the letters stored in \verb+\smash@+ we reset either % the height, depth or both of box zero. % \begin{macrocode} \def\finsm@sh{\def\mb@t{\ht\z@\z@}\def\mb@b{\dp\z@\z@}% \def\mb@tb{\mb@t\mb@b}% {\csname mb@\smash@\endcsname}% \leavevmode\boxz@} % \end{macrocode} % \end{macro} % % The minus sign used in constructing these arrow fills is smashed % so that superscripts above the arrows won't be too high. This % primarily affects the \verb|@>>>| and \verb|@<<<| arrows. % % Only the height of the minus sign box is set to 0 because the % depth is not any greater than the depth of the arrowheads it will % be used with. % \begin{macrocode} \def\rightarrowfill@#1{\m@th\setboxz@h{$#1-$}\ht\z@\z@ $#1\copy\z@\mkern-6mu\cleaders \hbox{$#1\mkern-2mu\box\z@\mkern-2mu$}\hfill \mkern-6mu\mathord\rightarrow$} \def\leftarrowfill@#1{\m@th\setboxz@h{$#1-$}\ht\z@\z@ $#1\mathord\leftarrow\mkern-6mu\cleaders \hbox{$#1\mkern-2mu\copy\z@\mkern-2mu$}\hfill \mkern-6mu\box\z@$} \def\leftrightarrowfill@#1{\m@th\setboxz@h{$#1-$}\ht\z@\z@ $#1\mathord\leftarrow\mkern-6mu\cleaders \hbox{$#1\mkern-2mu\box\z@\mkern-2mu$}\hfill \mkern-6mu\mathord\rightarrow$} % \def\overarrow@#1#2#3{\vbox{\ialign{##\crcr#1#2\crcr \noalign{\kern-\ex@\nointerlineskip}$\m@th\hfil#2#3\hfil$\crcr}}} \def\overrightarrow{\mathpalette{\overarrow@\rightarrowfill@}} \def\overleftarrow{\mathpalette{\overarrow@\leftarrowfill@}} \def\overleftrightarrow{\mathpalette{\overarrow@\leftrightarrowfill@}} % \def\underarrow@#1#2#3{% \vtop{\ialign{##\crcr$\m@th\hfil#2#3\hfil$\crcr \noalign{\nointerlineskip\kern-.5\ex@}#1#2\crcr}}} \def\underrightarrow{\mathpalette{\underarrow@\rightarrowfill@}} \def\underleftarrow{\mathpalette{\underarrow@\leftarrowfill@}} \def\underleftrightarrow{\mathpalette{\underarrow@\leftrightarrowfill@}} % \end{macrocode} % % We can't use \verb|\newif| for \verb|\ifgtest@| because we want % to include \verb|\global| in the definitions of % \verb|\gtest@true| and \verb|\gtest@false|. % \begin{macrocode} \let\ifgtest@\iffalse % initial value \def\gtest@true{\global\let\ifgtest@\iftrue} \def\gtest@false{\global\let\ifgtest@\iffalse} \let\DOTSI\relax \let\DOTSB\relax \let\DOTSX\relax {\uccode`7=`\\ \uccode`8=`m \uccode`9=`a \uccode`0=`t \uccode`!=`h \uppercase{% \gdef\math@#1#2#3#4#5#6\math@{\gtest@false\ifx 7#1\ifx 8#2% \ifx 9#3\ifx 0#4\ifx !#5\xdef\meaning@{#6}\gtest@true \fi\fi\fi\fi\fi}}} {\uccode`7=`c \uccode`8=`h \uccode`9=`\" \uppercase{\gdef\mathch@#1#2#3#4#5#6\mathch@{\gtest@false \ifx 7#1\ifx 8#2\ifx 9#5\gtest@true\xdef\meaning@{9#6}\fi\fi\fi}}} \newcount\classnum@ \def\getmathch@#1.#2\getmathch@{\classnum@#1 \divide\classnum@4096 \ifcase\number\classnum@\or\or\gdef\thedots@{\dotsb@}\or \gdef\thedots@{\dotsb@}\fi} {\uccode`4=`b \uccode`5=`i \uccode`6=`n \uppercase{\gdef\mathbin@#1#2#3{\relaxnext@ \def\nextii@##1\mathbin@{\ifx\@sptoken\@let@token\gtest@true\fi}% \gtest@false\DN@##1\mathbin@{}% \ifx 4#1\ifx 5#2\ifx 6#3\DN@{\FN@\nextii@}\fi\fi\fi\next@}}} {\uccode`4=`r \uccode`5=`e \uccode`6=`l \uppercase{\gdef\mathrel@#1#2#3{\relaxnext@ \def\nextii@##1\mathrel@{\ifx\@sptoken\@let@token\gtest@true\fi}% \gtest@false\DN@##1\mathrel@{}% \ifx 4#1\ifx 5#2\ifx 6#3\DN@{\FN@\nextii@}\fi\fi\fi\next@}}} {\uccode`5=`m \uccode`6=`a \uccode`7=`c \uppercase{\gdef\macro@#1#2#3#4\macro@{\gtest@false \ifx 5#1\ifx 6#2\ifx 7#3\gtest@true \xdef\meaning@{\macro@@#4\macro@@}\fi\fi\fi}}} \def\macro@@#1->#2\macro@@{#2} \newcount\DOTSCASE@ {\uccode`6=`\\ \uccode`7=`D \uccode`8=`O \uccode`9=`T \uccode`0=`S \uppercase{\gdef\DOTS@#1#2#3#4#5{\gtest@false\DN@##1\DOTS@{}% \ifx 6#1\ifx 7#2\ifx 8#3\ifx 9#4\ifx 0#5\let\next@\DOTS@@ \fi\fi\fi\fi\fi \next@}}} {\uccode`3=`B \uccode`4=`I \uccode`5=`X \uppercase{\gdef\DOTS@@#1{\relaxnext@ \def\nextii@##1\DOTS@{\ifx\@sptoken\@let@token\gtest@true\fi}% \DN@{\FN@\nextii@}% \ifx 3#1\global\DOTSCASE@\z@\else \ifx 4#1\global\DOTSCASE@\@ne\else \ifx 5#1\global\DOTSCASE@\tw@\else\DN@##1\DOTS@{}% \fi\fi\fi\next@}}} {\uccode`5=`\\ \uccode`6=`n \uccode`7=`o \uccode`8=`t \uppercase{\gdef\not@#1#2#3#4{\relaxnext@ \def\nextii@##1\not@{\ifx\@sptoken\@let@token\gtest@true\fi}% \gtest@false\DN@##1\not@{}% \ifx 5#1\ifx 6#2\ifx 7#3\ifx 8#4\DN@{\FN@\nextii@}\fi\fi\fi \fi\next@}}} \def\keybin@{\gtest@true \ifx\@let@token+\else\ifx\@let@token=\else\ifx\@let@token<\else\ifx\@let@token>\else \ifx\@let@token-\else \ifx\@let@token*\else\ifx\@let@token:\else\gtest@false\fi\fi\fi\fi\fi\fi\fi} \DeclareRobustCommand{\dots}{\relax \csname\ifmmode m\else t\fi dots@\endcsname} \def\tdots@{\leavevmode\unskip\relaxnext@ \DN@{$\m@th\@ldots\, \ifx\@let@token,\,$\else\ifx\@let@token.\,$\else\ifx\@let@token;\,$\else \ifx\@let@token:\,$\else \ifx\@let@token?\,$\else\ifx\@let@token!\,$\else$ \fi\fi\fi\fi\fi\fi}% \ \FN@\next@} \def\mdots@{\FN@\mdots@@} \def\mdots@@{\gdef\thedots@{\dotso@}% \ifx\@let@token\boldsymbol\gdef\thedots@\boldsymbol{\boldsymboldots@}\else \ifx,\@let@token\gdef\thedots@{\dotsc}% \else\ifx\not\@let@token\gdef\thedots@{\dotsb@}% \else\keybin@ \ifgtest@\gdef\thedots@{\dotsb@}% \else\xdef\meaning@{\meaning\@let@token..........}\xdef\meaning@@{\meaning@}% \expandafter\math@\meaning@\math@ \ifgtest@ \expandafter\mathch@\meaning@\mathch@ \ifgtest@\expandafter\getmathch@\meaning@\getmathch@\fi \else\expandafter\macro@\meaning@@\macro@ \ifgtest@ \expandafter\not@\meaning@\not@\ifgtest@\gdef\thedots@{\dotsb@}% \else\expandafter\DOTS@\meaning@\DOTS@ \ifgtest@ \ifcase\number\DOTSCASE@\gdef\thedots@{\dotsb@}% \or\gdef\thedots@{\dotsi}\else\fi \else\expandafter\math@\meaning@\math@ \ifgtest@\expandafter\mathbin@\meaning@\mathbin@ \ifgtest@\gdef\thedots@{\dotsb@}% \else\expandafter\mathrel@\meaning@\mathrel@ \ifgtest@\gdef\thedots@{\dotsb@}% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \thedots@} % \end{macrocode} % % The \verb|=| character is necessary in the two \verb|\let| assignments % in \verb|\boldsymboldots@|, because the symbol we are making % bold might be an \verb|=| sign. % \begin{macrocode} \def\boldsymboldots@#1{\bold@true\let\@let@token=#1\let\delayed@=#1\mdots@@ \boldsymbol#1\bold@false} % \end{macrocode} % % The definition of |\@cdots| is merely the \fn{plain.tex} % definition of |\cdots|. % \begin{macrocode} \def\@cdots{\mathinner{\cdotp\cdotp\cdotp}} \def\dotsi{\!\@cdots} \let\dotsb@\@cdots % \end{macrocode} % % If any new right delimiters are defined, they would need to be % added to the definition of \verb|\rightdelim@| in order for \verb|\dots| % to work properly in all cases. % \begin{macrocode} \def\rightdelim@{\gtest@true \ifx\@let@token)\else \ifx\@let@token]\else \ifx\@let@token\rbrack\else \ifx\@let@token\}\else \ifx\@let@token\rbrace\else \ifx\@let@token\rangle\else \ifx\@let@token\rceil\else \ifx\@let@token\rfloor\else \ifx\@let@token\rgroup\else \ifx\@let@token\rmoustache\else \ifx\@let@token\right\else \ifx\@let@token\bigr\else \ifx\@let@token\biggr\else \ifx\@let@token\Bigr\else \ifx\@let@token\Biggr\else\gtest@false \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} \def\extra@{% \rightdelim@\ifgtest@ \else\ifx\@let@token$\gtest@true \else\xdef\meaning@{\meaning\@let@token..........}% \expandafter\macro@\meaning@\macro@\ifgtest@ \expandafter\DOTS@\meaning@\DOTS@ \ifgtest@ \ifnum\DOTSCASE@=\tw@\gtest@true\else\gtest@false \fi\fi\fi\fi\fi} \newif\ifbold@ \def\dotso@{\relaxnext@ \ifbold@ \let\@let@token\delayed@ \def\nextii@{\extra@\@ldots\ifgtest@\,\fi}% \else \def\nextii@{\DN@{\extra@\@ldots\ifgtest@\,\fi}\FN@\next@}% \fi \nextii@} % \end{macrocode} % Why not save some tokens? (space vs. time). % \begin{macrocode} \def\extrap@#1{% \DN@{#1\,}% \ifx\@let@token,\else \ifx\@let@token;\else \ifx\@let@token.\else\extra@ \ifgtest@\else \let\next@#1\fi\fi\fi\fi\next@} % \end{macrocode} % % \begin{macrocode} \DeclareRobustCommand{\ldots}{\DN@{\extrap@\@ldots}\FN@\next@} \DeclareRobustCommand{\cdots}{\DN@{\extrap@\@cdots}\FN@\next@} \let\dotso\ldots \let\dotsb\cdots \let\dotsm\dotsb \DeclareRobustCommand{\dotsc}{% \DN@{\ifx\@let@token;\@ldots\,% \else \ifx\@let@token.\@ldots\,% \else \extra@\@ldots \ifgtest@\,\fi \fi\fi}% \FN@\next@} \def\longrightarrow{\DOTSB\relbar\joinrel\rightarrow} \def\Longrightarrow{\DOTSB\Relbar\joinrel\Rightarrow} \def\longleftarrow{\DOTSB\leftarrow\joinrel\relbar} \def\Longleftarrow{\DOTSB\Leftarrow\joinrel\Relbar} \def\longleftrightarrow{\DOTSB\leftarrow\joinrel\rightarrow} \def\Longleftrightarrow{\DOTSB\Leftarrow\joinrel\Rightarrow} \def\mapsto{\DOTSB\mapstochar\rightarrow} \def\longmapsto{\DOTSB\mapstochar\longrightarrow} \def\hookrightarrow{\DOTSB\lhook\joinrel\rightarrow} \def\hookleftarrow{\DOTSB\leftarrow\joinrel\rhook} \def\doteq{\DOTSB\buildrel\textstyle.\over=} \def\iff{\DOTSB\;\Longleftrightarrow\;} % \end{macrocode} % % Remove the `variable' code 7 at the beginning of cap Greek % mathchardefs. These letters should only be made bold via % |\boldsymbol|, for consistency with lowercase Greek. If cap Gamma % does not have the expected definition (\mathchar"7000), skip this % section. % \begin{macrocode} \mathchardef\@tempa=\string"7000 \ifx\@tempa\Gamma \DeclareMathSymbol{\Gamma}{\mathord}{operators}{"00} \DeclareMathSymbol{\Delta}{\mathord}{operators}{"01} \DeclareMathSymbol{\Theta}{\mathord}{operators}{"02} \DeclareMathSymbol{\Lambda}{\mathord}{operators}{"03} \DeclareMathSymbol{\Xi}{\mathord}{operators}{"04} \DeclareMathSymbol{\Pi}{\mathord}{operators}{"05} \DeclareMathSymbol{\Sigma}{\mathord}{operators}{"06} \DeclareMathSymbol{\Upsilon}{\mathord}{operators}{"07} \DeclareMathSymbol{\Phi}{\mathord}{operators}{"08} \DeclareMathSymbol{\Psi}{\mathord}{operators}{"09} \DeclareMathSymbol{\Omega}{\mathord}{operators}{"0A} \DeclareMathSymbol{\varGamma}{\mathord}{letters}{"00} \DeclareMathSymbol{\varDelta}{\mathord}{letters}{"01} \DeclareMathSymbol{\varTheta}{\mathord}{letters}{"02} \DeclareMathSymbol{\varLambda}{\mathord}{letters}{"03} \DeclareMathSymbol{\varXi}{\mathord}{letters}{"04} \DeclareMathSymbol{\varPi}{\mathord}{letters}{"05} \DeclareMathSymbol{\varSigma}{\mathord}{letters}{"06} \DeclareMathSymbol{\varUpsilon}{\mathord}{letters}{"07} \DeclareMathSymbol{\varPhi}{\mathord}{letters}{"08} \DeclareMathSymbol{\varPsi}{\mathord}{letters}{"09} \DeclareMathSymbol{\varOmega}{\mathord}{letters}{"0A} \fi % \end{macrocode} % % We want to change the leading digit of math accents to be % |\accentclass@" so that it can vary according to certain internal % purposes. % \begin{macrocode} \def\accentclass@{7} \def\noaccents@{\def\accentclass@{0}} % \end{macrocode} % % There are a few \meta{math alphabet}s in the standard fonts where we % have to change the extra macros because the standard definitions % don't account for these accent problems. The first is for the % |\mathit| command. % \begin{macrocode} \DeclareFontEncoding{OML}{}{\noaccents@} % \end{macrocode} % The next one corrects the |\cal| alphabet. % \begin{macrocode} \DeclareFontEncoding{OMS}{}{\noaccents@} % \end{macrocode} % % Now let's change the accent commands. % \begin{macrocode} \edef\@tempa#1#2{\def#1{\mathaccent\string"\noexpand\accentclass@#2 }} \@tempa\hat{05E} \@tempa\check{014} \@tempa\tilde{07E} \@tempa\acute{013} \@tempa\grave{012} \@tempa\dot{05F} \@tempa\ddot{07F} \@tempa\breve{015} \@tempa\bar{016} \newcount\skewcharcount@ \newcount\familycount@ \def\theskewchar@{\familycount@\@ne \global\skewcharcount@\the\skewchar\textfont\@ne \ifnum\mathgroup>\m@ne\ifnum\mathgroup<16 \global\familycount@\the\mathgroup\relax \global\skewcharcount@\the\skewchar\textfont\the\mathgroup\relax\fi\fi \ifnum\skewcharcount@>\m@ne \ifnum\skewcharcount@<128 \multiply\familycount@256 \global\advance\skewcharcount@\familycount@ \global\advance\skewcharcount@28672 \mathchar\skewcharcount@\else \global\skewcharcount@\m@ne\fi\else \global\skewcharcount@\m@ne\fi} \newcount\pointcount@ \def\getpoints@#1.#2\getpoints@{\pointcount@#1 } \newdimen\accentdimen@ \newcount\accentmu@ \def\dimentomu@{\multiply\accentdimen@ 100 \expandafter\getpoints@\the\accentdimen@\getpoints@ \multiply\pointcount@18 \divide\pointcount@\@m \global\accentmu@\pointcount@} \def\mathaccent@#1#2{\ifnum\mathgroup=\m@ne\xdef\thefam@{1}\else \xdef\thefam@{\the\mathgroup}\fi \accentdimen@\z@ \setboxz@h{\unbracefonts@$\m@th\mathgroup\thefam@\relax#2$}% \ifdim\accentdimen@=\z@\DN@{\mathaccent#1{#2}}% \setbox\@ne\hbox{\unbracefonts@ $\m@th\mathgroup\thefam@\relax#2\theskewchar@$} \setbox\tw@\hbox{$\m@th\ifnum\skewcharcount@=\m@ne\else \mathchar\skewcharcount@\fi$}% \global\accentdimen@\wd\@ne\global\advance\accentdimen@-\wdz@ \global\advance\accentdimen@-\wd\tw@ \global\multiply\accentdimen@\tw@ \dimentomu@\global\advance\accentmu@\@ne \else\DN@{{\mathaccent#1{#2\mkern\accentmu@ mu}% \mkern-\accentmu@ mu}{}}\fi \next@} % \end{macrocode} % % \begin{macro}{\unbracefonts@} % The |\unbracefonts@| macro is used to % get rid of the braces of a \meta{math alphabet identifier}. % \begin{macrocode} \def\unbracefonts@{\let\math@bgroup\@empty\let\math@egroup\@empty} % \end{macrocode} % \end{macro} % % The commands |\Hat|, |\Tilde|, \ldots, are not made robust % because they are clearly complex commands, not used that often, % and we dont want to use up the extra string pool/csnames that % robustness would require. % \begin{macrocode} \begingroup \catcode`\"=12 \def\@tempa#1#2{\gdef#1{\RIfM@\DN@{\mathaccent@{"\accentclass@#2 }}% \else\DN@{\nonmatherr@{#1}}\fi\next@}} \@tempa\Hat{05E} \@tempa\Check{014} \@tempa\Tilde{07E} \@tempa\Acute{013} \@tempa\Grave{012} \@tempa\Dot{05F} \@tempa\Ddot{07F} \@tempa\Breve{015} \@tempa\Bar{016} \gdef\Vec{\RIfM@\DN@{\mathaccent@{"017E }}\else \DN@{\nonmatherr@\Vec}\fi\next@} \endgroup % \end{macrocode} % % The reason for redefining \verb+\@@sqrt+ (used by \LaTeX{}'s % definition of \verb+\sqrt+) to read an argument is discussed in % Spivak's amstex.doc. As an example, if \verb+\xD+ is defined as % \verb+\not D+ then \verb+\sqrt\xD+ produces this: % $\catcode`\"=12 \def\xD{\not D}\radical"270370 \xD$, with the % slash separated from the $D$. (The same thing happens with % \verb+^\xD+, by the way, but that is not so easy to fix.) This % refinement doesn't gain much if the user is careful and always % puts braces around the argument of \verb+\sqrt+, but it costs % little. MJD % % \begin{macrocode} \begingroup \catcode`\"=12 \gdef\@@sqrt#1{\radical"270370 {#1}} \endgroup % \end{macrocode} % % \verb+\overline@+ replaced by \verb+\@@overline+, to be % consistent with the \LaTeX{} name \verb+\@@underline+. % \verb+\overline+ is redefined for the same reason as % with \verb+\@@sqrt+. % \begin{macrocode} \@saveprimitive\overline\@@overline \def\overline#1{\@@overline{#1}} % \end{macrocode} % % The |\boxed| command is specifically intended to put a box around % an equation or piece of an equation. (Not incl. the equation % number.) This isn't trivial for end-users to do it properly % with |\fbox| so we provide a command for them. % \begin{macrocode} \def\boxed#1{\fbox{\m@th$\displaystyle#1$}} % \end{macrocode} % % \subsection{Preliminary macros} % % \begin{macro}{\setb@ck} % The macro \verb+\setb@ck+ decrements the {\tt equation} counter % by one. To avoid doing this twice in constructs that are % evaluated several times the \verb+firstchoice@+ switch is % checked. % \begin{macrocode} \def\setb@ck{\iffirstchoice@\global\advance\c@equation\m@ne\fi} % \end{macrocode} % \end{macro} % % The following macros implement the \LaTeX{} syntax for the \verb+\\+ % command, i.e. the possibility to add an asterisk to inhibit a page % break, or an optional argument to denote additional vertical space. % They are modelled more or less after the corresponding macros for % \LaTeX's \verb+eqnarray+ and \verb+array+ environments. % % (Internal remark: % we can use the eqnarray mechanism if we change it so that it also uses % the AMS-TeX \verb+\openup+ but this can be done later) % % \begin{macro}{\dspbrk@lvl} % We begin by defining the \verb+\dspbrk@lvl+ counter. This counter % records the desirability of a break after the current row, as a % number between $0$ and $4$. Its default value is $-1$ meaning that % no explicit \verb+\displaybreak+ command was given, and the default % \verb+\interdisplaylinepenalty+ is to be used. % \begin{macrocode} \newcount\dspbrk@lvl \dspbrk@lvl=-1 % \end{macrocode} % \end{macro} % % \begin{macro}{\interdisplaylinepenalty} % We set the \verb+\interdisplaylinepenalty+ to $10000$. % \begin{macrocode} \interdisplaylinepenalty\@M % \end{macrocode} % \end{macro} % % \begin{macro}{\allowdisplaybreaks} % The \verb+\allowdisplaybreaks+ declaration. % \begin{macrocode} \def\allowdisplaybreaks{% \new@ifnextchar[\allowdspbrks@{\allowdspbrks@[4]}} % \end{macrocode} % \end{macro} % % \begin{macro}{\allowdspbrks@} % Here we simply fetch a suitable value for % \verb+\interdisplaylinepenalty+. % \begin{macrocode} \def\allowdspbrks@[#1]{% \interdisplaylinepenalty\getdsp@pen{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\getdsp@pen} % Modelled after \LaTeX's \verb+\@getpen+. We use higher numbers % than would normally be provided by \verb+\@lowpenalty+, % \verb+\@medpenalty+, and \verb+\@highpenalty+, since display % breaks are almost always less desirable. % \begin{macrocode} \def\getdsp@pen#1{% \ifcase #1\relax \@M \or 9999 \or 6999 \or 2999 \or \z@\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\displaybreak} % \begin{macro}{\displaybreak@} % \begin{macro}{\dspbrk@} % For breaks in a certain row of a alignment. % \begin{macrocode} \def\displaybreak{\PackageError{amstex}{\Invalid@@\displaybreak}\@eha} \def\displaybreak@{% \def\displaybreak{\new@ifnextchar[\dspbrk@{\dspbrk@[4]}}} \def\dspbrk@[#1]{\global\dspbrk@lvl #1\relax} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\math@cr} % The macro \verb+\math@cr+ ends a row inside one of the \AmSTeX{} % environments, i.e. this is the internal name of the \verb+\\+ % commands in these environments. As usual for this kind of macro % inside of alignments we insert a special brace into \TeX's input % stream. % \begin{macrocode} \def\math@cr{{\ifnum0=`}\fi % \end{macrocode} % The first step is now to check whether an asterisk follows. % \verb+\@eqpen+ is used to hold the penalty value to be put on % the vertical list. % Then we call up \verb+\math@cr@+ which performs the next step. % If an asterisk is read page breaking is inhibited. % \begin{macrocode} \new@ifstar{\global\@eqpen\@M\math@cr@}% % \end{macrocode} % Otherwise we have to check the \verb+\dspbrk@lvl+ value. % \begin{macrocode} {\global\@eqpen \ifnum\dspbrk@lvl <\z@ \interdisplaylinepenalty \else -\@getpen\dspbrk@lvl \fi \math@cr@}} % \end{macrocode} % \end{macro} % % \begin{macro}{\math@cr@} % The purpose of \verb+\math@cr@+ is to check whether an optional % argument follows. If not it provides \verb+\z@+ as default % value. % \begin{macrocode} \def\math@cr@{\new@ifnextchar[\math@cr@@{\math@cr@@[\z@]}} % \end{macrocode} % \end{macro} % % \begin{macro}{\math@cr@@} % \verb+\math@cr@@+ closes the special brace opened in % \verb+\math@cr+, and calls \verb+\math@cr@@@+ which is supposed % the `real' row ending command. The meaning of this macro depends % on the environment in which it is used. % \begin{macrocode} \def\math@cr@@[#1]{\ifnum0=`{\fi}\math@cr@@@ % \end{macrocode} % Finally we put the additional space onto the vertical list. % \begin{macrocode} \noalign{\vskip#1\relax}} % \end{macrocode} % \end{macro} % % \begin{macro}{\Let@} % \verb+\Let@+ is called by all environments where \verb+\\+ % ends a row of an alignment. % \begin{macrocode} \def\Let@{\let\\\math@cr} % \end{macrocode} % \end{macro} % % \begin{macro}{\restore@math@cr} % We mentioned already that the exact meaning of \verb+\math@cr@@@+ % depends on the current environment. Since it is often a simple % \verb+\cr+ we provide \verb+\restore@math@cr+ to reset it. % \begin{macrocode} \def\restore@math@cr{\def\math@cr@@@{\cr}} % \end{macrocode} % This is also the default case. % \begin{macrocode} \restore@math@cr % \end{macrocode} % \end{macro} % % \begin{macro}{\intertext} % \begin{macro}{\intertext@} % The intertext command is used for inserting text between the % rows of an alignment. It's use is only allowed in special % places. % % Intertext might better be done as an environment, but the % |\begingroup| from |\begin| would cause the |\noalign| to fail. % \begin{macrocode} \def\intertext{\PackageError{amstex}{\Invalid@@\intertext}\@eha} % \end{macrocode} % \verb+\intertext@+ is called by all environments that allow % the use of the \verb+\intertext+ command. % \begin{macrocode} \def\intertext@{\def\intertext##1{\noalign{% \penalty\postdisplaypenalty\vskip\belowdisplayskip \vbox{\normalbaselines\noindent##1}% \penalty\predisplaypenalty\vskip\abovedisplayskip}}} % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{Implementing tags} % % In this section we describe some of the macros needed to make the % \verb+\tag+ command work in various places. We start by defining a % help text to be used when a \verb+\tag+ command is used somewhere % it should not appear. % % \begin{macro}{\tag@help} % This is the default error help text provided when \verb+\tag+ % generates an error message. % Note that \verb+\newhelp+ generates a control sequence name % from the string given as its argument so that a leading % backslash is provided automatically. % \begin{macrocode} \newhelp\tag@help {tag cannot be used at this point.\space If you don't understand why^^Jyou should consult the documentation.^^JBut don't worry: just continue, and I'll forget what happened.} % \end{macrocode} % \end{macro} % % \begin{macro}{\gobble@tag} % This macro is to be used when \verb+\tag+ should silently % skip its argument. % It is made to handle the \verb+*+-form of \verb+\tag+ as well. % \begin{macrocode} \def\gobble@tag{\new@ifstar\@gobble\@gobble} % \end{macrocode} % \end{macro} % % \begin{macro}{\invalid@tag} % \verb+\invalid@tag+ is a macro that should be used whenever % \verb+\tag+ appears in an illegal place. % It sets up \verb+\tag@help+ (as defined above) as help message, % prints its argument as error message, and skips \verb+\tag+'s % argument. % \begin{macrocode} \def\invalid@tag#1{\PackageError{amstex}{#1}{\the\tag@help}\gobble@tag} % \end{macrocode} % \end{macro} % % \begin{macro}{\dft@tag} % \begin{macro}{\default@tag} % \verb+\dft@tag+ provides a convenient way to disallow the % use of \verb+\tag+ at certain points. % One simply has to write % \begin{verbatim} %\let\tag\dft@tag % \end{verbatim} % and the \verb+\tag+ command will produce an error message, % with a suitable error help text, and discard its argument. % \begin{macrocode} \def\dft@tag{\invalid@tag{\string\tag\space not allowed here}} % \end{macrocode} % Since this is used several times we provide an abbreviation for % it. % \begin{macrocode} \def\default@tag{\let\tag\dft@tag} % \end{macrocode} % Since this is also the default, i.e.\ the \verb+\tag+ command % should not be used except in special places, we issue a % \verb+\default@tag+ command. % \begin{macrocode} \default@tag % \end{macrocode} % \end{macro} % \end{macro} % % % Now that we have taken care of the case that \verb+\tag+ is not % allowed we will provide some macros to process tags appropriately. % As the user documentation states, a \verb+\tag+ command (without % the asterisk typesets its argument according to the document % styles' conventions, whereas a \verb+\tag*+ command typesets its % argument exactly as given. We define therefore the following % interface: % % \begin{macro}{\maketag@@} % \begin{macro}{\maketag@@@} % \begin{macro}{\tagform@} % \verb+\tag+ is supposed to call \verb+\maketag@@+ which checks % whether an asterisk follows. If this is the case it calls up % \verb+\maketag@@@+ which sets its argument `as is'. Otherwise % \verb+\tagform@+ is called to do the job. (This macro is to be % defined appropriately by the document style.) % \begin{macrocode} \def\maketag@@{\new@ifstar\maketag@@@\tagform@} % \end{macrocode} % We define \verb+\maketag@@@+ to use the normal font of the % document text (since this is the usual practice for numbering of % document elements) and to put a box around the tag. Furthermore we % use \verb+\m@th+ for exceptional cases where the tag involves a % superscript or some such math. (Probably from an explicit use of % \verb+\tag*+ rather than from the automatic numbering.) % \begin{macrocode} \def\maketag@@@#1{\hbox{\m@th\normalfont#1}} % \end{macrocode} % We use the following default definition for \verb+\tagform@+ % that puts only parentheses around the tag. % \begin{macrocode} \def\tagform@#1{\maketag@@@{(\ignorespaces#1\unskip)}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\thetag} % Sometimes one needs to set a literal tag according to the rules of % the document style. To achieve this we provide the \verb+\thetag+ % command. It typesets its argument by calling \verb+\tagform@+ on % it. % \begin{macrocode} \def\thetag{\leavevmode\tagform@} % \end{macrocode} % \end{macro} % % \begin{macro}{\df@tag} % \begin{macro}{\make@df@tag} % \begin{macro}{\make@df@tag@@} % \begin{macro}{\make@df@tag@@@} % Sometimes it is necessary for a \verb+\tag+ command to store a tag % in a safe place and to process it later, e.g., for a tag in a row % of an alignment where the tag can only be typeset when the % \verb+\\+ at the end of the row was seen. Such a tag is stored in % the macro \verb+\df@tag+ (for `deferred tag'). For this purpose we % provide the \verb+\make@df@tag+ macro. It is built very similar to % the \verb+\maketag@@+ macro above. % \begin{macrocode} \def\make@df@tag{\new@ifstar\make@df@tag@@\make@df@tag@@@} % \end{macrocode} % \verb+\make@df@tag+ sets \verb+\@currentlabel+ and defines % \verb+\df@tag+ appropriately. % \begin{macrocode} \def\make@df@tag@@#1{% \def\@currentlabel{#1}% \gdef\df@tag{\maketag@@@{#1}}} % \end{macrocode} % \verb+\make@df@tag@@@+ does the same if the tag is to be typeset % according to the document style's conventions. % \begin{macrocode} \def\make@df@tag@@@#1{\@seteqlabel{#1}\gdef\df@tag{\tagform@{#1}}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\@seteqlabel} % Abbreviation for a common construction to set the current label to % the current equation number. % \begin{macrocode} \def\@seteqlabel#1{\toks@\@xp{\p@equation{#1}}% \edef\@currentlabel{\the\toks@}} % \end{macrocode} % \end{macro} % % For consistency we provide \verb+\notag+, equivalent to % \verb+\nonumber+. The alternative would have been to rename % \verb+\tag+ as \verb+\number+ to go along with \verb+\nonumber+, % but of course \verb+\number+ is a \TeX{} primitive that should not % be redefined. % \begin{macro} \def\notag{\nonumber} % \end{macro} % % Depending on the setting of the iftagsleft switch, we may need to % redefine \cs{@eqnnum}. % \begin{macrocode} \iftagsleft@ \def\@eqnnum{\hbox to1sp{}\rlap{\normalfont \hskip -\displaywidth\tagform@\theequation}} \fi % \end{macrocode} % \end{macro} % DMJ: TAG ADJUSTMENT % \begin{macro}{\adjusttag} % \begin{macro}{\@adjusttag} % \begin{macro}{\@movetag} % DMJ: Usage: \cn{adjusttag} \meta{dimen} % % DMJ: This will shift the next tag by \meta{dimen} in the vertical % direction in \emph{only} the next \cn{equation}, \cn{gather}, % \cn{align}, or \cn{multline} environment. % (mjd: \cs{@adjusttag} is a % macro rather than a dimen register because those tend to get used up % by add-on packages and there's no way around the upper limit of 256.) % \begin{macrocode} \let\@adjusttag\@empty \def\adjusttag#1{\skip@#1\relax\gdef\@adjusttag{#1}} \def\@movetag{% \ifx\@adjusttag\@empty \else \vskip\@adjusttag\relax \global\let\@adjusttag\@empty \fi } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \subsection{The {\tt Sb} and {\tt Sp} environments} % % The {\tt Sb} and {\tt Sp} environments are used to set subscripts % and superscripts that consists of several lines. % The main task of this is done by the macro \verb+\multilimits@+. % \begin{macro}{\multilimits@} % This macro sets up a horizontal alignment to set the lines. % The first few parts of this macro are worth considering in % detail since they are used in a very similar way in all % math alignment macros. % % The macro starts by opening a group to enclose the whole % subscript or superscript. % \begin{macrocode} \def\multilimits@{\bgroup % \end{macrocode} % Then we use \verb+\Let@+ to set the proper meaning of the % \verb+\\+ and \verb+\\*+ commands. % \begin{macrocode} \Let@ % \end{macrocode} % Now we restore the meaning of \verb+\math@cr@@@+ to \verb+\cr+ % (see above) as this may be used in one of the more complicated % alignment macros where the meaning of \verb+\math@cr@@@+ is % different. % \begin{macrocode} \restore@math@cr % \end{macrocode} % Then we call \verb+\default@tag+ since tags are not allowed % inside a {\tt Sb} or {\tt Sp} environment. % \begin{macrocode} \default@tag % \end{macrocode} % The rest of the \verb+\multilimits+ macro is rather % straightforward code to get the correct line spacing\ldots % \begin{macrocode} \baselineskip\fontdimen10 \scriptfont\tw@ \advance\baselineskip\fontdimen12 \scriptfont\tw@ \lineskip\thr@@\fontdimen8 \scriptfont\thr@@ \lineskiplimit\lineskip % \end{macrocode} % \ldots followed by a box containing the actual alignment. % \begin{macrocode} \vbox\bgroup\ialign\bgroup\hfil$\m@th\scriptstyle{##}$\hfil\crcr} % \end{macrocode} % \end{macro} % % \begin{macro}{\Sb} % \begin{macro}{\Sp} % \begin{macro}{\endSb} % \begin{macro}{\endSp} % The definitions of \verb+\Sb+ and \verb+\Sp+ are then easy: % \begin{macrocode} \def\Sb{_\multilimits@} \def\Sp{^\multilimits@} % \end{macrocode} % The environments end with a number of group closing braces. % \begin{macrocode} \def\endSb{\crcr\egroup\egroup\egroup} \let\endSp=\endSb % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \subsection{Matrices} % % \begin{macro}{\smallmatrix} % \begin{macro}{\endsmallmatrix} % \verb+\smallmatrix+ is again an alignment, this time in a % centered box. The opening incantations are basically the same as % those in \verb+\multilimits@+, followed by the alignment itself. % A remark: the baselineskip (\verb+9\ex@+) used in \AmSTeX{} is % too large for use in text with the usual baselineskip of $12$ or % $13$ points; we change it here to \verb+6\ex@+ and also adjust % the \verb+\lineskip+ and \verb+\lineskiplimit+ slightly to % compensate. (MJD) % \begin{macrocode} \def\smallmatrix{\null\,\vcenter\bgroup \Let@\restore@math@cr\default@tag \baselineskip6\ex@ \lineskip1.5\ex@ \lineskiplimit\lineskip \ialign\bgroup\hfil$\m@th\scriptstyle{##}$\hfil&&\thickspace\hfil $\m@th\scriptstyle{##}$\hfil\crcr} % \end{macrocode} % The corresponding \verb+\endsmallmatrix+ macro has only to % finish the alignment and to close the groups. % \begin{macrocode} \def\endsmallmatrix{\crcr\egroup\egroup\,} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\matrix} % \begin{macro}{\endmatrix} % \begin{macro}{\c@MaxMatrixCols} % For the matrix environment we provide only a very simple % macro: an {\tt array} environment with a predefined number of % centered columns. % This number is defined by the counter {\tt MaxMatrixCols} whose % default value is $10$. % \begin{macrocode} \newcount\c@MaxMatrixCols \c@MaxMatrixCols=10 \def\matrix{\hskip -\arraycolsep\array{*\c@MaxMatrixCols c}} \def\endmatrix{\endarray \hskip -\arraycolsep} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\@array} % \LaTeX's \verb+\@array+ macro has a bug: it uses \verb+\halign+ % instead of \verb+\ialign+ which initializes the \verb+\tabskip+ % glue to zero. We define a corrected version here. % % But this should only be done when the original \LaTeX{} {\tt % array} environment is used, not when Frank's version was loaded. % This is tested by checking the macro \verb+\prepnext@tok+. % \begin{macrocode} \@ifundefined{prepnext@tok}{% \def\@array[#1]#2{% \setbox\@arstrutbox\hbox{\vrule\@height\arraystretch\ht\strutbox \@depth\arraystretch\dp\strutbox \@width\z@}% \@mkpream{#2}\edef\@preamble{\ialign \noexpand\@halignto \bgroup \tabskip\z@ \@arstrut \@preamble \tabskip\z@ \cr}% \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi % \end{macrocode} % \verb+\par+ set to \verb+\@empty+ to allow blank lines % in array entries. % \begin{macrocode} \bgroup \let\par\@empty \let\@sharp##\let\protect\relax \lineskip\z@\baselineskip\z@\@preamble}% % \end{macrocode} % \end{macro} % % \begin{macro}{\@xexpast} % We also need to substitute nonactive \verb|@| characters for % active ones in a preamble specification for \verb|{array}| or % \verb|{tabular}| or \verb|{multicolumn}|. We do this by defining % active \verb|@| to be (letter) \verb|@| temporarily, while some % \verb|\edef|'s are taking place. All \verb|@| characters % anywhere in the preamble will be expanded, so % \verb|@| characters that are not the beginning of % a column-specifier \verb|@|-expression will be improperly % expanded and cause an error message; however, this possibility % is unlikely enough that we will just ignore it. (And I suppose % that a \verb|\protect| before the \verb|@| might actually work.) % % While defining \verb|\@xexpast|, we use a standard \verb|\lccode| % trick to obtain an active \verb|@| character in the midst of % normal \LaTeX{} code with nonactive \verb|@| characters. % % One more stratagem that we use here is enclosing the main action % of \verb|\@xexpast| in a group so that we don't have to worry % about restoring the proper definition of active \verb|@| % afterwards; this entails the use of a special trick to throw the % definition of \verb|\@tempa| beyond the \verb|\endgroup|, to % avoid defining it globally. % \begin{macrocode} \begingroup \lccode`\~=`\@ \catcode`\~=\active % just to be sure! \lowercase{% \gdef\@xexpast#1*#2#3#4\@@{\begingroup \def~{@}\edef\reserved@a{#1}\@tempcnta#2\relax \ifnum\@tempcnta >\z@ \@whilenum\@tempcnta >\z@\do {\edef\reserved@a{\reserved@a#3}\advance\@tempcnta \m@ne}% \let\reserved@b\@xexpast \else \let\reserved@b\@xexnoop\fi \expandafter\reserved@b \reserved@a #4\@@ % \end{macrocode} % We want to expand the second \verb|\reserved@a| before we leave the % current group: % \begin{macrocode} \expandafter\endgroup \expandafter\def\expandafter\reserved@a\expandafter{\reserved@a}% % \end{macrocode} % For compatibility with the June 1994 version of \latex/ we need to % supply both \cs{reserved@a} and \cs{@tempa} to the parent function % \cs{@mkpream}. % \begin{macrocode} \let\@tempa\reserved@a }% End of \@xexpast }% End of \lowercase % \end{macrocode} % End the group where \verb|~| has lccode equal to \verb|@|. % \begin{macrocode} \endgroup % \end{macrocode} % \end{macro} % % \begin{macrocode} }{}% End of \@ifundefined test. % \end{macrocode} % % |\matrix| is defined in terms of |\array|. % \begin{macrocode} \def\pmatrix{\left(\matrix} \def\endpmatrix{\endmatrix\right)} \def\bmatrix{\left[\matrix} \def\endbmatrix{\endmatrix\right]} \def\vmatrix{\left|\matrix} \def\endvmatrix{\endmatrix\right|} \def\Vmatrix{\left\|\matrix} \def\endVmatrix{\endmatrix\right\|} % \end{macrocode} % % \begin{macrocode} \let\hdots\@ldots % \end{macrocode} % % \begin{macrocode} \def\hdotsfor#1{\if\noexpand#1[\expandafter\shdots@for\else \hdots@for\@ne{#1}\fi} \newmuskip\dotsspace@ \def\shdots@for#1]{\hdots@for{#1}} \def\hdots@for#1#2{\multicolumn{#2}c% {\m@th\dotsspace@1.5mu\mkern-#1\dotsspace@ \xleaders\hbox{$\m@th\mkern#1\dotsspace@.\mkern#1\dotsspace@$}% \hfill \mkern-#1\dotsspace@}% } % \end{macrocode} % % \begin{macro}{\cases} % \begin{macro}{\endcases} % The \verb+cases+ environment is easily implemented in terms % of \LaTeX's {\tt array} environment. % \begin{macrocode} \def\cases{\left\{\def\arraystretch{1.2}\hskip-\arraycolsep \array{l@{\quad}l}} \def\endcases{\endarray\hskip-\arraycolsep\right.} % \end{macrocode} % \end{macro} % \end{macro} % % % \subsection{Math alignment environments} % % \subsubsection{Preliminaries} % % \begin{macro}{\ifinany@} % \begin{macro}{\ifinalign@} % \begin{macro}{\ifingather@} % We define three switches that are set to true in certain % alignments: \verb+inalign@+ and \verb+ingather@+ inside of % the {\tt align} and {\tt gather} environments, respectively, % and \verb+inany@+ that is set true in any of these % environments. % These switches are needed to control certain actions that % depend on the surrounding conditions, more specifically: % on the setting already done by the surrounding environments. % \begin{macrocode} \newif\ifinany@ \newif\ifinalign@ \newif\ifingather@ % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\and@} % The counter \verb+\and@+ is used by the alignment macros to % keep track of the current column. % \begin{macrocode} \newcount\and@ % \end{macrocode} % \end{macro} % % \begin{macro}{\iftag@} % The switch \verb+tag@+ is set to false at the beginning of every % row and set to true by a \verb+\tag+ command. % This allows us to check whether there is more than one tag on % a row. % \begin{macrocode} \newif\iftag@ % \end{macrocode} % \end{macro} % % \begin{macro}{\andhelp@} % The help text stored in \verb+\andhelp@+ is used for errors % generated by too many \verb+&+ characters in a row. % \begin{macrocode} \newhelp\andhelp@ {An extra & here is so disastrous that you should probably exit^^J and fix things up.} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifst@rred} % The switch \verb+st@rred+ is set to true by all starred % environments % and set to false by the unstarred versions. % \begin{macrocode} \newif\ifst@rred % \end{macrocode} % \end{macro} % % % \subsubsection{Scanning the environments' body} % % Several of the math alignment macros must scan their body twice: % once to determine how wide the columns are and then to actually % typeset them. % This means that we must collect all text in this body before % calling the environment macros. % % \begin{macro}{\@envbody} % We start by defining a token register to contain the body. % \begin{macrocode} \newtoks\@envbody % \end{macrocode} % \end{macro} % % \begin{macro}{\addto@envbody} % Then we define a macro to add something (i.e.\ its argument) % to the token register \verb+\@envbody+. % \begin{macrocode} \def\addto@envbody#1{\@envbody\expandafter{\the\@envbody#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\collect@body} % The macro \verb+\collect@body+ starts the scan for the % \verb+\end{+\ldots\verb+}+ command of the current environment. % It takes a macro name as argument. This macro is supposed % to take the whole body of the environment as its argument. % For example, \verb+\begin{align}+ would call % \verb+\collect@body\@align+ if \verb+\@align#1{+\ldots\verb+}+ % is the macro that sets the alignment with body \verb+#1+. % % \verb+\collect@body+ first initializes the token register % \verb+\@envbody+. % \begin{macrocode} \def\collect@body#1{% \@envbody{}% % \end{macrocode} % Then it defines the macro \verb+\process@envbody+ which is % called when the \verb+\end+ command was successfully scanned. % It will insert the scanned text as argument to the macro that % is the argument to \verb+\collect@body+. % \begin{macrocode} \def\process@envbody{% \expandafter#1\expandafter{\the\@envbody}}% % \end{macrocode} % Finally it calls \verb+\collect@@body+ to perform the scan. % But we use a renaming trick described below. % \begin{macrocode} \expandafter\let\csname\@currenvir\endcsname\collect@@body \csname\@currenvir\endcsname} % \end{macrocode} % \end{macro} % % \begin{macro}{\collect@@body} % \verb+\collect@@body+ takes two arguments: the first will consist % of all text up to the next \verb+\end+ command, the second will % be the \verb+\end+ command's argument. Note the underlying % assumption: an environment that uses \verb=\collect@@body= cannot % have another environment of the same name nested within it. This % assumption is true for the major display alignment macros of the % {\tt amstex} option. % \begin{macrocode} \def\collect@@body#1\end#2{% % \end{macrocode} % This argument is then compared to the name of the current % environment. % \begin{macrocode} \def\@tempa{#2}% \ifx\@tempa\@currenvir % \end{macrocode} % If this is the matching \verb+\end+ the rest of the environment's % body is collected and the macro \verb+\xxxxx+ (where `xxxxx' is % the name of the current environment) is redefined to process the % environment's body using the \verb+\process@envbody+ macro % defined in \verb+\collect@body+. Redefining \verb=\xxxxx= in % this way is possible first because we are in a group (from % \verb=\begin=\dots\verb=\end=) and second because the % environments that call \verb=\collect@@body= cannot be nested, as % mentioned above. And the reason we want to redefine % \verb=\xxxxx= is so that the user will get a more understandable % error message if they have a mismatched or misspelled end of the % environment, for example something like % \begin{verbatim} % \begin{multline*} % ... % \end{multline} % \end{verbatim} % In an earlier implementation the scratch macro \verb=\next= was % used instead of \verb=\xxxxx=, and the resulting error message % was % \begin{verbatim} % ! Paragraph ended before \next was complete. % \end{verbatim} % Now the error message is % \begin{verbatim} % ! Paragraph ended before \multline* was complete. % \end{verbatim} % % \begin{macrocode} \addto@envbody{#1}% \expandafter\edef\csname\@currenvir\endcsname {\noexpand\process@envbody\noexpand\end{\@tempa}}% % \end{macrocode} % Otherwise the text just read is collected in our token register. % \begin{macrocode} \else \addto@envbody{#1\end{#2}}% \fi % \end{macrocode} % The only thing that remains to be done is to call up % \verb+\+. % \begin{macrocode} \csname\@currenvir\endcsname} % \end{macrocode} % \end{macro} % % % \subsubsection{Simple aligning environments} % % \begin{macro}{\aligned} % \begin{macro}{\aligned@} % \begin{macro}{\endaligned} % The {\tt aligned} environment first checks if an optional % argument follows and calls up \verb+\aligned@+ to do the % work. % \begin{macrocode} \def\aligned{\RIfM@\else\nonmatherr@{\begin{aligned}}\fi \null\,\new@ifnextchar[{\aligned@}{\aligned@[c]}} % \end{macrocode} % \verb+\aligned@+ is taken nearly unchanged from {\tt amstex.tex}. % Depending on its position argument it selects the appropriate % type of box. % \begin{macrocode} \def\aligned@[#1]{% \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi \bgroup % \end{macrocode} % Then it does a number of initializations. % \begin{macrocode} \Let@\restore@math@cr % \end{macrocode} % One of these is the restoration of the default definition % of the \verb+\tag+ macro, in case that the {\tt aligned} % environment is used inside, e.g., an {\tt gather} % environment. % \begin{macrocode} \default@tag % \end{macrocode} % Another is to increase the vertical space between rows a bit % if used inside of another aligning environment. % \begin{macrocode} \ifinany@\else\openup\jot\fi % \end{macrocode} % Finally it starts the alignment itself. % \begin{macrocode} \ialign\bgroup\hfil\strut@$\m@th\displaystyle{##}$&% $\m@th\displaystyle{{}##}$\hfil\crcr} % \end{macrocode} % The \verb+\endalign+ macro ends the alignment and the enclosing % vertical box. % \begin{macrocode} \def\endaligned{\crcr\egroup\egroup} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % |\hashtoks@| is used to conceal |#| from \tex/'s scanner at % certain inconvenient moments in the construction of some display % alignments. % % Maybe this could be replaced with the \verb+\sharp+ mechanism % from \LaTeX? [mjd,5-Sep-1994] % \begin{macrocode} \newtoks\hashtoks@ \hashtoks@{#} % \end{macrocode} % % \begin{macro}{\atcount@} % For the {\tt alignat} and {\tt alignedat} environment we need % an additional counter to keep track of the columns. % \begin{macrocode} \newcount\atcount@ % \end{macrocode} % \end{macro} % % \begin{macro}{\doat@} % The macro \verb+doat@+ takes as positive number as argument % and generates a preamble for an alignment with twice as much % columns, alternately being flushright and flushleft. % This preamble is stored in the macro \verb+\preamble@@+. % \begin{macrocode} \def\doat@#1{\toks@{\hfil\strut@$\m@th \displaystyle{\the\hashtoks@}$&$\m@th\displaystyle {{}\the\hashtoks@}$\hfil}% \atcount@#1\relax\advance\atcount@\m@ne \loop\ifnum\atcount@>\z@\toks@\expandafter{\the\toks@&\hfil$\m@th \displaystyle{\the\hashtoks@}$&$\m@th \displaystyle{{}\the\hashtoks@}$\hfil}\advance \atcount@\m@ne\repeat \xdef\preamble@{\the\toks@}\xdef\preamble@@{\preamble@}} % \end{macrocode} % \end{macro} % % \begin{macro}{\alignedat} % \begin{macro}{\endalignedat} % The definition of \verb+\alignat+ is rather straightforward. % Not the use of the \verb+\span+ primitive to expand % \verb+\preamble@@+. % \begin{macrocode} \def\alignedat#1{\null\,\vcenter\bgroup\doat@{#1}\Let@ \restore@math@cr\default@tag \ifinany@\else\openup\jot\fi\ialign\bgroup\span\preamble@@\crcr} % \end{macrocode} % \verb+\endalignedat+ has exactly the same task as % \verb+\endaligned+. % \begin{macrocode} \let\endalignedat =\endaligned % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\gathered} % \begin{macro}{\endgathered} % Again, \verb+\gather+ and \verb+\endgather+ do not present % any new mysteries. % \begin{macrocode} \def\gathered{\RIfM@\else\nonmatherr@{\begin{gathered}}\fi \null\,\vcenter\bgroup\Let@\restore@math@cr \ifinany@\else\openup\jot\fi\ialign \bgroup\hfil\strut@$\m@th\displaystyle{##}$\hfil\crcr} \let\endgathered =\endaligned % \end{macrocode} % \end{macro} % \end{macro} % % % \subsubsection{The {\tt align} environment} % % We start by discussing the special versions of \verb+\tag+ and % \verb+\math@cr@@@+ to be used within the {\tt align} environments. % \begin{macro}{\tag@in@align} % The \verb+\tag+ command may only appear once in a row of % an alignment. Therefore we first check the switch \verb+tag@+ % that is set to false at the begin of every row. % If this switch is true a \verb+\tag+ was already given in this % row and we define \verb+\next@+ to expand to a call to % \verb+\invalid@tag+. % \begin{macrocode} \def\tag@in@align{\relax \iftag@\DN@{\invalid@tag{Multiple \string\tag}}\else % \end{macrocode} % Otherwise we set the \verb+tag@+ switch. But there is more to % be done: we must also prevent the automatic generation of a % tag. Therefore we also reset the \verb+@eqnsw+. % \begin{macrocode} \global\tag@true \if@eqnsw\global\@eqnswfalse\fi % \end{macrocode} % Within a row of an {\tt align} environment the \verb+\tag+ % command must not typeset the tag immediately since its % position can be determined only later. % Therefore we use the \verb+\make@df@tag+ macro defined % earlier. % Finally we call up \verb+\next@+ to process the argument % that follows. % \begin{macrocode} \let\next@\make@df@tag\fi \next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\math@cr@@@align} % To understand this macro you have to know how an {\tt align} % environment is typeset: it has three columns, the first two % used for the alignment itself, the last for the tag if there is % one. If not all columns are used \verb+\math@cr@@@align+ has % to insert a suitable number of \verb+&+ tokens to put the tag % into the third column. % This is necessary if either the \verb+@eqnsw+ or the \verb+tag@+ % switch are set. To avoid a number of checks we also set the % \verb+tag@+ switch when the \verb+@eqnsw+ switch is set. % \begin{macrocode} \def\math@cr@@@align{% \if@eqnsw\global\tag@true\fi % \end{macrocode} % This allows us to check only the \verb+tag@+ switch. % \begin{macrocode} \iftag@ % \end{macrocode} % The \verb+\and@+ counter is set to zero at the beginning of every % row and incremented by one for every column. This keeps track % of the number of \verb+&+ tokens already encountered. % Depending of this value we define \verb+\next@+ to expand to % the missing \verb+&+ tokens and call it. % \begin{macrocode} \ifcase\and@ \DN@{&&}\else \DN@{&}\fi\else \let\next@\relax\fi \next@ % \end{macrocode} % Now we are ready to typeset the tag. We have to check to % \verb+@eqnsw+ once again, to find out if the tag was specified % in a \verb+\tag+ command or is to be generated automatically % using the {\tt equation} counter. % In the former case we use the tag recorded in the \verb+\df@tag+ % macro, in the latter we also step the {\tt equation} counter. % But before we insert a \verb+\relax+ to prevent \TeX{} from % scanning too far after a \verb+&+ token. % \begin{macrocode} \relax \if@eqnsw\tagform@\theequation\stepcounter{equation}\else \iftag@\df@tag\fi\fi \global\@eqnswtrue\cr} % \end{macrocode} % \end{macro} % % \begin{macro}{\Tag@} % This macro helps to keep things straight if the user typed more % than one \verb+&+. It will be called in the third column of the % alignment. Since this column is only used for the tag it is an % error to use it otherwise. % % \verb|\Tag@| sets \verb|\iffirstchoice@| to true because this % test is used by error messages. Normally \verb|\iffirstchoice@| is % false inside of \verb|\measure@| because we don't want counters % to be stepped, etc.\ while we are measuring; but the \verb|\Tag@| % error message is intended precisely for the measuring case, only. % \begin{macrocode} \def\Tag@{\relax\iftag@\else\firstchoice@true \PackageError{amstex}{% Extra & on this line% }{\the\andhelp@% "An extra & here is disastrous" }\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\lwidth@} % \begin{macro}{\rwidth@} % \begin{macro}{\maxlwidth@} % \begin{macro}{\maxrwidth@} % \begin{macro}{\totwidth@} % \begin{macrocode} \newdimen\lwidth@ \newdimen\rwidth@ \newdimen\maxlwidth@ \newdimen\maxrwidth@ \newdimen\totwidth@ % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\measure@} % \verb+\measure@+ is one of the most important macros of % the code that implements the {\tt align} environment. % It processes the whole alignment, only to determine the widths % of the columns. For this purpose it uses the following % \meta{dimen} registers: \verb+\lwidth@+ and \verb+\rwidth@+ % for the width of the left and right columns of the current % row, \verb+\maxlwidth@+ and \verb+\maxrwidth@+ for the maximum % of the widths in the columns processed so far. % To keep track of the current column it uses the \verb+\and@+ % counter. % \begin{macrocode} \def\measure@#1{\lwidth@\z@\rwidth@\z@\maxlwidth@\z@\maxrwidth@\z@ \global\and@\z@ % \end{macrocode} % The alignment is gathered in a \meta{box} register that will % be thrown away afterwards. % \begin{macrocode} \setbox\@ne\vbox{% % \end{macrocode} % We start with some initializations: % \verb+\everycr+ is set so that the {\tt tag} switch is reset % and the \verb+\and@+ counter set to zero at the beginning % of every column. \verb+\Let@+ is called to define \verb+\\+, % and the \verb+\tag+ macro is defined to gobble its argument. % Finally the \verb+firstchoice@+ switch is reset to prevent % the stepping of counters, processing of labels, etc. % \begin{macrocode} \everycr{\noalign{\global\tag@false\global\and@\z@}}\Let@ \let\tag\gobble@tag % \end{macrocode} % % We also change \verb|\notag| and \verb|\nonumber| while % measuring, because their change of the global switch % \verb|\if@eqnsw| could have side effects (and did, in version % 1.0, if \verb|\notag| was used on the last line of an {\tt align} % environment). % \begin{macrocode} \let\notag\@empty \let\nonumber\@empty \firstchoice@false % \end{macrocode} % Now we are ready to do the alignment. % The preamble looks complicated, but is rather straightforward: % the material in an entry is gathered in \verb+\box+ register % $1$ the width of which is then measured. The values of % the corresponding \verb+\dimen+ registers are then updated. % Finally the \verb+\and@+ counter is increased by one. % \begin{macrocode} \halign{\setboxz@h{$\m@th\displaystyle{\@lign##}$}% \global\lwidth@\wdz@ \ifdim\lwidth@>\maxlwidth@\global\maxlwidth@\lwidth@\fi \global\advance\and@\@ne &\setboxz@h{$\m@th\displaystyle{{}\@lign##}$}% \global\rwidth@\wdz@ \ifdim\rwidth@>\maxrwidth@\global\maxrwidth@\rwidth@\fi \global\advance\and@\@ne % \end{macrocode} % In the third column the \verb+\Tag@+ macro is called to produce % an error message if the user tries to put more than one \verb+&+ % in a row (or forgets the \verb|\\| command at the end of a row). % The material in this column is simply thrown away. % \begin{macrocode} &\Tag@\@gobble{##}\crcr#1\crcr}}% % \end{macrocode} % Finally we set \verb+\totwidth@+ to the sum of \verb+\maxlwidth@+ % and \verb+\maxrwidth@+. % This will be used later to determine the vertical position of % the tags. % \begin{macrocode} \totwidth@\maxlwidth@\advance\totwidth@\maxrwidth@} % \end{macrocode} % \end{macro} % % \begin{macro}{\displ@y} % \begin{macro}{\displ@y@} % The macro \verb+\displ@y+ was copied from the {\tt plain.tex} % file, and then \verb+\interdisplaylinepenalty+ was changed to % \verb+\@eqpen+. % \begin{macrocode} \def\displ@y{\global\dt@ptrue\openup\jot\m@th \everycr{\noalign{\ifdt@p \global\dt@pfalse \vskip-\lineskiplimit \vskip\normallineskiplimit \else \penalty\@eqpen \fi}}} % \end{macrocode} % \verb+\displ@y@+ is nearly the same; it additionally % sets the \verb+tag@+ switch and the \verb+\and@+ and % \verb+\dspbrk@lvl+ counters to their default values. % \begin{macrocode} \def\displ@y@{\global\dt@ptrue\openup\jot \everycr{\noalign{\global\tag@false \global\and@\z@ \global\dspbrk@lvl\m@ne \ifdt@p\global\dt@pfalse \vskip-\lineskiplimit\vskip\normallineskiplimit\else \penalty\@eqpen\fi}}} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\black@} % This macro is made to produce an overfull box message and % possibly (depending on the value of \verb+\overfullrule+) % a rule in the margin if the total width of an alignment % is larger than the value of \verb+\displaywidth+. % \begin{macrocode} \def\black@#1{\noalign{\ifdim#1>\displaywidth \dimen@\prevdepth\nointerlineskip \vskip-\ht\strutbox@\vskip-\dp\strutbox@ \vbox{\noindent\hbox to#1{\strut@\hfill}}% \prevdepth\dimen@ \fi}} % \end{macrocode} % \end{macro} % % \begin{macro}{\align} % The {\tt align} environment may appear at two different places: % inside of a {\tt gather} environment or in outer paragraph mode. % These two cases may be distinguished easily by checking the % \verb+ingather@+ switch. % \begin{macrocode} \def\align{\ifingather@ % \end{macrocode} % The version of \verb+\align+ to be used % inside {\tt gather} is called \verb+\align (in \gather)+. % We define \verb+\next@+ to call this macro. % But before we have to insert a special brace to hide the % \verb+&+ in the body of the align environment from \TeX{}'s % scanning mechanism. % \begin{macrocode} {\ifnum0=`}\fi \DN@{\@nameuse{align (in \string\gather)}}% % \end{macrocode} % Otherwise we proceed by first checking if we are in the right % mode. If not we define \verb+\next@+ to make the % \verb+\endalign+ macro a no-op and to throw away its % argument. The reason for this will become clear below. % \begin{macrocode} \else \ifmmode\nomath@env \DN@{\let\endalign\relax\@gobble}\else % \end{macrocode} % Now we can safely start the display math mode and do the % appropriate initializations. We define \verb+\next@+ to % be \verb+\align@+ which is the internal macro that processes % the body of a top-level {\tt align} environment. % \begin{macrocode} $$\stepcounter{equation}% \st@rredfalse\let\next@\align@\fi\fi % \end{macrocode} % Finally we scan the environments body and call \verb+\next@+ % on it. The definition of \verb+\next@+ in the invalid case % above is made to recover most gracefully from the error by % skipping the whole environment. % \begin{macrocode} \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\align*} % The \verb+\align*+ macro is defined analogously to % \verb+align+. % \begin{macrocode} \@namedef{align*}{\ifingather@ {\ifnum0=`}\fi \DN@{\@nameuse{align* (in \string\gather)}}\else \ifmmode\nomath@env \DN@{\@namedef{endalign*}{}\@gobble}\else $$\st@rredtrue \let\next@\align@\fi\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\lineht@} % The dimen register \verb+\lineht@+ is used to keep track % of the height of a row in an alignment. % \begin{macrocode} \newdimen\lineht@ % \end{macrocode} % \end{macro} % % \begin{macro}{\align@} % The definition of the \verb+\align@+ macro is now rather % straightforward. After setting the switches and doing % the initializations we call up either \verb*+\align + or % \verb*+\align +, depending on whether the tags should be % typeset to the left or to the right. % \begin{macrocode} \def\align@{\inalign@true\inany@true \displaybreak@\intertext@ \let\math@cr@@@\math@cr@@@align \let\tag\tag@in@align \global\and@\z@\global\dspbrk@lvl\m@ne \iftagsleft@\DN@{\@nameuse{align }}\else \DN@{\@nameuse{align \space}}\fi\next@} % \end{macrocode} % \end{macro} % % (Internal note: Beginning here, numerous changes have been made % by David M. Jones to implement the \opt{fleqn} option and the % \cn{adjusttag} command. The changes to \cs{align\space} are % typical, so they have been described in some detail. Later, I'll % only describe new types of changes.) % % \begin{macro}{\align\space} % \begin{macrocode} \@namedef{align }#1{% \measure@{#1}% \global\and@\z@ \global\dspbrk@lvl\m@ne % \end{macrocode} % DMJ: \cs{totwidth@} is the width of the longest line of the % display, as calculated by \cs{measure@} above, and is used to % determine whether the equation will result in an overfull hbox. % However, if the flushleft style is being used, this should be % incremented by \cs{@mathmargin}, since the left margin is fixed. % \begin{macrocode} \if@fleqn %%*F \advance\totwidth@\@mathmargin %%*F \fi %%*F \ifdim\totwidth@>\displaywidth \let\displaywidth@\totwidth@ \else \let\displaywidth@\displaywidth \fi \ifingather@ \everycr{% \noalign{% \global\and@\z@ \global\dspbrk@lvl\m@ne }% }% \else \displ@y@ \fi \Let@ \ifst@rred\else\@seteqlabel\theequation\fi % \end{macrocode} % DMJ: The initial \cs{tabskip} is set to \cs{@mathmargin}, rather % than the hardcoded value of \cs{@centering} that was used % previously. % \begin{macrocode} \tabskip\@mathmargin %%*F % \end{macrocode} % DMJ: Normally, the \cs{halign} that makes up the \cs{align} % should be typesset to a width of \cs{displaywidth}. However, if % the \cs{align} is used inside of a \cs{gather} when \opt{fleqn} % is in force, the \cs{align} will be shifted to the right by % \cs{@mathmargin}, since the enclosing \cs{gather} will itself % start with a \cs{tabskip} of \cs{@mathmargin}. So, if the % \cs{align} is inside a \cs{gather}, we set the \cs{align}'s % initial \cs{tabskip} to zero, and decrease the width of the % \cs{align} by \cs{@mathmargin}. % \begin{macrocode} \dimen@\displaywidth %%*F \if@fleqn %%*F \ifingather@ %%*F \tabskip\z@skip %%*F \advance\dimen@-\@mathmargin %%*F \fi %%*F \fi %%*F \halign to\dimen@\bgroup %%*F \ifst@rred\nonumber\fi \hfil \strut@ \setboxz@h{\global\tag@false$\m@th\displaystyle{\@lign##}$}% \global\lwidth@\wdz@ \global\lineht@\ht\z@ \boxz@ \global\advance\and@\@ne \tabskip\z@skip &\setboxz@h{$\m@th\displaystyle{{}\@lign##}$}% \global\rwidth@\wdz@ \ifdim\ht\z@>\lineht@ \global\lineht@\ht\z@ \fi \boxz@ \hfil \global\advance\and@\@ne \tabskip\@centering &\kern-\displaywidth@ \setboxz@h{\@lign\strut@{##}}% % \end{macrocode} % DMJ: If \opt{fleqn} is in force,, the calculation of how much % space is left for the equation tag needs to be modified in a % fairly obvious way. % \begin{macrocode} \if@fleqn %%*F \dimen@\@mathmargin %%*F \advance\dimen@\maxlwidth@ %%*F \advance\dimen@-\lwidth@ %%*F \else %%*F \dimen@\displaywidth \advance\dimen@-\totwidth@ \divide\dimen@\tw@ \advance\dimen@\maxlwidth@ \advance\dimen@-\lwidth@ \fi %%*F \ifdim\dimen@<\tw@\wdz@ \rlap{\vbox{\normalbaselines\boxz@\vbox to\lineht@{}}}% \else \rlap{\boxz@}% \fi \tabskip\displaywidth@ \crcr #1% } % \end{macrocode} % \end{macro} % % \begin{macro}{\align\space\space} % \begin{macrocode} \@namedef{align \space}#1{% \measure@{#1}% \if@fleqn %%*F \advance\totwidth@\@mathmargin %%*F \fi %%*F \global\and@\z@ \global\dspbrk@lvl\m@ne \ifingather@ \everycr{\noalign{\global\and@\z@\global\dspbrk@lvl\m@ne}}% \else \displ@y@ \fi \Let@ \ifst@rred\else\@seteqlabel\theequation\fi \tabskip\@mathmargin %%*F \dimen@\displaywidth %%*F \if@fleqn %%* \ifingather@ %%*F \tabskip\z@skip %%*F \advance\dimen@-\@mathmargin %%*F \fi %%*F \fi %%*F \halign to\dimen@\bgroup %%*F \ifst@rred\nonumber\fi \hfil \strut@ \setboxz@h{\global\tag@false$\m@th\displaystyle{\@lign##}$}% \global\lwidth@\wdz@\boxz@ \global\advance\and@\@ne \tabskip\z@skip &\setboxz@h{$\m@th\displaystyle{{}\@lign##}$}% \global\rwidth@\wdz@ \boxz@ % \end{macrocode} % DMJ: Miscellaneous question: Is the following line a typo? Why % not \cs{hfil}, as in the corresponding line in % \verb+\@nameuse{align }+? % \begin{macrocode} \hfill \global\advance\and@\@ne \tabskip\@centering &\setboxz@h{\@lign\strut@{##}}% \dimen@\displaywidth \advance\dimen@-\totwidth@ \divide\dimen@\tw@ \advance\dimen@\maxrwidth@ \advance\dimen@-\rwidth@ \ifdim\dimen@<\tw@\wdz@ % \end{macrocode} % DMJ: \cs{@movetag} will take care of any vertical adjustment % requested by \adjusttag. % \begin{macrocode} \llap{\vtop{\@movetag\normalbaselines\null\boxz@}}%%*T \else \llap{\boxz@}% \fi \tabskip\z@skip \crcr#1% } % \end{macrocode} % \end{macro} % % \begin{macro}{\endalign} % \begin{macro}{\endalign*} % (Internal remark: should \verb+\endalign+ set % \verb+\postdisplaypenalty+ according to the % value of \verb+\dspbrk@lvl+?) % \begin{macrocode} \def\endalign{\math@cr@@@align \black@\totwidth@ \egroup$$\global\@ignoretrue\setb@ck} \@namedef{endalign*}{\math@cr@@@align\black@\totwidth@ \egroup$$\global\@ignoretrue} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\align\space (in \string\gather)} % \begin{macrocode} \@namedef{align (in \string\gather)}{% \ifst@rred\stepcounter{equation}\fi \def\endalign{\@nameuse{endalign (in \string\gather)}\ifnum0=`{\fi}}% \vcenter\bgroup\st@rredfalse \collect@body\align@} % \end{macrocode} % \end{macro} % % \begin{macro}{\endalign\space (in \string\gather)} % \begin{macrocode} \@namedef{endalign (in \string\gather)}{% \math@cr@@@align\black@\totwidth@ \egroup\egroup \ifst@rred\setb@ck\fi% this ifst@rred is set by the enclosing gather \global\tag@false\global\@eqnswfalse} % \end{macrocode} % \end{macro} % % \begin{macro}{\align* (in \string\gather)} % \begin{macrocode} \@namedef{align* (in \string\gather)}{% \@namedef{endalign*}{\@nameuse{endalign* (in \string\gather)}% \ifnum0=`{\fi}}% \vcenter\bgroup\st@rredtrue \collect@body\align@} % \end{macrocode} % \end{macro} % % \begin{macro}{\endalign* (in \string\gather)} % \begin{macrocode} \@namedef{endalign* (in \string\gather)}{% \math@cr@@@align\black@\totwidth@\egroup\egroup \global\tag@false\global\@eqnswfalse} % \end{macrocode} % \end{macro} % % % \subsubsection{The {\tt alignat} environment} % % \begin{macro}{\ifxat@} % \begin{macrocode} \newif\ifxat@ % \end{macrocode} % \end{macro} % % \begin{macro}{\alignat} % \begin{macrocode} \def\alignat#1{% \ifmmode\nomath@env\DN@{\let\endalignat\relax\@gobble}\else$$% \st@rredfalse\stepcounter{equation}\@seteqlabel\theequation \DN@{\@nameuse{alignat }#1}\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\alignat*} % \begin{macrocode} \@namedef{alignat*}#1{% \ifmmode\nomath@env\DN@{\@namedef{endalignat*}{}\@gobble}\else$$% \st@rredtrue \DN@{\@nameuse{alignat }#1}\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifmeasuring@} % \begin{macrocode} \newif\ifmeasuring@ % \end{macrocode} % \end{macro} % % \begin{macro}{\savealignat@} % \begin{macrocode} \newbox\savealignat@ % \end{macrocode} % \end{macro} % % \begin{macro}{\math@cr@@@alignat} % \begin{macrocode} \def\math@cr@@@alignat{% \if@eqnsw\global\tag@true\fi \iftag@ \multiply\count@\tw@ \xdef\next@{}\loop\ifnum\count@>\and@\xdef\next@{&\next@}% \advance\count@\m@ne\repeat\else \let\next@\relax\fi \next@ \relax \if@eqnsw\tagform@\theequation\stepcounter{equation}\else \iftag@\df@tag\fi\fi \global\@eqnswtrue\cr}% % \end{macrocode} % \end{macro} % % \begin{macro}{\alignat\space} % \begin{macrocode} \@namedef{alignat }#1#2{% \inany@true \xat@false \let\tag\tag@in@align \def\math@cr@@@{\count@#1\relax \math@cr@@@alignat}% \displaybreak@ \intertext@ \displ@y@ \ifst@rred \global\@eqnswfalse \else \global\@eqnswtrue \fi \measuring@true \setbox\savealignat@\hbox{% $\m@th\displaystyle\Let@ \attag@{#1}% \vbox{\firstchoice@false\halign{\span\preamble@@\crcr#2\crcr}}$% }% \measuring@false \Let@ \attag@{#1}% \tabskip\@mathmargin %%*F \halign to\displaywidth\bgroup \span\preamble@@\crcr #2% } % \end{macrocode} % \end{macro} % % \begin{macro}{\endalignat} % \begin{macrocode} \def\endalignat{\math@cr@@@\black@{\wd\savealignat@}% \egroup\setb@ck$$\global\@ignoretrue} % \end{macrocode} % \end{macro} % % \begin{macro}{\endalignat*} % \begin{macrocode} \@namedef{endalignat*}{\math@cr@@@\black@{\wd\savealignat@}\egroup $$\global\@ignoretrue} % \end{macrocode} % \end{macro} % % % \subsubsection{The {\tt xalignat} environment} % % \begin{macro}{\xalignat} % \begin{macrocode} \def\xalignat#1{% \ifmmode\nomath@env\DN@{\let\endxalignat\relax\@gobble}\else$$% \st@rredfalse\stepcounter{equation}\@seteqlabel\theequation \DN@{\@nameuse{xalignat }#1}\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\xalignat*} % \begin{macrocode} \@namedef{xalignat*}#1{% \ifmmode\nomath@env\DN@{\@namedef{endxalignat*}{}\@gobble}\else$$% \st@rredtrue \DN@{\@nameuse{xalignat }#1}\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\endxalignat} % \begin{macro}{\endxalignat*} % \begin{macrocode} \let\endxalignat=\endalignat \expandafter\let\csname endxalignat*\expandafter \endcsname\csname endalignat*\endcsname % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\xalignat\space} % \begin{macrocode} \@namedef{xalignat }#1#2{% \inany@true \xat@true \let\tag\tag@in@align \def\math@cr@@@{\count@#1\relax\math@cr@@@alignat}% \displaybreak@ \intertext@ \displ@y@ \measuring@true \setbox\savealignat@\hbox{% $\m@th\displaystyle\Let@ \attag@{#1}% \vbox{% \firstchoice@false \halign{\span\preamble@@\crcr#2\crcr}% }% $% }% \measuring@false \Let@ \attag@{#1}% \tabskip\@mathmargin %%*F \halign to\displaywidth\bgroup \span\preamble@@\crcr#2% } % \end{macrocode} % \end{macro} % % Bug: xalignat* did not suppress numbers. Fix [mjd,1994/10/11]: Take % out \cs{ifst@rred} reference in \cs{xalignat\char`\ } and move it % to the beginning of the halign preamble (in \cs{attag@}); the % \cn{nonumber} function needs to be executed at the beginning of % every line if the \cs{ifst@rred} switch is true. % \begin{macro}{\attag@} % \begin{macrocode} \def\attag@#1{% \let\TAG@\Tag@\let\Tag@0% \ifmeasuring@\def\llap@##1{\setboxz@h{##1}\hbox to\tw@\wdz@{}}% \def\rlap@##1{\setboxz@h{##1}\hbox to\tw@\wdz@{}}\else \let\llap@\llap\let\rlap@\rlap\fi \toks@{\hfil\strut@$\m@th\displaystyle{\@lign\the\hashtoks@}$% \tabskip\z@skip \global\advance\and@\@ne &$\m@th\displaystyle{{}\@lign\the\hashtoks@}$\hfil \ifxat@\tabskip\@centering\fi\global\advance\and@\@ne}% \iftagsleft@ \@temptokena{\tabskip\@centering&\Tag@\kern-\displaywidth \rlap@{\@lign \the\hashtoks@ }% \global\advance\and@\@ne\tabskip\displaywidth}\else \@temptokena{\tabskip\@centering&\Tag@\llap@{\@lign \the\hashtoks@ }\global\advance\and@\@ne\tabskip\z@skip}\fi \atcount@#1\relax\advance\atcount@\m@ne \loop\ifnum\atcount@>\z@ \toks@\expandafter{\the\toks@&\hfil$\m@th\displaystyle{\@lign \the\hashtoks@}$\global\advance\and@\@ne \tabskip\z@skip &$\m@th\displaystyle{{}\@lign\the\hashtoks@}$\hfil\ifxat@ \tabskip\@centering\fi\global\advance\and@\@ne}\advance\atcount@\m@ne \repeat \xdef\preamble@{\the\toks@\the\@temptokena}% \xdef\preamble@@{\ifst@rred\noexpand\nonumber\fi\preamble@}% \let\Tag@\TAG@} % \end{macrocode} % \end{macro} % % \begin{macro}{\xxalignat} % \begin{macrocode} \def\xxalignat#1{% \ifmmode\nomath@env\DN@{\let\endxxalignat\relax\@gobble}\else$$% \DN@{\@nameuse{xxalignat }#1}\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\xxalignat\space} % \begin{macrocode} \@namedef{xxalignat }#1#2{\inany@true \displaybreak@\intertext@ \displ@y\setbox\savealignat@\hbox{$\m@th\displaystyle\Let@ \xxattag@{#1}% \vbox{\firstchoice@false\halign{\span\preamble@@\crcr#2\crcr}}$}% \Let@\xxattag@{#1}\tabskip\z@skip\halign to\displaywidth\bgroup \span\preamble@@\crcr#2} % \end{macrocode} % \end{macro} % % \begin{macro}{\endxxalignat} % \begin{macrocode} \expandafter\let\expandafter\endxxalignat\csname endxalignat*\endcsname % \end{macrocode} % \end{macro} % % \begin{macro}{\xxattag@} % \begin{macrocode} \def\xxattag@#1{\toks@{\tabskip\z@skip\hfil\strut@ $\m@th\displaystyle{\the\hashtoks@}$&% $\m@th\displaystyle{{}\the\hashtoks@}$\hfil\tabskip\@centering&}% \atcount@#1\relax\advance\atcount@\m@ne\loop\ifnum\atcount@>\z@ \toks@ \expandafter {\the\toks@&\hfil$\m@th\displaystyle{\the\hashtoks@}$% \tabskip\z@skip&$\m@th\displaystyle{{}\the\hashtoks@}$\hfil \tabskip\@centering}\advance\atcount@\m@ne\repeat \xdef\preamble@{\the\toks@\tabskip\z@skip}\xdef\preamble@@{\preamble@}} % \end{macrocode} % \end{macro} % % % \subsubsection{The {\tt gather} environment} % % \begin{macro}{\gwidth@} % \begin{macro}{\gmaxwidth@} % \begin{macrocode} \newdimen\gwidth@ \newdimen\gmaxwidth@ % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\gmeasure@} % \begin{macrocode} \def\gmeasure@#1{\gwidth@\z@\gmaxwidth@\z@\setbox\@ne\vbox{\Let@ \firstchoice@false\let\tag\gobble@tag \halign{\setboxz@h{$\m@th\displaystyle{##}$}\global\gwidth@\wdz@ \ifdim\gwidth@>\gmaxwidth@\global\gmaxwidth@\gwidth@\fi &\@gobble{##}\crcr#1\crcr}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\math@cr@@@gather} % \begin{macrocode} \def\math@cr@@@gather{% \if@eqnsw\global\tag@true\fi \iftag@ \DN@{&\relax \if@eqnsw \tagform@\theequation \stepcounter{equation}% \else\iftag@\df@tag\fi\fi}% \else \expandafter\@gobble\fi \next@ \global\@eqnswtrue\cr} % \end{macrocode} % \end{macro} % % \begin{macro}{\gather} % \begin{macrocode} \def\gather{% \ifmmode\nomath@env\DN@{\let\endgather\relax\@gobble}\else $$% \ingather@true\inany@true \stepcounter{equation}% \let\tag\tag@in@align\st@rredfalse \displaybreak@\intertext@ \displ@y \Let@\@seteqlabel\theequation \let\math@cr@@@\math@cr@@@gather \iftagsleft@\DN@{\@nameuse{gather }}\else \DN@{\@nameuse{gather \space}}\fi\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\gather*} % \begin{macrocode} \@namedef{gather*}{% \ifmmode\nomath@env\DN@{\@namedef{endgather*}{}\@gobble}\else $$% \ingather@true\inany@true \let\tag\tag@in@align\st@rredtrue \displaybreak@\intertext@ \displ@y\Let@ \let\math@cr@@@\math@cr@@@gather \iftagsleft@\DN@{\@nameuse{gather }}\else \DN@{\@nameuse{gather \space}}\fi\fi \collect@body\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\glineht@} % \begin{macrocode} \newdimen\glineht@ % \end{macrocode} % \end{macro} % % \begin{macro}{\gather\space\space} % After using \verb;\gmeasure@; we need to again % \verb;\dt@ptrue;. (If not then we get % \verb;\penalty\@eqpen; before the first line, which could % allow an undesired page break.) % \begin{macrocode} \@namedef{gather \space}#1{% \gmeasure@{#1}% \if@fleqn %%*F \advance\gmaxwidth@\@mathmargin %%*F \fi %%*F \global\dt@ptrue \tabskip\@mathmargin %%*F \halign to\displaywidth\bgroup \ifst@rred\nonumber\else\global\@eqnswtrue\fi % \end{macrocode} % DMJ: If we're doing flush left equations, we don't want any extra % glue here. % \begin{macrocode} \if@fleqn\else\hfil\fi %%*F \strut@ \setboxz@h{\global\tag@false$\m@th\displaystyle{##}$}% \global\gwidth@\wdz@\boxz@ \hfil % \end{macrocode} % DMJ: We need to explicitly set \cs{tabskip} back to % \cs{@centering} here, since it no longer inherits that value from % the \cs{tabskip} set above. % \begin{macrocode} \tabskip\@centering %%*F &\setboxz@h{\strut@{##}}% \dimen@\displaywidth \advance\dimen@-\gwidth@ \if@fleqn %%*F \advance\dimen@-\@mathmargin %%*F \else %%*F % \begin{macrocode} % DMJ: I've fixed a bug here in the algorithm used by \cn{gather} % for deciding when equation tags should be put on a separate line: % The previous algorithm only checked to see if there was space for % the label itself, rather than seeing if there was twice as much % space as the label takes up. The solution is to divide the % currently calculated distance by 2. (This is, naturally, not % backwards compatible.) % \end{macrocode} \divide\dimen@\tw@ %%*B \fi %%*F \ifdim\dimen@<\tw@\wdz@ %%* \llap{\vtop{\@movetag\normalbaselines\null\boxz@}}%%*T %%* \else \llap{\boxz@}% %%* \fi \tabskip\z@skip \crcr #1% } % \end{macrocode} % \end{macro} % % \begin{macro}{\endgather} % \begin{macro}{\endgather*} % \begin{macrocode} \def\endgather{\math@cr@@@ \black@\gmaxwidth@\egroup $$\setb@ck\global\@ignoretrue} \@namedef{endgather*}{\math@cr@@@ \black@\gmaxwidth@\egroup $$\global\@ignoretrue} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\gather\space} % \begin{macrocode} \@namedef{gather }#1{% \gmeasure@{#1}% \global\dt@ptrue \if@fleqn %%*F \advance\gmaxwidth@\@mathmargin %%*F \fi %%*F \ifdim\gmaxwidth@>\displaywidth \let\gdisplaywidth@\gmaxwidth@ \else \let\gdisplaywidth@\displaywidth \fi \tabskip\@mathmargin %%*F \halign to\displaywidth\bgroup \ifst@rred\nonumber\else\global\@eqnswtrue\fi \if@fleqn\else\hfil\fi %%*F \strut@ \setboxz@h{\global\tag@false$\m@th\displaystyle{##}$}% \global\gwidth@\wdz@ \global\glineht@\ht\z@ \boxz@ \hfil \tabskip\@centering %%*F &\kern-\gdisplaywidth@ \setboxz@h{\strut@{##}}% \if@fleqn %%*F \dimen@\@mathmargin %%*F \else %%*F \dimen@\displaywidth \advance\dimen@-\gwidth@ % \end{macrocode} % Another instance of the non-backwards compatible bug fix % mentioned above. % \begin{macrocode} \divide\dimen@\tw@ %%*B \fi %%*F \ifdim\dimen@<\tw@\wdz@ %%* \rlap{\vbox{\normalbaselines\boxz@\vbox to\glineht@{}}}% %%* \else \rlap{\boxz@}% %%* \fi \tabskip\gdisplaywidth@ \crcr #1% } % \end{macrocode} % \end{macro} % % % \subsubsection {The {\tt split} environment} % % \begin{macro}{\split} % \begin{macrocode} \def\split{% \ifinany@\let\next@\insplit@\else \DN@{\PackageError{amstex}{\string\begin{split} is not allowed here. Try the `aligned' environment.}\@ehb}\fi \next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\insplit@} % \begin{macrocode} \def\insplit@{\global\setbox\z@\vbox\bgroup \Let@ \restore@math@cr \default@tag % disallow use of \tag here \ialign\bgroup \hfil\strut@ $\m@th\displaystyle{##}$&$\m@th\displaystyle{{}##}$\hfill\crcr} % \end{macrocode} % \end{macro} % % \begin{macro}{\endsplit} % \begin{macrocode} \def\endsplit{\crcr\egroup\egroup \iftagsleft@\expandafter\lendsplit@\else \expandafter\rendsplit@\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\rendsplit@} % \begin{macrocode} \def\rendsplit@{\global\setbox9 \vbox {\unvcopy\z@\global\setbox8 \lastbox\unskip}% \setbox\@ne\hbox{\unhcopy8 \unskip\global\setbox\tw@\lastbox \unskip\global\setbox\thr@@\lastbox}% \global\setbox7 \hbox{\unhbox\tw@\unskip}% \ifinalign@\ifctagsplit@ \gdef\split@{\hbox to\wd\thr@@{}& \vcenter{\vbox{\moveleft\wd\thr@@\boxz@}}}% \else\gdef\split@{&\vbox{\moveleft\wd\thr@@\box9}\crcr \box\thr@@&\box7}\fi \else \ifctagsplit@\gdef\split@{\vcenter{\boxz@}}\else \gdef\split@{\box9\crcr\hbox{\box\thr@@\box7}}\fi \fi \aftergroup\split@} % \end{macrocode} % \end{macro} % % \begin{macro}{\lendsplit@} % \begin{macrocode} \def\lendsplit@{\global\setbox9\vtop{\unvcopy\z@}% \setbox\@ne\vbox{\unvcopy\z@\global\setbox8\lastbox}% \setbox\@ne\hbox{\unhcopy8\unskip\setbox\tw@\lastbox \unskip\global\setbox\thr@@\lastbox}% \ifinalign@\ifctagsplit@ \gdef\split@{\hbox to\wd\thr@@{}& \vcenter{\vbox{\moveleft\wd\thr@@\box9}}}% \else \gdef\split@{\hbox to\wd\thr@@{}&\vbox{\moveleft\wd\thr@@\box9}}\fi \else \ifctagsplit@\gdef\split@{\vcenter{\box9}}\else \gdef\split@{\box9}\fi \fi\aftergroup\split@} % \end{macrocode} % \end{macro} % % % \subsubsection{The {\tt multline} environment} % % In the original \AmSTeX{}, \verb=\multlinegap= is a macro with % an argument that resets an internal dimension (one with an % @ character in its name). Here, to save control sequence names, % we define \verb=\multlinegap= to be the dimension itself and the % documentation instructs users to use \verb=\setlength= if they % need to change it. % \begin{macro}{\multlinegap} % \begin{macro}{\multlinetaggap@} % \begin{macrocode} \newdimen\multlinegap \multlinegap10pt \newdimen\multlinetaggap@ \multlinetaggap@10pt % \end{macrocode} % \end{macro} % \end{macro} % % Remark (21-JUN-1990): If \verb=\tag= is used inside % \verb=multline= to override the normal tag, the \verb=\label= % doesn't seem to be correctly set. Need to look into this. % \begin{macro}{\multline} % \begin{macrocode} \def\multline{% \ifmmode\nomath@env\DN@{\let\endmultline\relax\@gobble}% \else $$\DN@{\collect@body\multline@}\fi \st@rredfalse\@eqnswtrue \@seteqlabel\theequation \stepcounter{equation}\next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\multline*} % \begin{macrocode} \@namedef{multline*}{% \ifmmode\nomath@env\DN@{\@namedef{endmultline*}{}\@gobble}% \else $$\DN@{\collect@body\multline@}\fi \st@rredtrue\@eqnswfalse \let\@currentlabel\@empty \next@} % \end{macrocode} % \end{macro} % % \begin{macro}{\multline@} % The definition of \verb'\tag' here is complicated by the fact that % the tag contents are typeset only during the measuring phase, and % saved in a box. So we do not want to apply the % \verb'\iffirstchoice@' test to the statement that sets back the % equation counter. As previously defined (in versions 1.1 and % earlier), a \verb'\tag' in a \verb'multline' environment did not % properly set the equation counter back to the proper value. % [mjd,17-Jan-1994] % \begin{macrocode} \def\multline@{\inany@true\displaybreak@ \global\tag@false \def\tag{\ifst@rred\else % Can't use \setb@ck here because its \iffirstchoice@ test is % misguided in the multline case. \global\advance\c@equation\m@ne\fi\tag@in@align}% \iftagsleft@ \expandafter\lmultline@@\else \expandafter\rmultline@@\fi} % \end{macrocode} % \end{macro} % % \begin{macro}{\mwidth@} % \begin{macrocode} \newdimen\mwidth@ % \end{macrocode} % \end{macro} % % \begin{macro}{\rmeasure@} % \begin{macrocode} \def\rmmeasure@#1{% \def\shoveleft##1{##1}\def\shoveright##1{##1}% \setbox\@ne\vbox{\firstchoice@false\Let@\halign{\setboxz@h {$\m@th\@lign\displaystyle{}##$}\global\mwidth@\wdz@ \crcr#1\crcr}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\mlineht@} % \begin{macrocode} \newdimen\mlineht@ % \end{macrocode} % \end{macro} % % \begin{macro}{\ifzerocr@} % \begin{macro}{\ifonecr@} % \begin{macrocode} \newif\ifzerocr@ \newif\ifonecr@ % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\lmmeasure@} % \begin{macrocode} \def\lmmeasure@#1{\global\zerocr@true\global\onecr@false \everycr{\noalign{\ifonecr@\global\onecr@false\fi \ifzerocr@\global\zerocr@false\global\onecr@true\fi}}% \def\shoveleft##1{##1}\def\shoveright##1{##1}% \setbox\@ne\vbox{\Let@\firstchoice@false\halign{\setboxz@h {$\m@th\@lign\displaystyle{}##$}\ifonecr@\global\mwidth@\wdz@ \global\mlineht@\ht\z@\fi\crcr#1\crcr}}} % \end{macrocode} % \end{macro} % % \begin{macro}{\mtagbox@} % \begin{macro}{\ltwidth@} % \begin{macro}{\rtwidth@} % \begin{macrocode} \newbox\mtagbox@ \newdimen\ltwidth@ \newdimen\rtwidth@ % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\lmultline@@} % \begin{macrocode} \def\lmultline@@#1{% \lmmeasure@{#1}% \setbox\mtagbox@\hbox{% \iftag@ \df@tag \else \if@eqnsw \global\tag@true \tagform@\theequation \fi \fi }% \dimen@\mwidth@ \advance\dimen@\wd\mtagbox@ \advance\dimen@\multlinetaggap@ \if@fleqn %%*F \advance\dimen@\@mathmargin %%*F \fi %%*F \ifdim\dimen@>\displaywidth \ltwidth@\z@ \else \ltwidth@\wd\mtagbox@ \fi \lmultline@@@#1 } % \end{macrocode} % \end{macro} % % \begin{macro}{\lmultline@@} % \begin{macrocode} \def\lmultline@@@{% \displ@y \def\shoveright##1{##1\hfilneg\hskip\multlinegap}% % \end{macrocode} % DMJ: In \opt{fleqn} mode, \cn{shoveleft} doesn't need to do % anything. (Question: Are \cs{shoveleft} and \cs{shoveright} even % considered supported parts of \AmS-\LaTeX? I don't think they're % in the documentation.) % % DMJ: It's mildly annoying that \cs{shoveleft} and \cs{shoveright} % do unreasonable things if used on the first or last line of a % \cs{multline}, but I haven't tried to do anything about that. It % might be hard. % \begin{macrocode} \if@fleqn %%*F \def\shoveleft##1{##1}% %%*F \else %%*F \def\shoveleft##1{% \setboxz@h{$\m@th\displaystyle{}##1$}% \setbox\@ne\hbox{$\m@th\displaystyle##1$}% \hfilneg \iftag@ \ifdim\ltwidth@>\z@ \hskip\ltwidth@ \hskip\multlinetaggap@ \fi \else \hskip\multlinegap \fi \hskip.5\wd\@ne \hskip-.5\wdz@##1% }% \fi %%*F % \end{macrocode} % DMJ: It seems like a good idea to initialize \cs{tabskip} to 0 % here, just in case it's been left with a non-zero value. % \begin{macrocode} \if@fleqn %%*F \tabskip\@mathmargin %%*F \else %%*F \tabskip\z@skip %%* \fi %%*F % \end{macrocode} % DMJ: In \opt{fleqn} mode, effective width of the display is % $\cs{displaywidth} - \cs{@mathmargin}$, so that's how wide the % \cs{hbox} in the preamble should be. I'll reuse \cs{totwidth@} % here to do the calculation since an align can't occur inside a % \cs{multline}. % \begin{macrocode} \totwidth@\displaywidth %%*F \if@fleqn %%*F \advance\totwidth@-\@mathmargin %%*F \fi %%*F \halign\bgroup \Let@ \let\tag\gobble@tag \hbox to\totwidth@{% %%*F \strut@$\m@th\displaystyle % \end{macrocode} % DMJ: In order to get the spacing of the last line right in fleqn % mode, we need to play a little game here. Normally the % stretchability of the \cs{hskip} here will be suppressed by the % \cs{hfil} at the end of the template, except for the last line, % when that \cs{hfil} will be removed by the \cs{hfilneg} in % \lendmultline@. % \begin{macrocode} \if@fleqn %%*F \hskip 0pt plus 1000pt %%*F \else %%*F \hfil \fi %%*F {}##\hfil$% }% \crcr % \end{macrocode} % DMJ: In \opt{fleqn} mode, it's the \cs{tabskip} of % \cs{@mathmargin} that needs to be removed in the first line, not % the \cs{hfil} at the beginning of the template. % \begin{macrocode} \if@fleqn %%*F \hskip-\@mathmargin %%*F \else %%*F \hfilneg \fi %%*F \iftag@ \ifdim\ltwidth@>\z@ \box\mtagbox@ \hskip\multlinetaggap@ \else \rlap{% \vbox{% \normalbaselines \hbox{\strut@\box\mtagbox@}% \vbox to\mlineht@{}% }% }% % \end{macrocode} % DMJ: This is just a whim of mine: if the equation tag doesn't fit % on the same line with the first line of the display, shouldn't % the first line be indented by \multlinegap? This isn't backwards % compatible. % \begin{macrocode} \hskip\multlinegap %%* \fi \else \hskip\multlinegap \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\rmultline@@} % \begin{macrocode} \def\rmultline@@#1{% \rmmeasure@{#1}% \setbox\mtagbox@\hbox{% \iftag@ \df@tag \else \if@eqnsw \global\tag@true \tagform@\theequation \fi \fi }% \dimen@\mwidth@ \advance\dimen@\wd\mtagbox@ \advance\dimen@\multlinetaggap@ \if@fleqn %%*F \advance\dimen@\@mathmargin %%*F \fi %%*F \ifdim\dimen@>\displaywidth \rtwidth@\z@ \else \rtwidth@\wd\mtagbox@ \fi \rmultline@@@#1 } % \end{macrocode} % \end{macro} % % \begin{macro}{\rmultline@@@} % \begin{macrocode} \def\rmultline@@@{% \displ@y \def\shoveright##1{% ##1% \hfilneg \iftag@ \ifdim\rtwidth@>\z@ \hskip\rtwidth@ \hskip\multlinetaggap@ \fi \else \hskip\multlinegap \fi }% \if@fleqn %%*F \def\shoveleft##1{##1}% %%*F \else %%*F \def\shoveleft##1{% \setboxz@h{$\m@th\displaystyle{}##1$}% \setbox\@ne\hbox{$\m@th\displaystyle##1$}% \hfilneg \hskip\multlinegap \hskip.5\wd\@ne \hskip-.5\wdz@ ##1% }% \fi %%*F \if@fleqn %%*F \tabskip\@mathmargin %%*F \else %%*F \tabskip\z@skip %%* \fi %%*F \totwidth@\displaywidth %%*F \if@fleqn %%*F \advance\totwidth@-\@mathmargin %%*F \fi %%*F \halign\bgroup \Let@ \let\tag\gobble@tag \hbox to\totwidth@{% \strut@$\m@th\displaystyle \if@fleqn %%*F \hskip 0pt plus 1000pt %%*F \else %%*F \hfil \fi %%*F {}##\hfil$% }% \crcr \if@fleqn %%*F \hskip-\@mathmargin %%*F \else %%*F \hfilneg \fi %%*F \hskip\multlinegap } % \end{macrocode} % \end{macro} % % \begin{macro}{\endmultline} % \begin{macro}{\endmultline*} % We use some expandafters here to reduce the number % of tokens in the replacement text of \verb;\endmultline;. % \verb;\endmultline; and \verb;\endmultline*; are the same. % \begin{macrocode} \def\endmultline{\iftagsleft@\expandafter\lendmultline@\else \expandafter\rendmultline@\fi\global\@ignoretrue} % \end{macrocode} % \begin{macrocode} \expandafter\let\csname endmultline*\endcsname=\endmultline % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\lendmultline@} % \begin{macrocode} \def\lendmultline@{\hfilneg\hskip\multlinegap\crcr\egroup$$} % \end{macrocode} % \end{macro} % % \begin{macro}{\rendmultline@} % \begin{macrocode} \def\rendmultline@{% \iftag@ \ifdim\rtwidth@>\z@ \hskip\multlinetaggap@ \box\mtagbox@ \else % \end{macrocode} % DMJ: More non-backwards compatible whim; see above. % \begin{macrocode} \hskip\multlinegap %%* \llap{% \vtop{% \@movetag %%*T \normalbaselines\null\hbox{\strut@\box\mtagbox@}% }% }% \fi \else \hskip\multlinegap \fi \hfilneg \crcr \egroup$$% } % \end{macrocode} % \end{macro} % % \subsection{DMJ: Miscellaneous} % % \begin{macro}{\[} % % DMJ: \cs\[ and \cs\] should be redefined for two reasons: % % \begin{enumerate} % % \item % so they act properly with \opt{fleqn} (of course, \fn{fleqn.clo} % will redefine them, so we have to be careful; see comments at % beginning of file) % % \item % so the spacing above and below it is consistent with the other % \AMS-\LaTeX\ math environments when $\cs{abovedisplayskip} \ne % \cs{abovedisplayshortskip}$. % % \end{enumerate} % % For obvious reasons, this change is not backwards compatible. % [mjd,1994/10/11] Canceled change pending further tests. \verb % inside \[...\] would no longer work. That might be too big a % problem for existing documents. % \begin{macrocode} %\def\[#1\]{\begin{equation*}#1\end{equation*}} % \end{macrocode} % \end{macro} % % \subsection{Final incantations} % % \begin{macro}{\@arrayparboxrestore} % Here we must reset a few additional parameters. % In principle we also have to ensure that the \verb+\and@+ % counter does not change over a \verb+\parbox+ or % {\tt minipage}. But this can be done later. % \begin{macrocode} \expandafter\def \expandafter\@arrayparboxrestore \expandafter{\@arrayparboxrestore \inany@false\ingather@false\inalign@false \default@tag} % \end{macrocode} % \end{macro} % % \begin{macro}{\equation} % \begin{macro}{\endequation} % The {\tt split} environment does not work inside a % {\tt displaymath} or {\tt equation} environment since it % must be enclosed by an alignment. % We therefore redefine the {\tt equation} environment to be % a one-lined {\tt gather} environment. % The \verb+\\+ command is made inaccessible in an {\tt equation} % environment. % \begin{macrocode} \def\equation{\gather\def\\{\PackageError{amstex}{\Invalid@@\\}\@eha}} \def\endequation{\endgather} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\equation*} % \begin{macro}{\endequation*} % The {\tt equation*} environment is nearly the same; it only % suppresses the automatic generation of a tag. % \begin{macrocode} \newenvironment{equation*}{% \equation }{% \nonumber\endequation } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macrocode} \newcounter{parentequation}% Counter for ``parent equation''. % \end{macrocode} % % \begin{macrocode} \newenvironment{subequations}[1]{% % \end{macrocode} % Before sending down the `equation' counter to the subordinate % level, add 1 using standard \refstepcounter. % \begin{macrocode} \refstepcounter{equation}% % \end{macrocode} % Define \cn{theparentequation} equivalent to current % \cn{theequation}. \cn{edef} is necessary to expand the current % value of the equation counter. This might in rare cases cause % something to blow up, in which case the user needs to add % \cn{protect}. % \begin{macrocode} \begingroup % conservative approach \let\protect\noexpand \edef\@tempa{\def\noexpand\theparentequation{\theequation}}% \expandafter\endgroup\@tempa \setcounter{parentequation}{\value{equation}}% % And set the equation counter to 0. It will be incremented to 1 (= % "a" or whatever) by \begin{xxx} where "xxx" is the name of an % equation environment such as `equation', `align', or `multline' \setcounter{equation}{0}% \toks@\ifx#11{\arabic}% \else\ifx#1i{\roman}\else\ifx#1I{\Roman}% \else\ifx#1A{\Alph}\else\ifx#1a{\alph}% \else\ifx#1f{\fnsymbol}% \else{}\fi\fi\fi\fi\fi\fi \edef\@tempa{\the\toks@}% \ifx\@tempa\@empty \@badnumtype{#1}\toks@{\alph}\fi \edef\theequation{\noexpand\theparentequation \the\toks@{equation}}% \ignorespaces }{% \setcounter{equation}{\value{parentequation}}% % Prevent an extra space from creeping in after % \end{subequations}: \global\@ignoretrue } % \end{macrocode} % % \begin{macrocode} \def\@badnumtype#1{% \PackageError{amstex}{Unknown number type: `#1'}\@ehc} % \end{macrocode} % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \providecommand{\atchar}{{\normalfont\ttfamily\char64 }} % \section{Handling of active {\atchar} character} % % The \verb|@| character in [amstex] is used as a prefix % in various combinations including \verb|@,|, \verb|@!|, % and \verb|@>>>|. It is given category 13 (active) in % order to be able to select the right action based on % what follows. For consistency, we use a special macro % to define \verb|@| combinations. To give better looking error % messages if an error occurs in an |@| command, the internal name % consists of the command name as it appears to the user, with a % leading space added. % \begin{macro}{\atdef@} % \begin{macrocode} \def\atdef@#1{\expandafter\def\csname\space @\string#1\endcsname} % \end{macrocode} % \end{macro} % % We make the next definition inside a group because we don't want % \verb|@| to remain active for all following code, we only want it % activated the next time \LaTeX{} calls \cn{makeatother}. % \begin{macrocode} \begingroup \catcode`\@=\active \gdef @{\Iat} \endgroup \DeclareRobustCommand{\Iat}{\FN@\at@} % \end{macrocode} % % \verb|\at@| gives an error message (\verb|\at@@@|) if the % following character---stored in \verb|\@let@token| by % \verb|\futurelet|---has an unusual catcode (not 11 or 12). % Otherwise it constructs a \verb|\csname| using that character % (actually it might be a control sequence, also, which will % be converted using \verb|\string|). % \begin{macrocode} \def\at@{\let\next@\at@@ \ifcat\noexpand\@let@token a\else \ifcat\noexpand\@let@token0\else \ifcat\noexpand\@let@token\relax\else \let\@let@token@\at@@@\fi\fi\fi\next@} % \end{macrocode} % If the category of the next token was OK, but this particular % combination was not defined, \verb|\at@@| calls \verb|\at@@@| to % give an error message. Otherwise we construct a suitable csname. % \begin{macrocode} \def\at@@#1{\expandafter \@ifundefined{ @\string#1}% {\DN@{\at@@@#1}}% {\DN@{\csname\space @\string#1\endcsname}}% \next@}% % \end{macrocode} % If we encounter an invalid \verb|@| combination, we assume the % user wanted a real printed \verb|@| and so we typeset one, after % the error message. % \begin{macrocode} \def\at@@@{\PackageError{amstex}{\Invalid@@ @}% {\the\athelp@}% "I'll assume you wanted @@" \char64\relax} % \end{macrocode} % % This is the help message that goes along with the error message % of \verb|\at@@@|. % \begin{macrocode} \newhelp\athelp@ {Only certain combinations beginning with @ make sense to me.^^J% I'll assume you wanted @@ for a printed @.} % \end{macrocode} % % If \verb|@| is active, we must have an alternative way for % printing the character in a document. It would be natural % to use \verb|\@| for this purpose but that is already taken % in \LaTeX{} for something else. So we resort to \verb|@@|. % We define \verb|@@| to expand to \verb|\atchar| (a \cn{chardef}) % rather than a % category 12 or 11 \verb|@| character, so that it will be robust % if passed between files, e.g. to and from the .toc file. The % extra braces ensure that a following space is not lost if this % expansion gets passed to (e.g.) the toc file. % \begin{macrocode} \atdef@ @{{\atchar}}% to define @@ \chardef\atchar=64 % \end{macrocode} % And we must redefine \cs{makeatother} to set the category code of % \verb+@+ to active instead of other. Furthermore we must do some % surgery on \cs{@currnamestack} to make the catcode of \verb'@' % revert to active when \LaTeX{} once again reaches top level. We % can't just put \cs{makeatother} at the end of amstex.sty because % the \LaTeX{} package loading mechanisms will immediately override % with the previous value of \verb'@''s catcode. Not to mention that % the amstex package might be loaded inside a document class or % another package. When \LaTeX{} gets an interface for active % characters this can be fixed. :-) % \begin{macrocode} \def\makeatother{\catcode64=\active} \def\@tempa#1#2#3#4#5#6{% {#1}{#2}\ifnum0#6=0{13}\@xp\@gobblefour \else{#3}\fi\@tempa{#4}{#5}{#6}}% \xdef\@currnamestack{\@xp\@tempa\@currnamestack{}{}{0}} % \end{macrocode} % % \begin{macro}{\@sanitize} % We have to add \verb+\@+ to the list of special characters % in \verb+\@sanitize+ otherwise \verb+\index+ and the like % will run amok. % \begin{macrocode} {\def\@makeother{\noexpand\@makeother\noexpand} \xdef\@sanitize{\@sanitize\@makeother\@}} % \end{macrocode} % \end{macro} % % \begin{macro}{\dospecials} % We have to add \verb+\@+ to the list of special characters % in \verb+\dospecials+ otherwise \verb+\verb+ or the verbatim % environments will run amok. % \begin{macrocode} {\def\do{\noexpand\do\noexpand} \xdef\dospecials{\dospecials\do\@}} % \end{macrocode} % \end{macro} % % The \verb+@.+ macro was moved to the {\tt amscd} style file. % % The non-math alternatives in the following definitions are % superseded by \LaTeX's \verb+\@+ command and were therefore % removed. % \begin{macrocode} \atdef@,{\ifmmode\mskip.1\thinmuskip\else \nonmatherr@{@,}\fi} \atdef@!{\RIfM@\mskip-.1\thinmuskip\else \nonmatherr@{@!}\fi} % \end{macrocode} % The arrows \verb+@>>>+ and \verb+@<<<+ will be redefined by {\tt % amscd.sty} if that option is used. These definitions here are % slightly reduced by removal of CD-specific code. Therefore we % must skip them if {\tt amscd} precedes {\tt amstex} in the % documentstyle options list. % % Note that \verb|\rightarrowfill@| and \verb|\leftarrowfill@| % use smashed minus signs to prevent superscripts above the % arrows from being too high. % \begin{macrocode} \@ifpackageloaded{amscd}{% % amscd loaded earlier: do nothing }{% % amscd not loaded: OK to define @>>> and @<<< \atdef@>#1>#2>{% \global\bigaw@\minaw@ \setboxz@h{$\m@th\scriptstyle\;{#1}\;\;$}% \ifdim\wdz@>\bigaw@ \global\bigaw@\wdz@ \fi % \end{macrocode} % If \verb|#2| is empty we can save some work. % \begin{macrocode} \@ifnotempty{#2}{\setbox\@ne\hbox{$\m@th\scriptstyle\;{#2}\;\;$}% \ifdim\wd\@ne>\bigaw@ \global\bigaw@\wd\@ne \fi}% \mathrel{\mathop{\hbox to\bigaw@{\rightarrowfill@\displaystyle}}% \limits^{#1}\@ifnotempty{#2}{_{#2}}}% }% end of @>>> % \atdef@<#1<#2<{% \global\bigaw@\minaw@ \setboxz@h{$\m@th\scriptstyle\;\;{#1}\;$}% \ifdim\wdz@>\bigaw@ \global\bigaw@\wdz@ \fi \@ifnotempty{#2}{\setbox\@ne\hbox{$\m@th\scriptstyle\;\;{#2}\;$}% \ifdim\wd\@ne>\bigaw@ \global\bigaw@\wd\@ne \fi}% \mathrel{\mathop{\hbox to\bigaw@{\leftarrowfill@\displaystyle}}% \limits^{#1}\@ifnotempty{#2}{_{#2}}}% }% end of @<<< }% end of @ifpackageloaded % \end{macrocode} % % We use \verb|\@ifundefined| tests here for \verb|\minaw@| and % \verb|\bigaw@| so that they will not be reallocated if {\tt % amscd} precedes {\tt amstex} in a documentstyle options list. % \begin{macrocode} \@ifundefined{minaw@}{\newdimen\minaw@}{} \minaw@11.111pt \@ifundefined{bigaw@}{\newdimen\bigaw@}{} % \end{macrocode} % % Non-breaking hyphen command of amstex. % Setting the hyphen in a box and then unboxing it means that the % normal penalty will not be added after it---and if the penalty is % not there a break will not be taken (unless an explicit penalty % or glue follows, thus the final \cw{nobreak}). To begin the % recursion we make \cw{next} = hyphen; after that \cw{next} % will be equal or not equal to hyphen depending on the result of % the \cw{futurelet} in \cw{FN@}. % \begin{macrocode} \atdef@-{\let\next-%% \DN@{\ifx\next-%% \def\next-{\setbox\z@\hbox{-}\unhbox\z@\FN@\next@}%% \expandafter\next \else\nobreak\fi}%% \next@-}%% % \end{macrocode} % % This root stuff needs syntax work and implementation work. Surely % something more compact can be done?? [mjd,5-Sep-1994] % \begin{macrocode} \def\leftroot{\PackageError{amstex}{\Invalid@@\leftroot}\@eha} \def\uproot{\PackageError{amstex}{\Invalid@@\uproot}\@eha} \newcount\uproot@ \newcount\leftroot@ \def\root{\relaxnext@ \DN@{\ifx\@let@token\uproot\let\next@\nextii@\else \ifx\@let@token\leftroot\let\next@\nextiii@\else \let\next@\plainroot@\fi\fi\next@}% \def\nextii@\uproot##1{\uproot@##1\relax\FN@\nextiv@}% \def\nextiv@{\ifx\@let@token\@sptoken\DN@. {\FN@\nextv@}\else \DN@.{\FN@\nextv@}\fi\next@.}% \def\nextv@{\ifx\@let@token\leftroot\let\next@\nextvi@\else \let\next@\plainroot@\fi\next@}% \def\nextvi@\leftroot##1{\leftroot@##1\relax\plainroot@}% \def\nextiii@\leftroot##1{\leftroot@##1\relax\FN@\nextvii@}% \def\nextvii@{\ifx\@let@token\@sptoken \DN@. {\FN@\nextviii@}\else \DN@.{\FN@\nextviii@}\fi\next@.}% \def\nextviii@{\ifx\@let@token\uproot\let\next@\nextix@\else \let\next@\plainroot@\fi\next@}% \def\nextix@\uproot##1{\uproot@##1\relax\plainroot@}% \bgroup\uproot@\z@\leftroot@\z@\FN@\next@} \def\plainroot@#1\of#2{\setbox\rootbox\hbox{% $\m@th\scriptscriptstyle{#1}$}% \mathchoice{\r@@t\displaystyle{#2}}{\r@@t\textstyle{#2}} {\r@@t\scriptstyle{#2}}{\r@@t\scriptscriptstyle{#2}}\egroup} \def\r@@t#1#2{\setboxz@h{$\m@th#1\@@sqrt{#2}$}% \dimen@\ht\z@\advance\dimen@-\dp\z@ \setbox\@ne\hbox{$\m@th#1\mskip\uproot@ mu$}% \advance\dimen@ by1.667\wd\@ne \mkern-\leftroot@ mu\mkern5mu\raise.6\dimen@\copy\rootbox \mkern-10mu\mkern\leftroot@ mu\boxz@} % \end{macrocode} % % The usual \cs{endinput} to ensure that random garbage at the end of % the file doesn't get copied by \fn{docstrip}. % \begin{macrocode} \endinput % \end{macrocode} % % \CheckSum{3777} % \Finale