
\def\fileversion{v2.0d}
\def\filedate{90/08/20}
\def\docdate {90/08/20}

%% \CheckSum{681}
%% \CharacterTable
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%   Digits        \0\1\2\3\4\5\6\7\8\9
%%   Exclamation   \!     Double quote  \"     Hash (number) \#
%%   Dollar        \$     Percent       \%     Ampersand     \&
%%   Acute accent  \'     Left paren    \(     Right paren   \)
%%   Asterisk      \*     Plus          \+     Comma         \,
%%   Minus         \-     Point         \.     Solidus       \/
%%   Colon         \:     Semicolon     \;     Less than     \<
%%   Equals        \=     Greater than  \>     Question mark \?
%%   Commercial at \@     Left bracket  \[     Backslash     \\
%%   Right bracket \]     Circumflex    \^     Underscore    \_
%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%%   Right brace   \}     Tilde         \~}
%%
%
%\iffalse   % this is a METACOMMENT !
%
%
%
% Style-option `array' to use with LaTeX v2.09
% Copyright (C) 1989 Frank Mittelbach, 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 name it something other than
%     array.doc.
% This restriction helps ensure that all styles developed at Mainz
% are identical.
%
% Please send bug reports to:
%
%                          F. Mittelbach
%                          Eichenweg 29
%                          D-6500 Mainz
%                          Federal Republic of Germany
%                  Email:  <PZF5HZ@DRUEDS2.BITNET> 
%
% \fi
%
% \changes{v1.0b}{87/06/04}{`@classi (faster),
%                        `@classvi (new)   A in preamble means
%                                         \&\& in `halign.}
%
% \changes{v1.1a}{87/07/05}{New concept:
%                        preamblechar: c,l,r,C,L,R,A,p,t,|,@,!}
% \changes{v1.1b}{87/09/21}{Again p like orginal \LaTeX{} and z for
%                        centered `parbox.}
%
% \changes{v1.2a}{87/09/27}{Completely new implementation.}
% \changes{v1.2b}{87/10/06}{| does no longer generate space at start or
%                        end of the preamble. Otherwise `hline is too
%                        long (exactly like Lamport's implementation).
%                        Enlarged `@arstrutbox by 1pt (Test-Impl)
%                         with dimen `@strutheight.}
% \changes{v1.2c}{87/10/22}{New dimen parameter `extrarowheight
%                        (default: 0pt).
%                        Enlarged `@arstrutbox by `extrarowheight.
%                        Thus you may avoid large characters to
%                        overprint a `hline.
%                        Introduced `m@th in `@array to allow non-zero
%                        values of `mathsurround.}
% \changes{v1.2d}{87/11/02}{Completed the documentation.}
% \changes{v1.2e}{87/11/03}{Bug fixed: A at start of preamble resulted
%                        in an error since `@mkpream generated
%                        `@arstrut \& ... as a preamble.}
% \changes{v1.2f}{87/11/09}{`@testpach documented.}
%
% \changes{v1.3a}{87/11/11}{Again a new implementation, with a new
%                        concept (cf. the documentation).}
% \changes{v1.3b}{88/03/17}{`@decl expands now into `@empty, i.e. it
%                        disappears when the preamble is generated,
%                        except when the user specifies A{...} or
%                        B{...}.}
%
% \changes{v1.4a}{88/03/18}{Test implementation of use of token
%                        registers in order to do without `protect.}
% \changes{v1.4b}{88/03/19}{Changed erroneous class numbers:
%                        5 -> 6
%                        6 -> 7
%                        7 -> 5
%                        Correesponding changes in the macros.}
% \changes{v1.4c}{88/03/19}{Everything except p,z now works with token
%                        registers.}
%
% \changes{v1.9a}{88/03/20}{Last (so I hope) major change:
%                        1) Options B,A now called >,<. Looks much
%                           better readable to me, e.g.,
%                           l>{\tt}c>{$}c<{$}. These options now point
%                           to the column they modify.
%                        2) `protect is no longer necessary. But
%                           still the macro `@expast needs top be
%                           modified. `multicolumn still does not work.
%                           (Therefore version number 1.9, version 2.0
%                           hopefully will be ready for distribution.)}
% \changes{v1.9b}{88/04/29}{inserted missing `fi in `@testpach.
%                        Corrected \LaTeX bug in `@tfor.}
% \changes{v1.9c}{88/05/07}{Re-introduced `@endpbox.
%                        `multicolumn now works! Version number still
%                        1.9 since the documentation is still not
%                        finished.
%                        Numerous small improvements in the code:
%                        1) `def`the@toks{`the ...} remaining only in 
%                           `@mkpream.
%                        2) Removed `@classiii and replaced by
%                           `save@decl.
%                        3) `insert@column contains only `@tempcnta and
%                           `count@ counters.
%                        4) `@@startpbox and `@@endpbox now totally
%                           obsolete.}
% \changes{v1.9d}{88/05/10}{Replaced `number by `the where the `toks
%                        registers' contents are used.}
% \changes{v1.9e}{88/05/11}{Re-introduced `@xargarraycr and
%                        `@yargarraycr, since `endtemplate seems to
%                        be `outer.}
% \changes{v1.9f}{88/05/20}{Small changes finally carried out:
%                        1) `par=`@empty.
%                        2) {..ifnum0=`}...  $\to$ `bgroup and
%                           analoguously `egroup.}
% \changes{v1.9g}{88/02/24}{Inserted again {..ifnum0=`}..,
%                        c.f. Appendix D of the \TeX{}book.}
% \changes{v1.9h}{88/06/28}{No longer necessary to read in the file
%                        twice.}
% \changes{v1.9i}{88/06/28}{Corrected typo in german version.}
% \changes{v1.9j}{88/11/23}{In a `r' column an extra `kern`z@ is
%                        needed. Otherwise the `hfil on the left side
%                        will be removed by the `unskip in
%                        `insert@column if the entry is empty.
%                        This gave problems in rather obscure cases
%                        together with `multicolumn.}
% \changes{v1.9k}{88/06/28}{Corrected typo in german version.}
% \changes{v1.9k}{89/01/16}{`begin{Macro} changed to `begin{macro} in
%                        documentation.}
%
% \changes{v2.0a}{89/05/12}{{\tt\protect\bslash @thetoks} changed to
%                          {\tt\protect\bslash the@toks}.}
% \changes{v2.0a}{89/05/12}{source changed to reflect new doc.sty
%                          conventions.}
% \changes{v2.0a}{89/05/12}{t option renamed to p to be compatible to
%                        the original.}
% \changes{v2.0a}{89/05/12}{File renamed from arraye.sty to array.sty.}
% \changes{v2.0b}{89/05/17}{Three forgotten end macro added.}
% \changes{v2.0b}{89/05/17}{All lines shortened to 72 or less.}
%
% \DoNotIndex{\@depth,\@ehc,\@fortmp,\@height,\@ifnextchar,\@ifstar}
% \DoNotIndex{\@ifundefined,\@latexerr,\@ne,\@nil,\@tempa,\@tempb}
% \DoNotIndex{\@tempcnta,\@tempd,\@tempdima,\@whilenum,\@width,\\}
% \DoNotIndex{\@tforloop}
% \DoNotIndex{\advance}
% \DoNotIndex{\baselineskip,\begingroup,\bgroup}
% \DoNotIndex{\cr,\crcr,\csname}
% \DoNotIndex{\def,\do,\docdate,\dp}
% \DoNotIndex{\edef,\egroup,\else,\endcsname,\endinput,\expandafter}
% \DoNotIndex{\fi,\filedate,\fileversion}
% \DoNotIndex{\gdef}
% \DoNotIndex{\hbox,\hfil,\hsize,\hskip,\ht}
% \DoNotIndex{\if,\ifcase,\ifdim,\ifnum,\ifx,\ignorespaces}
% \DoNotIndex{\kern}
% \DoNotIndex{\leavevmode,\let,\lineskip}
% \DoNotIndex{\m@ne,\multispan}
% \DoNotIndex{\newcount,\newdimen,\noalign}
% \DoNotIndex{\or}
% \DoNotIndex{\relax}
% \DoNotIndex{\setbox,\space,\strutbox}
% \DoNotIndex{\tabskip,\thr@@,\the,\toks,\toks@,\tw@,\typeout}
% \DoNotIndex{\unhcopy,\unskip}
% \DoNotIndex{\vbox,\vcenter,\vline,\vrule,\vtop,\vskip}
% \DoNotIndex{\xdef}
% \DoNotIndex{\z@}
%
%
% \title{A new implementation of \LaTeX's {\sf tabular}
%        and {\sf array} environment\thanks{This file
%        has version number \fileversion, last
%        revised \filedate, documentation dated \docdate.}}
% \author{Frank Mittelbach\\
%         Eichenweg 29\\
%         D-6500 Mainz \\
%         Federal Republic of Germany\\
%         Bitnet:  $\langle$\tt PZF5HZ@DRUEDS2$\rangle$} 
%
% \date{Printed \today}
%
% \maketitle
%
% \begin{abstract}
% This article describes a new implementation of the \LaTeX\
% {\sf array}-- and {\sf tabular}--environments. The special merits of
% this
% implementation are further options to format columns and the fact
% that fragile \LaTeX--commands don't have to be \verb+\protect+'ed any
% more within those environments.
%
% At the same time it shows a new --- and in our opinion sensible ---
% way of documenting \TeX\--macros: This article \underline{is the
% style--file} that is to be used. All we need in addition to it is a
% short \TeX--program which visualizes the comments and puts the
% definitions in verbatim mode.
% \end{abstract}
%
%
%
% \section{Introduction}
%
% This new implementation of the
% {\sf array}-- and {\sf tabular}--environments is part of a larger
% project
% in which we are trying to improve the \LaTeX\--code in some aspects
% and to make \LaTeX\ even
% easier to handle. At the moment we are experimenting with a version
% were all commands are automatically robust.
%
% The reader should be familiar with the general structure of the
% environments
% mentioned above. Further information can be found in {\sc Lamport}
% \cite{bk:lamport}. The additional options which can be used in the
% preamble as well as those which now have a slightly different meaning
% are described in table~\ref{tab:opt}.
%
% Additionally we introduce a new
% parameter called \verb+\extrarowheight+. If it takes a positive
% length, the value of the parameter is added to the normal height of
% every row of the table, while
% the depth will remain the same. This is important for tables
% with horizontal lines because those lines normally touch the
% capital letters.
% For example, we used \verb+\setlength{\extrarowheight}{1pt}+
% in table~\ref{tab:opt} below.
%
% \begin{table}[b]
% \begin{center}
%    \setlength{\extrarowheight}{1pt}
%    \begin{tabular}{|>{\tt}c|m{9cm}|}
%       \hline
%       m\{width\}    &  Defines a column of width {\tt width}.
%                        Every entry will be centered in proportion to
%                        the rest of the line. It is somewhat like
%                        \verb+\parbox{width}+. \\
%       \hline
%       p\{width\}    &  Equivalent to \verb+\parbox[t]{width}+. \\
%       \hline
%       b\{width\}    &  Coincides with \verb+\parbox[b]{width}+. \\
%       \hline
%       >\{decl.\}    &  Can be used before an {\tt l}, {\tt r},
%                        {\tt c}, {\tt p}, {\tt m} or a {\tt b}
%                        option. It inserts
%                        {\tt decl.} directly in front of the entry of
%                        the column.   \\
%       \hline
%       <\{decl.\}    &  Can be used after an {\tt l}, {\tt r},
%                        {\tt c}, \verb+p{..}+, \verb+t{..}+ or a
%                        \verb+b{..}+ option.
%                        It inserts {\tt decl.} right after the entry
%                        of the column.   \\
%       \hline
%       |             &  Inserts a vertical line. The distance between
%                        two columns will be enlarged by the width of
%                        the line
%                        in contrast to the original definition of
%                        \LaTeX.  \\
%       \hline
%       !\{decl.\}    &  Can be used anywhere and corresponds with the
%                        {\tt |} option. The difference is that
%                        {\tt decl.} is inserted instead of a vertical
%                        line, so this option doesn't suppress the
%                        normally inserted space between columns in
%                        contrast to \verb+@{...}+.\\
%       \hline
%    \end{tabular}
% \end{center}
% \caption{The new preamble options.} \label{tab:opt}
% \end{table}
%
%
% We will discuss a few examples using the new preamble options before
% dealing with the implementation.
% \begin{itemize}
%    \item
%       If you want to use a special font (for example \verb+\bf+) in a
%       flushed left column, this can be done with \verb+>{\bf}l+. You
%       do not have to begin every entry of the column with  \verb+\bf+
%       any more.
%    \item
%       In columns which have been generated with {\tt p}, {\tt m}
%       or {\tt b}, the default value of \verb+\parindent+ is
%       {\sf 0pt}.
%       This can be changed with
%       \verb+>{\setlength{\parindent}{1cm}}p+.
%    \item
%       The {\tt <}--option was originally developed for the following
%       application:
%       \verb+>{$}c<{$}+ generates a column in math mode in a
%       {\sf tabular}--environment. If you use this type of a preamble
%       in an
%       {\sf array}--environment, you get a column in LR mode because
%       the additional \$'s cancel the existing \$'s.
%    \item
%       One can also think of more complex applications. A problem
%       which has
%       been mentioned several times in \TeX{}hax can be solved with
%       \verb+>{\centerdots}c+\linebreak[0]\verb+<{\endcenterdots}+.
%       To center decimals at their
%       decimal points you (only?) have to define the following macros:
%       \begin{verbatim}
%{\catcode`\.=\active\gdef.{\egroup\setbox2=\hbox\bgroup}}
%\def\centerdots{\catcode`\.=\active\setbox0=\hbox\bgroup}
%\def\endcenterdots{\egroup\ifvoid2 \setbox2=\hbox{0}\fi
%   \ifdim \wd0>\wd2 \setbox2=\hbox to\wd0{\unhbox2\hfill}\else
%     \setbox0=\hbox to\wd2{\hfill\unhbox0}\fi
%   \catcode`\.=12 \box0.\box2}
%\end{verbatim}
%    \item
%       Using \verb+c!{\hspace{1cm}}c+ you get space between two
%       columns which is enlarged by one centimeter, while
%       \verb+c@{\hspace{1cm}}c+ gives you exactly one centimeter
%       space between two columns.
% \end{itemize}
% These examples should be sufficient to demonstrate the use of the new
% preamble options.
%
% \StopEventually{
%
% \PrintIndex
%
% \begin{thebibliography}{1}
%    \bibitem{bk:knuth}  {\sc D. E. Knuth}.
%       \newblock  The \TeX{}book (Computers \& Typesetting Volume A).
%       \newblock
%       Addison-Wesley, Reading, Massachusetts, 1986.
%    \bibitem{cd:knuth}  {\sc D. E. Knuth}.
%       \newblock
%       The \TeX{}program (Computers \& Typesetting Volume B).
%       \newblock
%       Addison-Wesley, Reading, Massachusetts, 1986.
%    \bibitem{bk:lamport} {\sc L. Lamport}.
%       \newblock
%       \LaTeX\ -- A Document Preparation System.
%       \newblock
%       Addison-Wesley, Reading, Massachusetts, 1986.
%    \bibitem{cd:lamport} {\sc L. Lamport}.
%       \newblock
%       {\tt latex.tex}, Version 2.09 of $\left\langle
%                                            \mbox{15. Sept. 87}
%                                         \right\rangle  $.
% \end{thebibliography}
%
% \makesignature
%
% }   ^^A  end of \StopEventually
%
%
% It is obvious that those environments will consist mainly of an
% \verb+\halign+, because \TeX\ typesets tables using this primitive.
% That is why we will now take a look at the algorithm which determines
% a preamble for a \verb+\halign+ starting with a given user preamble
% using the options mentioned above.
%
%
% \section{The construction of the preamble}
%
% First we will define the current version of this file:
%    \begin{macrocode}
\@ifundefined{d@llar}{}{\endinput}
\typeout{Style-Option: `array' \fileversion 
         \space\space <\filedate> (F.M.)}
\typeout{English documentation dated \space <\docdate> (F.M.)}
%    \end{macrocode}
%
% The most interesting macros of this implementation are without doubt
% those
% which are responsible for the construction of the preamble
% for the \verb+\halign+. The underlying algorithm was developed by
% {\sc Lamport} (resp.\ {\sc Knuth}, see texhax V87\#??), and it has
% been
% extended and improved.
%
% The user preamble will be read {\sf token} by {\sf token}.
% A {\sf token} is a single character like {\tt c} or a block enclosed
% in
% \verb+{...}+. For example the preamble of
% \verb+\begin{tabular}+\linebreak[0]\verb+{lc||c@{\hspace{1cm}}}+
% consists of the {\sf token}
% {\tt l}, {\tt c}, {\tt |}, {\tt |}, {\tt @} and \verb+\hspace{1cm}+.
%
% The currently used {\sf token} and the one, used before, are needed
% to decide on how the construction of the preamble has to be
% continued.
% In the example mentioned above the {\tt l} causes the preamble
% to begin with \verb+\hskip\tabcolsep+. Furthermore
% \verb+# \hfil+ would be appended to define a flush left column.
% The next {\sf token} is a {\tt c}. Because it was preceded by an
% {\tt l} it generates a new column. This is done with
% \verb+\hskip \tabcolsep & \hskip \tabcolsep+. The column which is to
% be centered will be appended with \verb+\hfil # \hfil+.
% The {\sf token} {\tt |} would then add a space of
% \verb+\hskip \tabcolsep+
% and a vertical line because the last
% {\sf tokens} was a {\tt c}.
% The following {\sf token} {\tt |} would only add a space
% \verb+\hskip \doublerulesep+ because it was preceded by the
% {\sf token} {\tt |}. We will not discuss our example further but
%  rather take a look at the general case of constructing preambles.
%
% The example shows that the desired preamble for the
% \verb+\halign+ can be constructed as soon as the action of all
% combinations
% of the preamble {\sf tokens} are specified. There are 18 such
% {\sf tokens}
% so we have $19 \cdot 18 = 342$ combinations if we count the
% beginning of
% the preamble as a special {\sf token}. Fortunately, there are many
% combinations which generate the same spaces, so we can define
% {\sf token} classes. We will identify a
% {\sf token} within a class with a number, so we can insert the
% formatting (for example of a column).
% Table~\ref{tab:Klassen} lists all {\sf token} classes and
% their corresponding numbers.
% \begin{table}[ht]
% \begin{center}
%    \begin{tabular}[t]{>{\tt}ccc}
%       {\sf token} & \verb+\@chclass+ & \verb+\@chnum+ \\[2mm]
%       c   & 0  & 0 \\
%       l   & 0  & 1 \\
%       r   & 0  & 2 \\
%       p-arg    & 0  & 3 \\
%       t-arg    & 0  & 4 \\
%       b-arg    & 0  & 5 \\
%       |   & 1  & 0 \\
%       !-arg    & 1  & 1 \\
%       <-arg    & 2  & --- \\
%       >-arg    & 3  & ---
%    \end{tabular}
%    \kern3mm \vrule \kern3mm%
%    \begin{tabular}[t]{>{\tt}ccc}
%       {\sf token} & \verb+\@chclass+ & \verb+\@chnum+ \\[2mm]
%       Start    & 4  & --- \\
%       @-arg    & 5  & --- \\
%       !   & 6  & --- \\
%       @   & 7  & --- \\
%       <   & 8  & --- \\
%       >   & 9  & --- \\
%       p   & 10 & 3 \\
%       t   & 10 & 4 \\
%       b   & 10 & 5
%    \end{tabular}
% \end{center}
% \caption{Classes of preamble {\sf tokens}}
% \label{tab:Klassen}
% \end{table}
%
%
% \begin{macro}{\@chclass}
% \begin{macro}{\@chnum}
% \begin{macro}{\@lastchclass}
%    The class and the number of the current {\sf token} are saved in
%    the
%    {\sf count} registers \verb+\@chclass+
%    and \verb+\@chnum+, while the class of the previous
%    {\sf token} is stored in the
%    {\sf count} register \verb+\@lastchclass+.
%    All of the mentioned registers are already allocated in
%    {\tt latex.tex},
%    which is the reason why the following three lines of code are
%    commented out.
%    Later throughout the text I will not mention it again explicitely
%    whenever I use a \verb+%+ sign. These parts are already defined in
%    {\tt latex.tex}.
%    \begin{macrocode}
% \newcount \@chclass
% \newcount \@chnum
% \newcount \@lastchclass
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\@addtopreamble}
%    We will save the already constructed preamble for
%    the \verb+\halign+
%    in the global macro \verb+\@preamble+. This will then be
%     enlarged with
%    the command \verb+\@addtopreamble+.
%    \begin{macrocode}
\def\@addtopreamble#1{\xdef\@preamble{\@preamble #1}}
%    \end{macrocode}
% \end{macro}
%
%
%
%
%
% \subsection{The character class of a {\sf token}}
%
% \begin{macro}{\@testpach}
% \changes{v2.0a}{89/05/12}{p option renamed to m (middle).}
% \changes{v2.0a}{89/05/12}{t option renamed to p to be compatible to
%                         the original.}
%    With the help of \verb+\@lastchclass+ we can now define a macro
%    which determines the class and the number of a given preamble
%    {\sf token}
%    and assigns them to the registers
%    \verb+\@chclass+ and \verb+\@chnum+.
%    \begin{macrocode}
\def\@testpach#1{\@chclass
%    \end{macrocode}
%    First we deal with the cases in which the {\sf token}
%    (\verb+#1+) is the argument of {\tt !}, {\tt @}, {\tt <} or
%    {\tt >}. We can see this from the value of \verb+\@lastchclass+:
%    \begin{macrocode}
 \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
  \ifnum \@lastchclass=7 5 \else
   \ifnum \@lastchclass=8 \tw@ \else
    \ifnum \@lastchclass=9 \thr@@
%    \end{macrocode}
%    Otherwise we will assume that the {\sf token} belongs to the
%    class $0$
%    and assign the corresponding number to \verb+\@chnum+ if our
%    assumption is correct.
%    \begin{macrocode}
   \else \z@
%    \end{macrocode}
%    If the last {\sf token} was a {\tt p}, {\tt m} or a {\tt b},
%    \verb+\@chnum+ already has the right value. This is the reason for
%    the
%    somewhat curious choice of the {\sf token} numbers in class $10$.
%    \begin{macrocode}
   \ifnum \@lastchclass = 10 \else
%    \end{macrocode}
%    Otherwise we will check if \verb+#1+ is either a {\tt c}, {\tt l}
%    or an {\tt r}.
%    \begin{macrocode}
   \@chnum
   \if #1c\z@ \else
    \if #1l\@ne \else
     \if #1r\tw@ \else
%    \end{macrocode}
%    If it is a different {\sf token}, we know that the class was
%    not $0$. We assign the
%    value $0$ to \verb+\@chnum+ because this value is needed for the
%    {\tt |}--{\sf token}. Now we must check the remaining classes.
%    Note that the value of \verb+\@chnum+ is insignificant here for
%    most classes.
%    \begin{macrocode}
   \z@ \@chclass
   \if#1|\@ne \else
    \if #1!6 \else
     \if #1@7 \else
      \if #1<8 \else
       \if #1>9 \else
%    \end{macrocode}
%    The remaining permitted {\sf tokens} are {\tt p}, {\tt m} and
%    {\tt b} (class $10$).
%    \begin{macrocode}
  10
  \@chnum
  \if #1m\thr@@\else
   \if #1p4 \else
    \if #1b5 \else
%    \end{macrocode}
%    Now the only remaining possibility is a forbidden {\sf token},
%    so we choose class $0$ and number $0$ and give an error message.
%    Then we finish the macro by closing all \verb+\if+'s.
%    \begin{macrocode}
   \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
   \fi \fi  \fi  \fi  \fi  \fi  \fi \fi \fi \fi \fi \fi}
%    \end{macrocode}
% \end{macro}
%
%
%
%
%
% \subsection{Multiple columns ($*$--form)}
%
% \begin{macro}{\@xexpast}
% \begin{macro}{\the@toks}
% \begin{macro}{\the@toksz}
%    \label{@xexpast}
%    Now we discuss the macro that deletes all forms of type
%    \verb+*{+{\it N\/}\verb+}{+{\it String\/}\verb+}+ from a user
%    preamble and replaces them with {\it N} copies of {\it String}.
%    Nested $*$--expressions are dealt with correctly, that means
%    $*$--expressions are not substituted if they are in explicit
%    braces, as in \verb+@{*}+.
%
%    This macro is called via
%    \verb+\@xexpast+$\left\langle
%                          \it preamble
%                     \right\rangle$\verb+*0x\@@+.
%    The $*$--expression \verb+*0x+ is being used to terminate the
%    recursion,
%    as we shall see later, and \verb+\@@+ serves as an argument
%    delimiter. \verb+\@xexpast+ has four arguments. The first
%    one is the part of the
%    user preamble before the first $*$--expression while the second
%    and third ones are the arguments of the first $*$--expression
%    (that is {\it N} and {\it String} in the notation mentioned
%    above).
%    The fourth argument is the rest of the preamble.
%    \begin{macrocode}
\def\@xexpast#1*#2#3#4\@@{%
%    \end{macrocode}
%    The number of copies of {\it String} (\verb+#2+) that are to be
%    produced will be saved in a {\sf count} register.
%    \begin{macrocode}
   \@tempcnta #2
%    \end{macrocode}
%    We save the part of the preamble which does not
%    contain a $*$--form (\verb+#1+)
%    in a \PlainTeX\ {\sf token} register.
%    We also save {\it String} (\verb+#3+) using a \LaTeX\
%    {\sf token} register.
%    \begin{macrocode}
   \toks@={#1}\@temptokena={#3}%
%    \end{macrocode}
%    Now we have to use a little trick to produce {\it N} copies of
%    {\it String}.
%    We could try \verb+\def\@tempa{#1}+ and then
%    {\it N} times \verb+\edef\@tempa{\@tempa#3}+. This would have the
%    undesired effect that all macros within \verb+#1+ and \verb+#3+
%    would be expanded, although, for example, constructions like
%    \verb+@{..}+ are not supposed to be changed.
%    That is why we \verb+\let+ two control sequences to
%    be equivalent to \verb+\relax+.
%    \begin{macrocode}
   \let\the@toksz\relax \let\the@toks\relax
%    \end{macrocode}
%    Then we ensure that \verb+\@tempa+ contains
%    \verb+{\the@toksz\the@toks...\the@toks}+ (the macro
%    \verb+\the@toks+ exactly {\it N\/} times) as substitution text.
%    \begin{macrocode}
   \def\@tempa{\the@toksz}%
   \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do
     {\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}%
%    \end{macrocode}
%    If {\it N\/} was greater than zero we prepare for another call of
%    \verb+\@xexpast+. Otherwise we assume we have reached the end of
%    the user preamble, because we had appended
%    \verb+*0x\@@+ when we first called
%     \verb+\@xexpast+.
%    In other words: if the user inserts
%    \verb+*{0}{..}+ in his preamble, \LaTeX\ ignores the rest of it.
%    \begin{macrocode}
       \let \@tempb \@xexpast \else
       \let \@tempb \@xexnoop \fi
%    \end{macrocode}
%    Now we will make sure that the part of the user preamble, which
%    was already dealt with, will be saved again in \verb+\@tempa+.
%    \begin{macrocode}
   \def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}%
   \edef\@tempa{\@tempa}%
%    \end{macrocode}
%    We have now evaluated the first $*$--expression, and the user
%    preamble up to this point
%    is saved in \verb+\@tempa+. We will put the contents of
%    \verb+\@tempa+ and the rest of the user preamble together and work
%    on the result with \verb+\@tempb+. This macro either corresponds
%    to \verb+\@xexpast+, so that the next
%    $*$--expression is handled, or to the macro \verb+\@xexnoop+,
%    which only ends the recursion by deleting its argument.
%    \begin{macrocode}
   \expandafter \@tempb \@tempa #4\@@}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@xexnoop}
%    So the first big problem is solved. Now it is easy to
%    specify \verb+\@xexnoop+.
%    Its argument is delimited by \verb+\@@+ and it simply expands to
%    nothing.
%    \begin{macrocode}
%  \def\@xexnoop#1\@@{}
%    \end{macrocode}
% \end{macro}
%
%
%
%
% \section{The insertion of declarations
%           ({\tt >}, {\tt <}, {\tt !}, {\tt @})}
%
%
% The preamble will be enlarged with the help of \verb+\xdef+, but the
% arguments of {\tt >}, {\tt <},~{\tt !}\ and {\tt @} are not supposed
% to be expanded during the construction (we want an implementation
% that doesn't need a \verb+\protect+). So we have to find a way to
% inhibit the expansion of those arguments.
%
% We will solve this problen with {\sf token} registers. We need one
% register for every {\tt !}\ and {\tt @}, while we need two for every
% {\tt c}, {\tt l}, {\tt r}, {\tt m}, {\tt p} or {\tt b}. This limits
% the number of columns of a table because there are only 256
% {\sf token} registers. But then, who needs tables with more
% than 100 columns?
%
% One could also find a solution which only needs two or three
% {\sf token} registers by proceeding similarly as in the macro
% \verb+\@xexpast+ (see page \pageref{@xexpast}). The advantage of our
% approach is the fact that we avoid some of the problems that arise
% with the other method\footnote{Maybe there are also historical
%  reasons.}.
%
% So how do we proceed? Let us assume that we had \verb+!{foo}+ in the
% user preamble and say we saved {\tt foo} in
% {\sf token} register $5$. Then we call
% \verb+\@addtopreamble{\the@toks5}+ where
% \verb+\the@toks+ is defined in a way that it does not expand
% (for example it could be equivalent to \verb+\relax+). Every
% following call
% of \verb+\@addtopreamble+ leaves \verb+\the@toks5+ unchanged in
% \verb+\@preamble+. If the construction of the preamble is completed
% we change the definition of \verb+\the@toks+ to
% \verb+\the\toks+ and expand \verb+\@preamble+ for the last time.
% During this process all parts of the form
%    \verb+\the@toks+$\left\langle
%                        \it Number
%                     \right\rangle  $
% will be substituted by the contents of the respective {\sf token}
% registers.
%
% As we can see from this informal discussion the construction of the
% preamble has to take place within a group, so that the
% {\sf token} registers we use will be freed later on. For that reason
% we keep all assignments to \verb+\@preamble+ global; therefore the
% replacement text of this macro will remain the same after we leave
% the group.
%
% \begin{macro}{\count@}
%    We further need a {\sf count} register to remember which
%    {\sf token} register is to be used next. This will be initialized
%    with $-1$ if we want to begin with the
%    {\sf token} register $0$. We use the
%    \PlainTeX\ scratch register \verb+\count@+ because everything
%    takes place locally. All we have to do is insert
%    \verb+\the@toks+ \verb+\the+ \verb+\count@+ into the preamble.
%    \verb+\the@toks+ will remain unchanged and
%    \verb+\the\count@+ expands into the saved number.
% \end{macro}
%
% \begin{macro}{\prepnext@tok}
%    The macro \verb+\prepnext@tok+ is in charge of preparing the next
%    {\sf token} register. For that purpose we increase
%    \verb+\count@+ by $1$:
%    \begin{macrocode}
\def\prepnext@tok{\advance \count@ \@ne
%    \end{macrocode}
%    Then we locally delete any contents the
%    {\sf token} register might have.
%    \begin{macrocode}
   \toks\count@={}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\save@decl}
%    During the construction of the preamble the current {\sf token} is
%    always saved in the macro \verb+\@nextchar+ (see the definition
%    of \verb+\@mkpream+ on page \pageref{@mkpream}). The macro
%    \verb+\save@decl+ saves it into the next free
%    {\sf token} register, i.e.\ in \verb+\toks\count@+.
% \changes{2.0c}{90/08/14}{`relax removed and added elsewhere.}
%    \begin{macrocode}
\def\save@decl{\toks\count@ \expandafter{\@nextchar}}
%    \end{macrocode}
%    The reason for the  use of \verb+\relax+ is the following
%    hypothetical situation in the preamble:
%    \quad \verb+..\the\toks1\the\toks2..+ \quad \TeX\ expands
%    \verb+\the\toks2+ first in order to find out if the digit \verb+1+
%    is followed by other digits. E.g.\ a \verb+5+ saved in the
%    {\sf token} register $2$ would lead \TeX\ to insert the contents
%    of {\sf token} register $15$ instead of $1$ later on.
% 
% The example above refered to an older version of \verb+\save@decl+ which
% inserted a \verb+\relex+ inside the token register. This is now moved to
% the places where the actual token registers are inserted (look for
% \verb+\the@toks+) because the old version would still make \verb+@+
% expressions to moving arguments since after expanding the second register
% while looking for the end of the number the contents of the token register
% is added so that later on the whole register will be expanded.
% This serious bug was found after nearly two years international use of this
% style option by Johannes Braams.
% \end{macro}
%
%
%
% How does the situation look like, if we want to add another column
% to the preamble, i.e.\ if we have found a {\tt c}, {\tt l}, {\tt r},
% {\tt p}, {\tt m} or {\tt b} in the user preamble~?
% In this case we have the problem of the {\sf token} register from
% \verb+>{..}+ and \verb+<{..}+ having to be inserted at this moment
% because formating instructions like \verb+\hfil+ have to be set
% around them. On the other hand it is not known yet, if any
% \verb+<{..}+ instruction will appear in the user preamble at all.
%
% We solve this problem by adding two {\sf token} registers at a time.
% This explains, why we have freed the {\sf token} registers in
% \verb+\prepnext@tok+.
%
% \begin{macro}{\insert@column}
% \begin{macro}{\@sharp}
%    We now define the macro \verb+\insert@column+ which will do
%    this work for us.
%    \begin{macrocode}
\def\insert@column{%
%    \end{macrocode}
%    Here, we assume that the {\sf count} register
%    \verb+\@tempcnta+ has saved the value $\verb+\count@+ - 1$.
%    \begin{macrocode}
   \the@toks \the \@tempcnta
%    \end{macrocode}
%    Next follows the \verb+#+ sign which specifies the place
%    where the text of the column shall be inserted. To avoid
%    errors during the expansions in
%    \verb+\@addtopreamble+ we hide this sign in the command
%    \verb+\@sharp+ which is temporarily occupied with
%    \verb+\relax+ during the build-up of the preamble.
%    To remove unwanted spaces before and after the column text, we set
%    an \verb+\ignorespaces+  in front and a \verb+\unskip+ afterwards.
%    \begin{macrocode}
   \ignorespaces \@sharp \unskip
%    \end{macrocode}
%    Then the second {\sf token} register follows whose number should
%    be saved in \verb+\count@+.
%    We make sure that there will be no further expansion after readind
%    the number, by finishing with \verb+\relax+. The case above is not
%    critical since it is ended by \verb+\ignoespaces+.
% \changes{2.0c}{90/08/14}{`relax added to avoid problem 
%                           `the`toks0`the`toks1.}
%    \begin{macrocode}
   \the@toks \the \count@ \relax}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%
% \subsection{The separation of columns}
%
% \begin{macro}{\@addamp}
%    In the preamble a \verb+&+ has to be inserted between any two
%    columns; before the first column there
%    should not be a \verb+&+. As the user preamble may start with a
%    {\tt |} we have to remember somehow if we have already inserted a
%    \verb+#+ (i.e.\ a column). This is done with the boolean variable
%    \verb+\if@firstamp+ that we test in \verb+\@addamp+,
%    the macro that inserts the \verb+&+.
%    \begin{macrocode}
%    \newif \@iffirstamp
%    \def\@addamp{\if@firstamp \@firstampfalse
%                 \else \@addtopreamble &\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@acol}
% \begin{macro}{\@acolampacol}
% \begin{macro}{\col@sep}
%    We will now define some abbreviations for the extensions,
%    appearing most often in the preamble build-up.
%    Here \verb+\col@sep+ is a {\sf dimen} register which is set
%    equivalent to \verb+\arraycolsep+ in an {\sf array}--environment,
%    otherwise it is set equivalent to \verb+\tabcolsep+.
%    \begin{macrocode}
\newdimen\col@sep
\def\@acol{\@addtopreamble{\hskip\col@sep}}
%    \def\@acolampacol{\@acol\@addamp\@acol}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsection{The macro {\tt \protect\bslash @mkpream}}
%
% \begin{macro}{\@mkpream}
% \begin{macro}{\the@toks}
%    \label{@mkpream}
%    Now we can define the macro which builds up the preamble for the
%    \verb+\halign+.
%    First we initialize \verb+\@preamble+, \verb+\@lastchclass+
%    and the boolean variable \verb+\if@firstamp+.
%    \begin{macrocode}
\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
%    \end{macrocode}
%    During the build-up of the preamble we cannot directly use the
%    \verb+#+ sign; this would lead to an error message in the next
%    \verb+\@addtopreamble+ call.
%    Instead, we use the command \verb+\@sharp+ at places where later
%    a \verb+#+ will be.
%    This command is at first given the meaning \verb+\relax+;
%    therefore it will not be expanded when the preamble
%    is extended.
%    In the macro \verb+\@array+, shortly before the \verb+\halign+
%    is carried out, \verb+\@sharp+ is given its final meaning.
%
%    In a simular way,
%    we deal with the commands \verb+\@startpbox+ and
%    \verb+\@endpbox+, although the reason is different here: these
%    macros expand in many {\sf tokens} which would delay the
%    build-up of the preamble.
%    \begin{macrocode}
   \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
%    \end{macrocode}
%    Now we remove possible  $*$-forms in the user preamble with the
%    command \verb+\@xexpast+.  As we already know, this command saves
%    its result in the macro \verb+\@tempa+.
%    \begin{macrocode}
   \@xexpast #1*0x\@@
%    \end{macrocode}
%    Afterwards we initialize all registers and macros, that we need
%    for the build-up of the preamble.
%    Since we want to start with the {\sf token} register $0$,
%    \verb+\count@+ has to contain the value $-1$.
%    \begin{macrocode}
   \count@\m@ne
   \let\the@toks\relax
%    \end{macrocode}
%    Then we call up \verb+\prepnext@tok+ in order to prepare the
%    {\sf token} register $0$ for use.
%    \begin{macrocode}
   \prepnext@tok
%    \end{macrocode}
%    To evaluate the user preamble (without stars) saved in
%    \verb+\@tempa+ we use the \LaTeX--macro \verb+\@tfor+.
%    The strange appearing construction with \verb+\expandafter+ is
%    based on the fact that we have to put the replacement text of
%    \verb+\@tempa+ and not the macro \verb+\@tempa+ to this
%    \LaTeX--macro.
%    \begin{macrocode}
   \expandafter \@tfor \expandafter \@nextchar
    \expandafter :\expandafter =\@tempa \do
%    \end{macrocode}
%    The body of this loop (the group after the \verb+\do+)
%    is executed for one {\sf token} at a time, whereas
%    the current {\sf token} is saved in \verb+\@nextchar+.
%    At first we evaluate the current {\sf token} with the already
%    defined macro \verb+\@testpach+, i.e.\ we assign to
%    \verb+\@chclass+ the character class and to \verb+\@chnum+
%    the characternumber of this {\sf token}.
%    \begin{macrocode}
   {\@testpach\@nextchar
%    \end{macrocode}
%    Then we branch out depending on the value of \verb+\@chclass+ into
%    different macros that extend the preamble respectively.
%    \begin{macrocode}
   \ifcase \@chclass \@classz \or \@classi \or \@classii
     \or \save@decl \or \or \@classv \or \@classvi
     \or \@classvii \or \@classviii  \or \@classix
     \or \@classx \fi
%    \end{macrocode}
%    Two cases deserve our special attention:
%    Since the current {\sf token} cannot have the character class $4$
%    (start) we have skipped this possibility. If the character class
%    is $3$, only the content of \verb+\@nextchar+ has to be saved into
%    the current {\sf token} register; therefore we call up
%    \verb+\save@decl+ directly and save a macro name.
%    After the preamble has been extended we assign the
%    value of \verb+\@chclass+ to the counter \verb+\@lastchclass+ to
%    assure that this information will be available during the next run
%    of the loop.
%    \begin{macrocode}
   \@lastchclass\@chclass}%
%    \end{macrocode}
%    After the loop has been finished space must still be added to
%    the created preamble, depending on the last {\sf token}.
%    Depending on the value of \verb+\@lastchclass+ we perform
%    the necessary operations.
%    \begin{macrocode}
   \ifcase\@lastchclass
%    \end{macrocode}
%    If the last class equals $0$ we add a
%    \verb+\hskip \col@sep+.
%    \begin{macrocode}
   \@acol \or
%    \end{macrocode}
%    If it equals $1$ we do not add any additional space so that the
%    horizontal lines do not exceed the vertical ones.
%    \begin{macrocode}
   \or
%    \end{macrocode}
%    Class $2$ is treated like class $0$ because a \verb+<{...}+  can
%    only directly follow after class $0$.
%    \begin{macrocode}
   \@acol \or
%    \end{macrocode}
%    Most of the other possibilities can only appear if the user
%    preamble was defective. Class $3$ is not allowed since after
%    a \verb+>{..}+ there must always follow a {\tt c}, {\tt l},
%    { {\tt r}, {\tt p},\tt m} or  {\tt b}. We report an error
%    and ignore the declaration given by \verb+{..}+.
%    \begin{macrocode}
   \@preamerr \thr@@ \or
%    \end{macrocode}
%    If \verb+\@lastchclass+ is $4$ the user preamble has been empty.
%    To continue, we insert a \verb+#+ in the preamble.
%    \begin{macrocode}
   \@preamerr \tw@ \@addtopreamble\@sharp \or
%    \end{macrocode}
%    Class $5$ is allowed again. In this case
%    (the user preamble ends with \verb+@{..}+) we need not
%    do anything.
%    \begin{macrocode}
   \or
%    \end{macrocode}
%    Any other case means that the arguments to
%    \verb+@+, {\tt !}, {\tt <}, {\tt >}, {\tt p}, {\tt m} or {\tt b}
%    have been forgotten. So we report an error and ignore the last
%    {\sf token}.
%    \begin{macrocode}
   \else  \@preamerr \@ne \fi
%    \end{macrocode}
%    Now that the build-up of the preamble is almost finished we can
%    insert the {\sf token} registers and therefore redefine
%    \verb+\the@toks+. The actual insertion, though, is performed
%    later.
%    \begin{macrocode}
   \def\the@toks{\the\toks}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%  \section{The macros {\tt \protect
%       \bslash @classz} to {\tt \protect\bslash @classx}}
%
% The preamble is extended by the macros \verb+\@classz+ to
% \verb+\@classx+ which are called by \verb+\@mkpream+
%  depending on \verb+\@lastchclass+
% (i.e. the character class of the last {\sf token}).
% \begin{macro}{\@classx}
%    First we define \verb+\@classx+ because of its important r\^ole.
%    When it is called we find that the current
%    {\sf token} is {\tt p}, {\tt m} or {\tt b}.
%    That means that a new column has to start.
%    \begin{macrocode}
\def\@classx{%
%    \end{macrocode}
%    Depending on the value of \verb+\@lastchclass+ different actions
%    must take place:
%    \begin{macrocode}
  \ifcase \@lastchclass
%    \end{macrocode}
%    If the last character class was $0$ we separate the columns by
%    \verb+\hskip\col@sep+ followed by \verb+&+ and another
%    \verb+\hskip\col@sep+.
%    \begin{macrocode}
  \@acolampacol \or
%    \end{macrocode}
%    If the last class was class $1$ --- that means that a vertical
%    line was
%    drawn, --- before this line a \verb+\hskip\col@sep+ was inserted.
%    Therefore there has to be only a \verb+&+ followed by
%    \verb+\hskip\col@sep+. But this \verb+&+ may be inserted only
%    if this is not the first column. This process is controlled
%    by \verb+\if@firstamp+ in the macro \verb+\addamp+.
%    \begin{macrocode}
  \@addamp \@acol \or
%    \end{macrocode}
%    Class $2$ is treated like class $0$ because \verb+<{...}+ can only
%    follow after class $0$.
%    \begin{macrocode}
  \@acolampacol \or
%    \end{macrocode}
%    Class $3$ requires no actions because all things necessary have
%    been done by the preamble {\sf token} {\tt >}.
%    \begin{macrocode}
  \or
%    \end{macrocode}
%    Class $4$ means that we are at the beginning of the preamble.
%    Therefore we start the preamble with \verb+\hskip\col@sep+ and
%    then call \verb+\@firstampfalse+. This makes sure that a later
%    \verb+\@addamp+ inserts the character
%    \verb+&+ into the preamble.
%    \begin{macrocode}
  \@acol \@firstampfalse \or
%    \end{macrocode}
%    For class $5$ {\sf tokens} only the character \verb+&+ is inserted
%    as a column separator. Therefore we call \verb+\@addamp+.
%    \begin{macrocode}
  \@addamp
%    \end{macrocode}
%    Other cases are impossible. For an example
%    $\verb+\@lastchclass+ = 6$---as it might appear in a
%    preamble of the form \verb+...!p...+---{\tt p} would have
%    been taken as an  argument of {\tt !}\ by \verb+\@testpach+.
%    \begin{macrocode}
  \fi}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classz}
%    If the character class of the last {\sf token} is $0$
%    we have {\tt c}, {\tt l}, {\tt r} or an argument of {\tt m},
%    {\tt b} or\ {\tt p}. In the first three cases the preamble must be
%    extended the same way as if we had class $10$. The remaining two
%    cases do not require any action because the space needed was
%    generated by the last {\sf token} (i.e.\ {\tt m}, {\tt b} or
%    {\tt p}). Since \verb+\@lastchclass+ has the value $10$ at
%    this point nothing happens when verb+\@classx+ is called. So the
%    macro \verb+\@chlassz+ may start like this:
%    \begin{macrocode}
\def\@classz{\@classx
%    \end{macrocode}
%    Acording to the definition of \verb+\insert@column+ we must store
%    the number of the {\sf token} register in which a preceding
%    \verb+>{..}+ might have stored its argument into
%    \verb+\@tempcnta+.
%    \begin{macrocode}
   \@tempcnta \count@
%    \end{macrocode}
%    To have $\verb+\count@+ = \verb+\@tmpcnta+ + 1$ we prepare
%    the next {\sf token} register.
%    \begin{macrocode}
   \prepnext@tok
%    \end{macrocode}
%    Now the preamble must be extended with the column whose format
%    can be determinated by \verb+\@chnum+.
%    \begin{macrocode}
   \@addtopreamble{\ifcase \@chnum
%    \end{macrocode}
%    If \verb+\@chnum+ has the value $0$ a centered column has to be
%    generated.
%    So we begin with stretchable space.
%    \begin{macrocode}
      \hfil
%    \end{macrocode}
%    The command \verb+\d@llar+ follows expanding into nothing
%    (in the {\sf tabular}--environment) or into \verb+$+.
%    Doing this (provided an appropriate setting of
%    \verb+\d@llar+) we achieve that the contents of the columns of an
%    {\sf array}--environment are set in math mode while those of a
%    {\sf tabular}--environment are set in LR mode.
%    \begin{macrocode}
      \d@llar
%    \end{macrocode}
%    Now we insert the contents of the two {\sf token} registers
%    and the symbol
%    for the column entry (i.e.\ \verb+#+ or
%    more precise \verb+\@sharp+) using \verb+\insert@column+.
%    \begin{macrocode}
      \insert@column
%    \end{macrocode}
%    We end this case with another \verb+\d@llar+ \verb+\hfil+.
%    \begin{macrocode}
      \d@llar \hfil \or
%    \end{macrocode}
%    The templates for {\tt l} and {\tt r} (i.e.\ \verb+\@chnum+ $1$
%    or $2$) are generated the same way. Since one  \verb+\hfil+ is
%    missing the text is moved to the relevant side.
%    The \verb+\kern\z@+ is needed in case of an empty column
%    entry. Otherwise
%    the \verb+\unskip+ in \verb+\insert@column+ removes the
%    \verb+\hfil+.
%    \begin{macrocode}
      \d@llar \insert@column \d@llar \hfil \or
      \hfil\kern\z@ \d@llar \insert@column \d@llar \or
%    \end{macrocode}
%    The templates for {\tt p}, {\tt m} and {\tt b} mainly consist
%    of a {\sf box}. In case of {\tt m} it is generated by
%    \verb+\vcenter+.
%    This command is allowed only in math mode. Therefore we start with
%    a~\verb+$+.
%    \begin{macrocode}
   $\vcenter
%    \end{macrocode}
%    The part of the templates which is the same in all three cases
%    ({\tt p}, {\tt m} and {\tt b})
%    is built by the macros \verb+\@startpbox+ and
%    \verb+\@endpbox+. \verb+\@startpbox+ has an argument:
%    the width of the column which is stored in the current
%    {\sf token} (i.e.\ \verb+\@nextchar+).
%    Between these two macros we find the well known
%    \verb+\insert@column+.
%    \begin{macrocode}
   \@startpbox{\@nextchar}\insert@column \@endpbox $\or
%    \end{macrocode}
%    The templates for {\tt p} and {\tt b} are generated in the same
%    way though we do not need the
%    \verb+$+ characters because we use \verb+\vtop+
%    or \verb+\vbox+.
%    \begin{macrocode}
   \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
   \vbox \@startpbox{\@nextchar}\insert@column \@endpbox
%    \end{macrocode}
%    Other values for \verb+\@chnum+ are impossible. Therefore we
%    end the arguments to \verb+\@addtopreamble+ and \verb+\ifcase+.
%    Before we come to the end of \verb+\@classz+ we have to
%    prepare the next {\sf token} register.
%    \begin{macrocode}
  \fi}\prepnext@tok}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classix}
%    In case of class $9$ ({\tt >}--{\sf token}) we first check
%    if the character class of the last
%    {\sf token} was $3$. In this case we have a
%    user preamble of the form \verb+..>{...}>{...}..+ which
%    is not allowed. We only give an error message and continue.
%    So the declarations defined by the first  \verb+>{...}+
%    are ignored.
%    \begin{macrocode}
\def\@classix{\ifnum \@lastchclass = \thr@@
       \@preamerr \thr@@ \fi
%    \end{macrocode}
%    Furthermore, we call up \verb+\@class10+
%    because afterwards always a new column is started by
%    {\tt c}, {\tt l}, {\tt r}, {\tt p}, {\tt m} or {\tt b}.
%    \begin{macrocode}
       \@classx}
%    \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\@classviii}
%    If the current {\sf token} is a {\tt <} the last
%    character class must be $0$. In this case it is not necessary to
%    extend the preamble. Otherwise we output an error message, set
%    \verb+\@chclass+ to $6$ and call \verb+\@classvi+.
%    By doing this we achieve that {\tt <} is treated like {\tt !}.
%    \begin{macrocode}
\def\@classviii{\ifnum \@lastchclass >\z@
      \@preamerr 4\@chclass 6 \@classvi \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arrayrule}
%    There is only one incompatibility with the original definition:
%    the definition of \verb+\@arrayrule+. In the original a line
%    without width\footnote{So the space between {\tt cc} and {\tt c|c}
%                                  is equal.}
%    is created by multiple \verb+\hskip .5\arrayrulewidth+.
%    We only insert a vertical line into the preamble.
%    This is done to prevent problems with \TeX's main
%    memory when generating
%    tables with many vertical lines in them (especially in the case of
%    {\sf floats}).
%    \begin{macrocode}
\def\@arrayrule{\@addtopreamble \vline}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classvii}
%    As a consequence it follows that in case of class $7$
%    (\verb+@+ {\sf token})  the preamble need not to be extended.
%    In the original definition $\verb+\@lastchclass+ = 1$
%    is treated by inserting \verb+\hskip .5\arrayrulewidth+.
%    We only check if the last {\sf token} was of class $3$ which is
%    forbidden.
%    \begin{macrocode}
\def\@classvii{\ifnum \@lastchclass = \thr@@
%    \end{macrocode}
%    If this is true we output an error message and
%    ignore the declarations stored
%    by the last  \verb+>{...}+, because these are overwritten
%    by the argument of {\tt @}.
%    \begin{macrocode}
   \@preamerr \thr@@ \fi}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classvi}
%    If the current {\sf token} is a regular {\tt !}\ and the last
%    class
%    was $0$ or $2$ we extend the preamble with \verb+\hskip \col@sep+.
%    If the last {\sf token} was of class $1$ (for instance {\tt |})
%    we extend with \verb+\hskip \doublerulesep+ because the
%    construction \verb+!{...}+ has to be treated like {\tt |}.
%    \begin{macrocode}
\def\@classvi{\ifcase \@lastchclass
      \@acol \or
      \@addtopreamble{\hskip \doublerulesep}\or
      \@acol \or
%    \end{macrocode}
%    Now \verb+\@preamerr...+ should follow because a
%    user preamble of the form \verb+..>{..}!..+ is not allowed.
%    To save memory we call \verb+\@classvii+ instead which also
%    does what we want.
%    \begin{macrocode}
      \@classvii
%    \end{macrocode}
%    If \verb+\@lastchclass+ is $4$ or $5$ nothing has to be done.
%    Class $6$ to $10$ are not possible.
%    So we finish the macro.
%    \begin{macrocode}
      \fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classii}
% \begin{macro}{\@classiii}
%    In the case of character classes $2$ and $3$ (i.e.\ the argument
%    of {\tt <} or {\tt >}) we only have to store the current
%    {\sf token} (\verb+\@nextchar+) into the corresponding
%    {\sf token} register since the preparation and
%    insertion of these registers
%    are done by the macro \verb+\@classz+.
%    This is equivalent to calling \verb+\save@decl+ in the case of
%    class $3$. To save command identifiers we do this call up
%     in the macro \verb+\@mkpream+.
%
%    Class $2$ exhibits a more complicated situation: the
%    {\sf token} registers have already been inserted by
%    \verb+\@classz+. So the value of \verb+\count@+ is too high
%    by one. Therefore we decrease \verb+\count@+ by $1$.
%    \begin{macrocode}
\def\@classii{\advance \count@ \m@ne
%    \end{macrocode}
%    Next we store the current {\sf token} into the correct 
%    {\sf token} register by calling \verb+\save@decl+ and then
%    increase the value of \verb+\count@+ again. At this point we
%    can save memory once more (at the cost of time) if we use the
%     macro \verb+\prepnext@tok+.
%    \begin{macrocode}
   \save@decl\prepnext@tok}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\@classv}
%    If the current {\sf token} is of class $5$ then it is an argument
%    of a {\tt @} {\sf token}. It must be stored into a
%    {\sf token} register.
%    \begin{macrocode}
\def\@classv{\save@decl
%    \end{macrocode}
%    We extend the preamble with a command which inserts this
%    {\sf token} register into the preamble when its construction is
%    finished. The user expects that this argument is worked out in
%    math mode if it was used in an {\sf array}--environment. Therefore
%    we surround it with \verb+\d@llar+'s.
% \changes{2.0c}{90/08/14}{`relax added to avoid problem 
%                           `the`toks0`the`toks1.}
%    \begin{macrocode}
   \@addtopreamble{\d@llar\the@toks\the\count@\relax\d@llar}%
%    \end{macrocode}
%    Finally we must prepare the next {\sf token} register.
%    \begin{macrocode}
   \prepnext@tok}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classi}
%    In the case of class $0$ we were able to generate the necessary
%    space between columns by using the macro \verb+\@classx+.
%    Analogously the macro \verb+\@classvi+ can be used for class $1$.
%    \begin{macrocode}
\def\@classi{\@classvi
%    \end{macrocode}
%    Depending on \verb+\@chnum+ a vertical line
%    \begin{macrocode}
   \ifcase \@chnum \@arrayrule \or
%    \end{macrocode}
%    or (in case of \verb+!{...}+) the current {\sf token} --- stored
%    in \verb+\@nextchar+ --- has to be inserted into the preamble.
%    This corresponds to calling \verb+\@classv+.
%    \begin{macrocode}
      \@classv \fi}
%    \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\@startpbox}
%    In \verb+\@classz+  the macro \verb+\@startpbox+ is used.
%    The width of the {\sf parbox} is passed as an argument.
%    \verb+\vcenter+, \verb+\vtop+ or \verb+\vbox+ are already in the
%    preamble. So we start with the braces for the wanted box.
%    \begin{macrocode}
\def\@startpbox#1{\bgroup
%    \end{macrocode}
%    The argument is the width of the box. This information has to be
%    assigned to \verb+\hsize+.
%    Then we assain default values to several parameters used in a
%    {\sf parbox}.
%    \begin{macrocode}
  \hsize #1 \@arrayparboxrestore
%    \end{macrocode}
%    Our main problem is to obtain the same distance between succeeding
%    lines of the {\sf parbox}.
%    We have to remember that the distance between two {\sf parboxes}
%    should be defined by \verb+\@arstrut+. That means that it can be
%    greater than the distance in a {\sf parbox}.
%    Therefore it is not enough to set a \verb+\@arstrut+ at the
%    beginning and at the end of the {\sf parbox}. This would
%    dimension the distance
%    between first and second line and the distance between the two
%    last lines of the {\sf parbox} wrongly.
%    To prevent this we set an invisible rule of height
%    \verb+\@arstrutbox+
%    at the beginning of the {\sf parbox}. This has no effect on the
%    depth of the first line. At the end of the {\sf parbox} we set
%    analogously another invisible rule which only affects the depth
%    of the last line.
%    \begin{macrocode}
   \vrule \@height \ht\@arstrutbox \@width \z@}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@endpbox}
%    If there are any declarations defined by \verb+>{...}+
%    and \verb+<{...}+
%    they now follow in the macro \verb+\@classz+ --- the contents
%    of the column in between.
%    So the macro \verb+\@endpbox+ must insert the {\sf specialstrut}
%    mentioned earlier and then close the group opened by
%    \verb+\@startpbox+.
%    \begin{macrocode}
\def\@endpbox{\vrule \@width \z@ \@depth \dp \@arstrutbox \egroup}
%    \end{macrocode}
% \end{macro}
%
%
% \section{Building and calling {\tt \protect\bslash halign}}
%
% \begin{macro}{\@array}
%    After we have discussed the macros needed for the evaluation
%    of the user preamble we can define the macro \verb+\@array+
%    which uses these macros to create a \verb+\halign+.
%    It has two arguments. The first one is a position argument
%    which can be {\tt t}, {\tt b} or {\tt c}; the
%    second one describes the wanted preamble,
%    e.g.\ it has the form \verb+|c|c|c|+.
%    \begin{macrocode}
\def\@array[#1]#2{%
%    \end{macrocode}
%    First we define a {\sf strut} whose size basically corresponds
%     to a normal {\sf strut} multiplied by the factor
%    \verb+\arraystretch+.
%    This {\sf strut} is then  inserted into every row and enforces
%     a minimal distance between two rows.
%    Nevertheless, when using horizontal lines, large letters
%    (like accented capital letters) still collide with such lines.
%    Therefore at first we add to the height of a normal {\sf strut}
%    the value of the parameter \verb+\extrarowheight+.
%    \begin{macrocode}
  \@tempdima \ht \strutbox
  \advance \@tempdima by\extrarowheight
  \setbox \@arstrutbox \hbox{\vrule
             \@height \arraystretch \@tempdima
             \@depth \arraystretch \dp \strutbox
             \@width \z@}%
%    \end{macrocode}
%    Then we open a group, in which the user preamble is evaluated by
%    the macro \verb+\@mkpream+. As we know this must happen locally.
%    This macro creates a preamble for a \verb+\halign+ and saves
%    its result globally in the control sequence \verb+\@preamble+.
%    \begin{macrocode}
  \begingroup
  \@mkpream{#2}%
%    \end{macrocode}
%    We again redefine \verb+\@preamble+ so that a call up of
%    \verb+\@preamble+ now starts the \verb+\halign+. Thus also the
%    arguments of {\tt >}, {\tt <}, {\tt @} and {\tt !}, saved in the
%    {\sf token} registers are inserted into the preamble.
%    The \verb+\tabskip+ at the beginning and end of the preamble
%    is set to {\sf 0pt} (in the beginning by the use of
%    \verb+\ialign+). Also the command \verb+\@arstrut+ is build in,
%    which inserts the \verb+\@arstrutbox+, defined above. Of course,
%    the opening brace after \verb+\ialign+ has to be implicit as it
%    will be closed in \verb+\endarray+ or another macro.
%    \begin{macrocode}
  \xdef\@preamble{\ialign \@halignto
                  \bgroup \@arstrut \@preamble
                          \tabskip \z@ \cr}%
%    \end{macrocode}
%    What we have not explained yet is the macro \verb+\@halignto+
%    that was just used. Depending on its replacement text the
%    \verb+\halign+ becomes a \verb+\halign+ {\tt to} \meta{dimen}.
%    Now we close the group again. Thus
%    \verb+\@startpbox+ and \verb+\@endpbox+ as well as all
%    {\sf token} registers get their former meaning back.
%    \begin{macrocode}
  \endgroup
%    \end{macrocode}
%    Now we decide depending on the position argument in which {\sf
%    box} the \verb+\halign+ is to be put. (\verb+\vcenter+ may be used
%    because we are in math mode.)
%    \begin{macrocode}
  \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
%    \end{macrocode}
%    Now another implicit opening brace appears; then definitions
%    which shall stay local follow. While constructing the
%    \verb+\@preamble+ in \verb+\@mkpream+ the \verb+#+ sign must be
%    hidden in the macro \verb+\@sharp+ which is \verb+\let+ to
%    \verb+\relax+ at that moment (see definition of \verb+\@mkpream+
%    on page~\pageref{@mkpream}).
%    All these now get their actual meaning.
%    \begin{macrocode}
  \bgroup
  \let \@sharp ##\let \protect \relax
%    \end{macrocode}
%    With the above defined {\sf struts} we fix down the distence
%    between rows by setting \verb+\lineskip+ and \verb+\baselineskip+
%    to {\sf 0pt}. Since there have to be set \verb+$+'s
%    around every column in the {\sf array}--environment
%     the parameter \verb+\mathsurround+ should
%    also be set to {\sf 0pt}. This prevents additional space between
%    the rows. The
%    \PlainTeX--macro \verb+\m@th+ does this.
%    \begin{macrocode}
  \lineskip \z@
  \baselineskip \z@
  \m@th
%    \end{macrocode}
%    Beside, we have to assign a special meaning (which we still have
%    to specify) to the line separator \verb+\\+. We also have to
%    redefine the command \verb+\par+ in such a way that empty lines in
%    \verb+\halign+ cannot do any damage. We succeed in doing  so
%    by choosing something that will disappear when expanding.
%    After that we only have to call up \verb+\@preamble+ to
%    start the wanted \verb+\halign+.
%    \begin{macrocode}
  \let\\ \@arraycr  \let\par\@empty \@preamble}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\extrarowheight}
%    The {\sf dimen} parameter used above also needs to be allocated.
%    As a default value we use {\sf 0pt}, to ensure compatibility with
%    standard \LaTeX.
%    \begin{macrocode}
\newdimen \extrarowheight
\extrarowheight=0pt
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arstrut}
%    Now the insertion of \verb+\@arstrutbox+ through \verb+\@arstut+
%    is easy since we know exacty in which mode \TeX\ is while working
%    on the \verb+\halign+ preamble.
%    \begin{macrocode}
\def\@arstrut{\unhcopy\@arstrutbox}
%    \end{macrocode}
% \end{macro}
%
%
% \section{The line separator {\tt\protect\bslash\protect\bslash}}
%
% \begin{macro}{\@arraycr}
%    In the macro \verb+\@array+ the line separator \verb+\\+ is
%    \verb+\let+ to the command \verb+\@arraycr+.
%    Its definition starts with a special brace which I have directly
%    copied from the original definition. It is
%    necessary, because the \verb+\futurlet+ in \verb+\@ifnextchar+
%    might
%    expand a  following \verb+&+ {\sf token} in a construction like
%    \verb+\\ &+. This would otherwise end the alignment template at a
%    wrong time. For further information see
%    \cite[Appendix D]{bk:knuth}.
%    \begin{macrocode}
\def\@arraycr{{\ifnum 0=`}\fi
%    \end{macrocode}
%    Then we test whether the user is using the star form and ignore
%    a possible star (I also disagree with this procedure, because a
%    star does not make any sence here).
%    \begin{macrocode}
  \@ifstar \@xarraycr \@xarraycr}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xarraycr}
%    In the command \verb+\@xarraycr+ we test if an optional argument
%    exists.
%    \begin{macrocode}
\def\@xarraycr{\@ifnextchar [%
%    \end{macrocode}
%    If it does, we branch out into the macro \verb+\@argarraycr+ if
%    not we close the special brace (mentioned above) and end the row
%    of the \verb+\halign+ with a \verb+\cr+.
%    \begin{macrocode}
  \@argarraycr {\ifnum 0=`{\fi}\cr}}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@argarraycr}
%    If additional space is requested by the user this case is treated
%    in the macro \verb+\@argarraycr+. First we close the special brace
%    and then we test if the additional space is positive.
%    \begin{macrocode}
\def\@argarraycr[#1]{\ifnum0=`{\fi}\ifdim #1>\z@
%    \end{macrocode}
%    If this is the case we create an invisible vertical rule with a
%    depth of $\verb+\dp\@arstutbox+  + \left\langle
%                                         \it wanted\ space
%                                       \right\rangle  $.
%    Thus we achieve that all vertical lines specified
%    in the user preamble by a {\tt |} are now
%    generally drawn.
%    Then the row ends with a \verb+\cr+.
%
%    If the space is negative we end the row at once with a \verb+\cr+
%    and move back up with a \verb+\vskip+.
%
%    While testing these macros I found out that the
%    \verb+\endtemplate+
%    created by \verb+\cr+ and \verb+&+ is something like an
%    \verb+\outer+ primitive and therefore it should not appear in
%    incomplete \verb+\if+ statements. Thus the following solution was
%    choosen which hides the \verb+\cr+ in other macros when \TeX\
%    is skipping conditional text.
%    \begin{macrocode}
  \@xargarraycr{#1}\else \@yargarraycr{#1}\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xargarraycr}
% \begin{macro}{\@yargarraycr}
%    The following macros were already explained above.
%    \begin{macrocode}
\def\@xargarraycr#1{\unskip
  \@tempdima #1\advance\@tempdima \dp\@arstrutbox
  \vrule \@depth\@tempdima \@width\z@ \cr}
\def\@yargarraycr#1{\cr\noalign{\vskip #1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%
% \section{Spanning several columns}
%
% \begin{macro}{\multicolumn}
%    If several columns should be held together with a special format
%    the command \verb+\multicolumn+ must be used. It has three
%    arguments: the number of columns to be covered; the format for
%    the result column and the actual column entry.
%    \begin{macrocode}
\def\multicolumn#1#2#3{%
%    \end{macrocode}
%    First we combine the given number of columns into a single one;
%    then we start a new block so that the following definition is kept
%    local.
%    \begin{macrocode}
   \multispan{#1}\begingroup
%    \end{macrocode}
%    Since a \verb+\multicolumn+ should only describe the format of a
%    result column, we redefine \verb+\@addamp+ in such a way that one
%    gets an error message if one uses more than one
%    {\tt c}, {\tt l}, {\tt r}, {\tt p}, {\tt m} or {\tt b} in the
%    second argument. One should consider that this definition is local
%    to the build-up of the preamble; an {\sf array}-- or
%    {\sf tabular}--environment in the third argument of the
%    \verb+\multicolumn+ is therefore worked through correctly as well.
%    \begin{macrocode}
   \def\@addamp{\if@firstamp \@firstampfalse \else
                \@preamerr 5\fi}%
%    \end{macrocode}
%    Then we evaluate the second argument with the help of
%    \verb+\@mkpream+.
%    Now we still have to insert the contents of the {\sf token}
%    register into the \verb+\@preamble+, i.e.\ we have to say
%    \verb+\xdef\@preamble{\@preamble}+. This is achieved shorter by
%    writing:
%    \begin{macrocode}
   \@mkpream{#2}\@addtopreamble\@empty
%    \end{macrocode}
%    After the \verb+\@preamble+ is created we forget all local
%    definitions and occupations of the {\sf token} registers.
%    \begin{macrocode}
   \endgroup
%    \end{macrocode}
%    In the special situation of  \verb+\multicolumn+ \verb+\@preamble+
%    is not needed as preamble for a \verb+\halign+ but it is directly
%    inserted into our table. Thus instead of \verb+\sharp+
%    there has to be the column entry (\verb+#3+) wanted by the user.
%    \begin{macrocode}
   \def\@sharp{#3}%
%    \end{macrocode}
%    Now we can pass the \verb+\@preamble+ to \TeX\ . For safety
%    we start with an \verb+\@arstrut+. This should usually be in the
%    template for the first column however we do not know if this
%    template was overwritten by our \verb+\multicolumn+.
%    \begin{macrocode}
   \@arstrut \@preamble \ignorespaces}
%    \end{macrocode}
% \end{macro}
%
%
%
%   \section{The Environment Definitions}
%
% After these preparations we are able to define the environments. They
% only differ in the initialisations of \verb+\d@llar+, \verb+\col@sep+
%  and \verb+\@halignto+.
%
% \begin{macro}{\@halignto}
% \begin{macro}{\d@llar}
%    In order to relieve the {\sf save stack} we assign the replacement
%    texts for \verb+\@halignto+ globaly. \verb+\d@llar+ has to be local
%    since otherwise nested {\sf tabular} and {\sf array} environments 
%    (via \verb+\multicolumn+) are impossible.
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\array}
%    Our new definition of \verb+\array+ then reads:
% \changes{2.0d}{90/08/20}{`d@llar local to preamble.}
%    \begin{macrocode}
\def\array{\col@sep\arraycolsep
  \def\d@llar{$}\gdef\@halignto{}%
%    \end{macrocode}
%    Since there might be an optional argument we call another
%    macro which is also used by the other environments.
%    \begin{macrocode}
  \@tabarray}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabarray}
%    This macro tests for a optional bracket and then calls up
%    \verb+\@array+ or \verb+\@array[c]+ (as default).
%    \begin{macrocode}
\def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\tabular}
% \begin{macro}{\tabular*}
%    The environments {\sf tabular} and {\sf tabular$*$} differ
%    only in the initialisation of \verb+\@halignto+. Therefore
%    we define
%    \begin{macrocode}
\def\tabular{\gdef\@halignto{}\@tabular}
%    \end{macrocode}
%     and analoguesly
%     \begin{macrocode}
\expandafter\def\csname tabular*\endcsname#1{%
      \gdef\@halignto{to#1}\@tabular}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@tabular}
%    The rest of the job is carried out by the \verb+\@tabular+ macro:
%    \begin{macrocode}
\def\@tabular{%
%    \end{macrocode}
%    First of all we have to make sure that we start out in {\sf
%    hmode}.
%    Otherwise we might find our table dangling by itself on a line.
%    \begin{macrocode}
  \leavevmode
%    \end{macrocode}
%    It should be taken into consideration that the macro
%    \verb+\@array+
%    must be called in math mode. Therefore we open a {\sf box}, insert
%    a \verb+$+ and then assign the correct values to \verb+\col@sep+
%    and \verb+\d@llar+.
% \changes{2.0d}{90/08/20}{`d@llar local to preamble.}
%    \begin{macrocode}
  \hbox \bgroup $\col@sep\tabcolsep \let\d@llar\@empty
%    \end{macrocode}
%    Now everything {\sf tabular} specific is done and we are able to
%    call the \verb+\@tabarray+ macro.
%    \begin{macrocode}
  \@tabarray}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endarray}
%    When the processing of {\sf array} is finished we have to
%    close the \verb+\halign+
%    and afterwards the surrounding {\sf box} selected by
%    \verb+\@array+. To save {\sf token} space we then redefine
%    \verb+\@preamble+
%    because its replacement text isn't longer needed.
%    \begin{macrocode}
\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endtabular}
% \begin{macro}{\endtabular*}
%    To end a {\sf tabular} or {\sf tabular$<*$} environment we call up
%    \verb+\endarray+, close the math mode and then the surrounding
%    \verb+\hbox+.
%    \begin{macrocode}
\def\endtabular{\endarray $\egroup}
\expandafter\let\csname endtabular*\endcsname=\endtabular
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%   \section{Last minute definitions}
%
%
% If this file is used as a style file we should \verb+\let+ all macros
% to \verb+\relax+ that were used in the original but are no longer
%  necessary.
%    \begin{macrocode}
\let\@ampacol=\relax        \let\@expast=\relax
\let\@arrayclassiv=\relax   \let\@arrayclassz=\relax
\let\@tabclassiv=\relax     \let\@tabclassz=\relax
\let\@arrayacol=\relax      \let\@tabacol=\relax
\let\@tabularcr=\relax      \let\@@endpbox=\relax
\let\@argtabularcr=\relax   \let\@xtabularcr=\relax
%    \end{macrocode}
%
% \begin{macro}{\@preamerr}
%    We also have to redefine the error routine \verb+\@preamerr+ since
%    new kind of errors are possible.
%    The code for this macro is not perfect yet;
%    it still needs too much memory.
%    \begin{macrocode}
\def\@preamerr#1{\def\@tempd{{..} at wrong position: }%
   \@latexerr{%
   \ifcase #1 Illegal pream-token (\@nextchar): `c' used\or %0
    Missing arg: token ignored\or                           %1
    Empty preamble: `l' used\or                             %2
    >\@tempd token ignored\or                               %3
    <\@tempd changed to !{..}\or                            %4
    Only one colum-spec. allowed.\fi}\@ehc}                 %5
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tfor}
%    Testing this implementation an error was found in the definition
%    of the \LaTeX{} macro \verb+\@tfor+. It was not implemented
%    according to
%    its specification. The assignment to \verb+\@fortmp+ must not take
%    place
%    via \verb+\xdef+. A \verb+\def+ has to be used because \verb+#2+
%    not be expanded. Since this mistake does not show up when
%    \verb+\@tfor+ is used in {\tt latex.tex}, it does not
%    seem to have been noticed.
%    \begin{macrocode}
\def\@tfor#1:=#2\do#3{\def\@fortmp{#2}\ifx\@fortmp\@empty
      \else\@tforloop#2\@nil\@nil\@@#1{#3}\fi}
%    \end{macrocode}
% \end{macro}
%
% \Finale
%
\endinput
