% \iffalse meta-comment
%
% Copyright 1993 1994 1995 1996 1997 1998 1999
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file.
%
% This file is part of the LaTeX2e system.
% ----------------------------------------
%
% It may be distributed under the terms of the LaTeX Project Public
% License, as described in lppl.txt in the base LaTeX distribution.
% Either version 1.0 or, at your option, any later version.
%
% \fi
%
% \iffalse
%%% From File: lttab.dtx
%<def>\ProvidesFile{autotabg.sty}
%<def> [1998/11/13 v1.1m tabbing autoload file]
%<*driver>
% \fi
\ProvidesFile{lttab.dtx}[1998/11/13 v1.1m LaTeX Kernel (Columns)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{lttab.dtx}
\title{\filename}
\date{\filedate}
\author{%
Johannes Braams\and
David Carlisle\and
Alan Jeffrey\and
Leslie Lamport\and
Frank Mittelbach\and
Chris Rowley\and
Rainer Sch\"opf}
\begin{document}
\maketitle
\DocInput{\filename}
\end{document}
%</driver>
% \fi
%
%
% \CheckSum{1131}
%
% \changes{v1.0l}{1995/05/07}{Use \cs{hb@xt@}}
% \changes{v1.1a}{1995/05/22}{Support autoloading feature}
% \changes{v1.1b}{1995/06/14}{Use \cs{ProvidesFile} in autoload}
% \changes{v1.1d}{1995/10/04}{Modify autoload support}
% \changes{v1.1k}{1998/06/18}{Small addition to documentation}
% \changes{v1.1l}{1998/07/06}{Small correction to documentation}
%
% \section{Tabbing, Tabular and Array Environments}
% This section deals with `Lining It Up in Columns'. First the
% |tabbing| environment is defined, and then in second part, |tabular|
% together with its variants, |tabular*| and |array|.
%
% Note that the |tabular| defined here is essentially the original
% \LaTeX~2.09 version, not the extended version described in \emph{The
% \LaTeX\ Companion}. Use the |array| package to obtain the extended
% version.
%
% \StopEventually{}
%
%
% \changes{v1.0a}{1994/03/04}{Initial version, split from latex.dtx}
% \changes{v1.0a}{1994/03/07}{Long lines wrapped to 72 columns}
% \changes{v1.0b}{1994/03/28}{Improve documentation}
% \changes{v1.0c}{1994/05/07}{Removed definition of \cs{+}}
% \changes{v1.0c}{1994/05/07}{Removed surplus braces from
% \cs{@ifnextchar} constructs}
% \changes{v1.0f}{1994/05/21}{Use new error commands}
% \changes{v1.0j}{1994/11/17}
% {\cs{@tempa} to \cs{reserved@a}}
%
% \subsection{tabbing}
%
% \begin{oldcomments}
%
% \dimen(\@firsttab + i) = distance of tab stop i from left margin
% 0 <= i <= 15 (?).
%
% \dimen\@firsttab is initialized to \@totalleftmargin, so it starts
% at the prevailing left margin.
%
% \@maxtab = number of highest defined tab register
% probably = \@firsttab + 12
% \@nxttabmar = tab stop number of next line's left margin
% \@curtabmar = tab stop number of current line's left margin
% \@curtab = number of the current tab. At start of line,
% it equals \@curtabmar
% \@hightab = largest tab number currently defined.
% \@tabpush = depth of \pushtab's
%
% \box\@curline = contents of current line, excluding left margin
% skip, and excluding contents of current field
% \box\@curfield = contents of current field
%
% @rjfield = switch: T iff the last field of the line should
% be right-justified at the right margin.
%
% \tabbingsep = distance left by the \' command between the
% current position and the field that is
% ``left-shifted''.
%
% UTILITY MACROS
% \@stopfield : closes the current field
% \@addfield : adds the current field to the current line.
% \@contfield : continues the current field
% \@startfield : begins the next field
% \@stopline : closes the current line and outputs it
% \@startline : starts the next line
% \@ifatmargin : an \if that is true iff the current line.
% has width zero
%
% \@startline ==
% BEGIN
% \@curtabmar :=G \@nxttabmar
% \@curtab :=G \@curtabmar
% \box\@curline :=G null
% \@startfield
% \strut
% END
%
% \@stopline ==
% BEGIN
% \unskip
% \@stopfield
% if @rjfield = T
% then @rjfield :=G F
% \@tempdima := \@totalleftmargin + \linewidth
% \hb@xt@ \@tempdima{\@itemfudge
% \hskip \dimen\@curtabmar
% \box\@curline
% \hfil
% \box\@curfield}
% else \@addfield
% \hbox {\@itemfudge
% \hskip \dimen\@curtabmar
% \box\@curline}
% fi
% END
%
% \@startfield ==
% BEGIN
% \box\@curfield :=G \hbox {
% END
%
% \@stopfield ==
% BEGIN
% }
% END
%
% \@contfield ==
% BEGIN
% \box\@curfield :=G \hbox { \unhbox\@currfield %%} brace matching
% END
% \@addfield ==
% BEGIN
% \box\@curline :=G \unbox\@curline * \unbox\@curfield
% END
%
% \@ifatmargin ==
% BEGIN
% if dim of box\@curline = 0pt then
% END
%
%
% \tabbing ==
% BEGIN
% \lineskip :=L 0pt
% \> == \@rtab
% \< == \@ltab
% \= == \@settab
% \+ == \@tabplus
% \- == \@tabminus
% \` == \@tabrj
% \' == \@tablab
% \\ == BEGIN \@stopline \@startline END
% \\[DIST] == BEGIN
% \@stopline \vskip DIST \@startline\ignorespaces END
% \\* == BEGIN \@stopline \penalty 10000 \@startline END
% \\*[DIST] == BEGIN \@stopline \penalty 10000 \vskip DIST
% \@startline\ignorespaces END
% \@hightab := \@nxttabmar :=G \@firsttab
% \@tabpush :=G 0
% \dimen\@firsttab := \@totalleftmargin
% @rjfield :=G F
% \trivlist \item\relax
% if @minipage = F then \vskip \parskip fi
% \box\@tabfbox = \rlap{\indent\the\everypar}
% % note: \the\everypar sets @inlabel :=G F
% \@itemfudge == BEGIN \box\@tabfbox END
% \@startline
% \ignorespaces
% END
%
% \@endtabbing ==
% BEGIN
% \@stopline
% if \@tabpush > 0 then error message: ''unmatched \poptabs'' fi
% \endtrivlist
% END
%
% \@rtab ==
% BEGIN
% \@stopfield
% \@addfield
% if \@curtab < \@hightab
% then \@curtab :=G \@curtab + 1
% else error message ``Undefined Tab'' fi
% \@tempdima := \dimen\@curtab - \dimen\@curtabmar
% - width of box \@curline
% \box\@curline :=G \hbox{\unhbox\@curline + \hskip\@tempdima}
% \@startfield
% END
%
% \@settab ==
% BEGIN
% \@stopfield
% \@addfield
% if \@curtab < \@maxtab
% then \@curtab :=G \@curtab+1
% else error message: ``Too many tabs'' fi
% if \@curtab > \@hightab
% then \@hightab :=L \@curtab fi
% \dimen\@curtab :=L \dimen\@curtabmar + width of \box\@curline
% \@startfield
% END
%
% \@ltab ==
% BEGIN
% \@ifatmargin
% then if \@curtabmar > \@firsttab
% then \@curtab :=G \@curtab - 1
% \@curtabmar :=G \@curtabmar - 1
% else error message ``Too many untabs'' fi
% else error message ``Left tab in middle of line''
% fi
% END
%
% \@tabplus ==
% BEGIN
% if \@nxttabmar < \@hightab
% then \@nxttabmar :=G \@nxttabmar+1
% else error message ``Undefined tab''
% fi
% END
%
% \@tabminus ==
% BEGIN
% if \@nxttabmar > \@firsttab
% then \@nxttabmar :=G \@nxttabmar-1
% else error message ``Too many untabs''
% fi
% END
%
% \@tabrj ==
% BEGIN \@stopfield
% \@addfield
% @rjfield :=G T
% \@startfield
% END
%
% \@tablab ==
% BEGIN \@stopfield
% \box\@curline G:= \hbox{\box\@curline %% `G' added 17 Jun 86
% \hskip - width of \box\@curfield
% \hskip -\tabbingsep
% \box\@curfield
% \hskip \tabbingsep }
% \@startfield
% END
%
% \pushtabs ==
% BEGIN
% \@stopfield
% \@tabpush :=G \@tabpush + 1
% \begingroup
% \@contfield
% END
%
% \poptabs ==
% BEGIN
% \@stopfield
% if \@tabpush > 0
% then \endgroup
% \@tabpush :=G \@tabpush - 1
% else error message: ``Too many \poptabs''
% fi
% \@contfield
% END
%
% \end{oldcomments}
%
% \begin{macro}{\a}
% The accents |\`| , |\'| , and |\=| that have been redefined inside a
% tabbing environment can be called by typing |\a`| , |\a'| , and |\a=|.
% The macro |\a| is defined in |ltoutenc.dtx|.
% \changes{v1.0d}{1994/05/13}
% {moved to ltoutenc}
% \end{macro}
%
%
% The `2ekernel' code ensures that a |\usepackage{autotabg}| is
% essentially ignored if a `full' format is being used that has
% picture mode already in the format.
% \begin{macrocode}
%<2ekernel>\expandafter\let\csname ver@autotabg.sty\endcsname\fmtversion
% \end{macrocode}
%
% \begin{macro}{\@firsttab}
% \begin{macro}{\@maxtab}
% \changes{v1.0c}{1994/05/07}{Changed \cs{@firsttab} to \cs{chardef}}
% \changes{v1.0c}{1994/05/07}{Changed \cs{@maxtab} to \cs{chardef}}
% \begin{macrocode}
%<*2ekernel|autoload>
\newdimen\@gtempa
\chardef\@firsttab=\the\allocationnumber
\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
\newdimen\@gtempa
\chardef\@maxtab=\the\allocationnumber
\dimen\@firsttab=0pt
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@nxttabmar}
% \begin{macro}{\@curtabmar}
% \begin{macro}{\@curtab}
% \begin{macro}{\@hightab}
% \begin{macro}{\@tabpush}
% \begin{macrocode}
\newcount\@nxttabmar
\newcount\@curtabmar
\newcount\@curtab
\newcount\@hightab
\newcount\@tabpush
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@curline}
% \begin{macro}{\@curfield}
% \begin{macro}{\@tabfbox}
% \begin{macrocode}
\newbox\@curline
\newbox\@curfield
\newbox\@tabfbox
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
%</2ekernel|autoload>
%<*2ekernel|def>
% \end{macrocode}
%
% \begin{macro}{\if@rjfield}
% \begin{macrocode}
\newif\if@rjfield
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@startline}
% \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@nxttabmar} is never
% larger than \cs{@hightab}}
% It is, in some sense, an error if the current margin
% tab setting is higher than the value of |\@hightab| (which is
% a local variable). That this is allowed is a fundamental design
% flaw which is not going to be corrected now.
% \begin{macrocode}
\gdef\@startline{%
\ifnum \@nxttabmar >\@hightab
\@badtab
\global\@nxttabmar \@hightab
\fi
\global\@curtabmar \@nxttabmar
\global\@curtab \@curtabmar
\global\setbox\@curline \hbox {}%
\@startfield
\strut}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@stopline}
% \begin{macrocode}
\gdef\@stopline{%
\unskip
\@stopfield
\if@rjfield
\global\@rjfieldfalse
\@tempdima\@totalleftmargin
\advance\@tempdima\linewidth
\hb@xt@\@tempdima{%
\@itemfudge\hskip\dimen\@curtabmar
\box\@curline
\hfil
\box\@curfield}%
\else
\@addfield
\hbox{\@itemfudge\hskip\dimen\@curtabmar\box\@curline}%
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@startfield}
% \changes{v1.0d}{1994/05/13}
% {Colour support}
% \begin{macrocode}
\gdef\@startfield{%
\global\setbox\@curfield\hbox\bgroup\color@begingroup}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@stopfield}
% \changes{v1.0d}{1994/05/13}
% {Colour support}
% \begin{macrocode}
\gdef\@stopfield{%
\color@endgroup\egroup}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@contfield}
% \changes{v1.0d}{1994/05/13}
% {Colour support}
% \begin{macrocode}
\gdef\@contfield{%
\global\setbox\@curfield\hbox\bgroup\color@begingroup
\unhbox\@curfield}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@addfield}
% \begin{macrocode}
\gdef\@addfield{\global\setbox\@curline\hbox{\unhbox
\@curline\unhbox\@curfield}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@ifatmargin}
% \begin{macrocode}
\gdef\@ifatmargin{\ifdim \wd\@curline =\z@}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabcr}
% \begin{macrocode}
\gdef\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xtabcr}
% \begin{macrocode}
\gdef\@xtabcr{\@ifnextchar[\@itabcr{\@startline\ignorespaces}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@itabcr}
% \begin{macrocode}
\gdef\@itabcr[#1]{\vskip #1\@startline\ignorespaces}
% \end{macrocode}
%
% \begin{macrocode}
\gdef\kill{\@stopfield\@startline\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tabbing}
% \changes{v1.1f}{1995/10/23}{(CAR)Make \cs{@hightab} consistently a
% local variable}
% \changes{latex2e}{1993/12/13}{Removed optional argument of \cs{item}}
% We use |\relax| to prevent |\item| from scanning too far.
% \begin{macrocode}
\gdef\tabbing{\lineskip \z@skip\let\>\@rtab\let\<\@ltab\let\=\@settab
\let\+\@tabplus\let\-\@tabminus\let\`\@tabrj\let\'\@tablab
\let\\=\@tabcr
\@hightab\@firsttab
\global\@nxttabmar\@firsttab
\dimen\@firsttab\@totalleftmargin
\global\@tabpush\z@ \global\@rjfieldfalse
\trivlist \item\relax
\if@minipage\else\vskip\parskip\fi
% \end{macrocode}
% \changes{v1.1i}{1996/10/21}{Moved the \cs{indent} so that the
% \cs{everypar} can remove it when necessary; this is needed because
% the code for items in lists has changed (see pr/22111)}
% \begin{macrocode}
\setbox\@tabfbox\hbox{%
\rlap{\hskip\@totalleftmargin\indent\the\everypar}}%
\def\@itemfudge{\box\@tabfbox}%
\@startline\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endtabbing}
% \begin{macrocode}
\gdef\endtabbing{%
\@stopline\ifnum\@tabpush >\z@ \@badpoptabs \fi\endtrivlist}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@rtab}
% Omitted |\global| added to |\@rtab| 17 Jun 86
% \begin{macrocode}
\gdef\@rtab{\@stopfield\@addfield\ifnum \@curtab<\@hightab
\global\advance\@curtab \@ne \else\@badtab\fi
\@tempdima\dimen\@curtab
\advance\@tempdima -\dimen\@curtabmar
\advance\@tempdima -\wd\@curline
\global\setbox\@curline\hbox{\unhbox\@curline\hskip\@tempdima}%
\@startfield\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@settab}
% \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@hightab} increases
% by at most one}
% \begin{macrocode}
\gdef\@settab{\@stopfield\@addfield
\ifnum \@curtab <\@maxtab
\ifnum\@curtab =\@hightab
\advance\@hightab \@ne
\fi
\global\advance\@curtab \@ne
\else
\@latex@error{Tab overflow}\@ehd
\fi
\dimen\@curtab \dimen\@curtabmar
\advance\dimen\@curtab \wd\@curline
\@startfield
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@ltab}
% \begin{macrocode}
\gdef\@ltab{\@ifatmargin\ifnum\@curtabmar >\@firsttab
\global\advance\@curtab \m@ne \global\advance\@curtabmar\m@ne\else
\@badtab\fi\else
\@latex@error{\string\<\space in mid line}\@ehd\fi\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabplus}
% \begin{macrocode}
\gdef\@tabplus{%
\ifnum\@nxttabmar<\@hightab
\global\advance\@nxttabmar\@ne
\else
\@badtab
\fi
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabminus}
% \begin{macrocode}
\gdef\@tabminus{%
\ifnum\@nxttabmar>\@firsttab
\global\advance\@nxttabmar\m@ne
\else
\@badtab
\fi
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabrj}
% \begin{macrocode}
\gdef\@tabrj{%
\@stopfield\@addfield\global\@rjfieldtrue\@startfield\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tablab}
% |\setbox\@curline| made |\global| in |\@tablab|. 17 Jun 86
% \begin{macrocode}
\gdef\@tablab{%
\@stopfield
\global\setbox\@curline\hbox{%
\box\@curline
\hskip-\wd\@curfield \hskip-\tabbingsep
\box\@curfield
\hskip\tabbingsep}%
\@startfield
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\pushtabs}
% \begin{macrocode}
\gdef\pushtabs{%
\@stopfield\@addfield\global\advance\@tabpush \@ne \begingroup
\@contfield}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\poptabs}
% \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@curtab} is never
% larger than \cs{@hightab}}
% It is, in some sense, an error if, after the endgroup, the current
% tab setting is higher than the new value of |\@hightab| (which is
% a local variable). That this is allowed is a fundamental design
% flaw which is not going to be corrected now.
% \begin{macrocode}
\gdef\poptabs{\@stopfield\@addfield
\ifnum \@tabpush >\z@
\endgroup
\global\advance\@tabpush \m@ne
\ifnum \@curtab >\@hightab
\global \@curtab \@hightab
\@badtab
\fi
\else
\@badpoptabs
\fi
\@contfield}
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%</2ekernel|def>
% \end{macrocode}
%
% \begin{macro}{\tabbingsep}
% \begin{macrocode}
%<*2ekernel|autoload>
\newdimen\tabbingsep
%</2ekernel|autoload>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tabbing}
% \begin{macrocode}
%<*autoload>
\def\tabbing{\@autoload{tabg}\tabbing}
%</autoload>
% \end{macrocode}
% \end{macro}
%
%
% \subsection{array and tabular environments}
%
% \begin{oldcomments}
%
% ARRAY PARMETERS:
% \arraycolsep
% : half the width separating columns in an array environment
% \tabcolsep
% : half the width separating columns in a tabular environment
% \arrayrulewidth
% : width of rules
% \doublerulesep
% : space between adjacent rules in array or tabular
% \arraystretch
% : line spacing in array and tabular environments is done by
% placing a strut in every row of height and depth
% \arraystretch times the height and depth of the strut
% produced by an ordinary \strut commmand.
%
% PREAMBLE:
% The PREAMBLE argument of an array or tabular environment can
% contain the following:
% l,r,c : indicate where entry is to be placed.
% | : for vertical rule
% @{EXP} : inserts the text EXP in every column.
% \arraycolsep or \tabcolsep spacing is suppressed.
% *{N}{PRE} : equivalent to writing N copies of PRE in the preamble.
% PRE may contain *{N'}{EXP'} expressions.
% p{LEN} : makes entry in parbox of width LEN.
%
% SPECIAL ARRAY COMMANDS:
% \multicolumn{N}{FORMAT}{ITEM} : replaces the next N column
% items by ITEM, formatted according to FORMAT.
% FORMAT should contain at most one l,r or c.
% If it contains none, then ITEM is ignored.
%
% \vline : draws a vertical line the height of the current row. May
% appear in an array element entry.
% \hline : draws a horizontal line between rows. Must appear either
% before the first entry (to appear above the first row) or
% right after a \\ command. If followed by another \hline,
% then adds a \vskip of \doublerulesep.
%
% \cline[i-j] : draws horizontal lines between rows covering columns
% i through j, inclusive. Multiple commands may follow
% one another to provide lines covering several disjoint
% columns
% \extracolsep{WIDTH} : for use inside an @ in the preamble. Causes
% a WIDTH space to be added between columns for the rest
% of the columns. This is in addition to the ordinary
% intercolumn space.
%
% \array ==
% BEGIN
% \@acol == \@arrayacol
% \@classz == \@arrayclassz
% \@classiv == \@arrayclassiv
% \\ == \@arraycr
% \@halignto == NULL
% \@tabarray
% END
%
% \endarray{NAME} == BEGIN \crcr }} END
%
% \tabular ==
% BEGIN
% \@halignto == NULL
% \@tabular
% END
%
% \tabular*{WIDTH} ==
% BEGIN
% \@halignto == to WIDTH
% \@tabular
% END
%
% \@tabular ==
% BEGIN
% \leavevmode
% \hbox { $
% \@acol == \@tabacol
% \@classz == \@tabclassz
% \@classiv == \@tabclassiv
% \\ == \@tabularcr
% \@tabarray
% END
%
% \endtabular == BEGIN \crcr}} $} END
%
% \@tabarray == if next char = [ then \@array else \@array[c] fi
%
% \@array[POS]{PREAMBLE} ==
% BEGIN
% define \@arstrutbox to make \@arstrut produce strut of height
% and depth \arraystretch times the height and
% depth of a normal strut.
% \@mkpream{PREAMBLE}
% \@preamble == \halign \@halignto {\tabskip=0pt\@arstrut
% eval{\@preamble}\tabskip = 0pt\cr %%}
% \@startpbox == \@@startpbox
% \@endpbox == \@@endpbox
% if POS = t then \vtop
% else if POS = b then \vbox
% else \vcenter
% fi fi
% {
% \par ==L {} % changed 92/09/18
% \@sharp == #
% \protect == \relax
% \lineskip :=L 0pt
% \baselineskip :=L 0pt
% \@preamble
% END
%
%
% \@arraycr ==
% BEGIN
% $ %% Prevents extra space at end of row's last entry.
% if next char = [
% then \@argarraycr
% else $ \cr %% Needed to balance $
% END
%
% \@argarraycr[LENGTH] ==
% BEGIN
% $ %% Needed to balance $ of \@arraycr
% if LENGTH > 0
% then \@tempdima := depth of \@arstrutbox + LENGTH
% \vrule height 0pt width 0pt depth \@tempdima
% \cr
% else \cr \noalign{\vskip LENGTH}
% END
%
% \@tabularcr and \@argtabularcr same as \@arraycr and \@argarraycr
% except without the extra $'s.
% \end{oldcomments}
%
% \begin{macrocode}
%<*2ekernel|autoload>
% \end{macrocode}
%
% \begin{macro}{\extracolsep}
% \begin{macrocode}
\def\extracolsep#1{\tabskip #1\relax}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\array}
% \begin{macrocode}
\def\array{\let\@acol\@arrayacol \let\@classz\@arrayclassz
\let\@classiv\@arrayclassiv
\let\\\@arraycr\let\@halignto\@empty\@tabarray}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endarray}
% \begin{macro}{\endtabular}
% \begin{macro}{\endtabular*}
% \begin{macrocode}
\def\endarray{\crcr\egroup\egroup}
\def\endtabular{\crcr\egroup\egroup $\egroup}
\expandafter \let \csname endtabular*\endcsname = \endtabular
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tabular}
% \begin{macrocode}
\def\tabular{\let\@halignto\@empty\@tabular}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tabular*}
% \changes{v1.1j}{1998/05/18}{Use \cs{setlength}, so that
% calc extensions apply.}
% Note that the change to use |\setlength| slightly alters the
% timing of the expansion and use of the length in |#1| but this is
% very unlikely to have any practical effect.
% \changes{latex2e}{1993/08/05}{Replaced \cs{expandafter}\cs{def}
% by \cs{@namedef}.}
% \begin{macrocode}
\@namedef{tabular*}#1{%
\setlength\dimen@{#1}%
\edef\@halignto{to\the\dimen@}\@tabular}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabular}
% \begin{macrocode}
\def\@tabular{\leavevmode \hbox \bgroup $\let\@acol\@tabacol
\let\@classz\@tabclassz
\let\@classiv\@tabclassiv \let\\\@tabularcr\@tabarray}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabarray}
% RmS 91/11/04 added |\m@th|.
% \begin{macrocode}
\def\@tabarray{\m@th\@ifnextchar[\@array{\@array[c]}}
% \end{macrocode}
% \end{macro}
%
% RmS 1993/11/03 changed |\halign| to |\ialign| and removed superfluous
% |\tabskip| assignment
%
%
% \changes{v1.1i}{1996/10/21}{Moved the code associated with
% \cs{@mkpream} into the group provided by the box, for robustness
% (latex/2183)}
% \begin{macro}{\@array}
% \begin{macrocode}
\def\@array[#1]#2{%
\if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi
% \end{macrocode}
% \changes{LaTeX2.09}{1992/09/18}
% {Changed \cs{par} to \cs{@empty} to avoid starting new row
% e.g. after \cs{hline}}
% \begin{macrocode}
\bgroup
% \end{macrocode}
% This next bit of code sets up the strut and then builds the halign
% and its preamble according to the specification in the second
% argument.
%
% This code has been moved inside the box.
% A side effect of this has been to expose what was a buglet in the
% previous version: since the |\@arstrut| below is expanded and
% contains an |\ifmmode| then it could produce an unnecessary extra
% box in every row, thus wasting `lots of' main memory.
% \begin{macrocode}
\setbox\@arstrutbox\hbox{%
\vrule \@height\arraystretch\ht\strutbox
\@depth\arraystretch \dp\strutbox
\@width\z@}%
\@mkpream{#2}%
\edef\@preamble{%
\ialign \noexpand\@halignto
\bgroup \@arstrut \@preamble \tabskip\z@skip \cr}%
% \end{macrocode}
% That is the end of setting up the preamble; now we reset
% things before executing the halign built-up in |\@preamble|.
% The restorations could be done by introducing an extra group,
% thus saving tokens.
% \changes{v1.0k}{1994/12/08}{Add \cs{tabularnewline}}
% \changes{v1.1i}{1996/10/21}{Use \cs{set@typeset@protect}}
% \begin{macrocode}
\let\@startpbox\@@startpbox \let\@endpbox\@@endpbox
\let\tabularnewline\\%
\let\par\@empty
\let\@sharp##%
\set@typeset@protect
\lineskip\z@skip\baselineskip\z@skip
% \end{macrocode}
% If the parsing of the preamble goes wrong there my be some
% characters left which \TeX{} then tries to typeset, i.e., we
% would be in horizontal mode. That would produce an endless loop
% because the |\halign| expects vertical mode thus issues a |\par|
% but that is a no-op at this point. So we better test this case
% issue some error message and make a crude recovery by ending that
% horizontal mode with force.
% A better fix would be to ensure that we never pick up more than a
% single character token (not done).
% \changes{v1.1m}{1998/11/13}{Check for hmode to see if something
% went wrong during parsing (pr/2884)}
% \begin{macrocode}
\ifhmode \@preamerr\z@ \@@par\fi
\@preamble}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arraycr}
% Array version of |\\|.
% \begin{macrocode}
\def\@arraycr{%
${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arraycr}
% \begin{macrocode}
\def\@xarraycr{\@ifnextchar[\@argarraycr{\ifnum0=`{\fi}${}\cr}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@argarraycr}
% \begin{macrocode}
\def\@argarraycr[#1]{%
\ifnum0=`{\fi}${}\ifdim #1>\z@ \@xargarraycr{#1}\else
\@yargarraycr{#1}\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tabularnewline}
% \changes{v1.0i}{1994/11/14}{(DPC) Macro added}
% \changes{v1.0k}{1994/12/08}{(DPC) Made it \cs{relax}}
% Tabular version of |\\|.
% \begin{macrocode}
\let\tabularnewline\relax
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabularcr}
% \begin{macrocode}
\def\@tabularcr{%
{\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xtabularcr}
% \begin{macrocode}
\def\@xtabularcr{\@ifnextchar[\@argtabularcr{\ifnum0=`{\fi}\cr}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@argtabularcr}
% \begin{macrocode}
\def\@argtabularcr[#1]{%
\ifnum0=`{\fi}%
\ifdim #1>\z@
\unskip\@xargarraycr{#1}%
\else
\@yargarraycr{#1}%
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xargarraycr}
% \begin{macrocode}
\def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp \@arstrutbox
\vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@yargarraycr}
% \begin{macrocode}
\def\@yargarraycr#1{\cr\noalign{\vskip #1}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\multicolumn}
% \begin{oldcomments}
% \multicolumn{NUMBER}{FORMAT}{ITEM} ==
% BEGIN
% \multispan{NUMBER}
% \begingroup
% \@addamp == null
% \@mkpream{FORMAT}
% \@sharp == ITEM
% \protect == \relax
% \@startpbox == \@@startpbox
% \@endpbox == \@@endpbox
% \@arstrut
% \@preamble
% \endgroup
% END
% \end{oldcomments}
%
% The command |\def\@addamp{}| was removed from |\multicolumn| on
% 6 Dec 86 because it caused embedded array environments not to work. I
% think that it was included originally to prevent an error message if
% the 2nd argument to the |\multicolumn| command had two column
% specifiers.
%
% 8 Feb 89 --- |\hbox{}| added after |\@preamble| to correct bug that
% occurred if |\multicolumn| preceded |\\[D]| with |D > 0|,
% caused by |\\[]| command doing an |\unskip|, which removed
% |\tabcolsep| glue inserted by |\multicolumn|.
%
%
% \changes{v1.0h}{1994/11/04}{(ASAJ) added \cs{set@typeset@protect}.}
% \changes{v1.1i}{1996/10/21}{Make \cs{multicolumn} long (latex/2180)}
% This has been made long so that, for example, a |p|-column can
% contain multiple paragraphs; maybe the arguments of |@|-expressions
% should also be able to contain multiple paragraphs.
% \begin{macrocode}
\long\def\multicolumn#1#2#3{\multispan{#1}\begingroup
\@mkpream{#2}%
\def\@sharp{#3}\set@typeset@protect
\let\@startpbox\@@startpbox\let\@endpbox\@@endpbox
\@arstrut \@preamble\hbox{}\endgroup\ignorespaces}
% \end{macrocode}
% \end{macro}
%
% \begin{oldcomments}
% Codes for classes and character numbers of array, tabular and
% multicolumn arguments.
%
% Character Class Number
% --------- ----- ------
% c 0 0
% l 0 1
% r 0 2
%
% | 1 -
% @ 2 -
% p 3 -
% {@-exp} 4 -
% {p-arg} 5 -
%
% \@testpach \foo : expands \foo, which should be an array parameter
% token, and sets \@chclass and \@chnum to its class and
% number. Uses \@lastchclass to distinguish 4 and 5
%
% Preamble error codes
% 0: 'illegal character'
% 1: 'Missing @-exp'
% 2: 'Missing p-arg'
%
% \@addamp ==
% BEGIN if @firstamp = true then @firstamp := false
% else & fi
% END
%
% \@mkpream TOKENLIST ==
% BEGIN
% @firstamp := T
% \@lastchclass := 6
% \@preamble == null
% \@sharp == \relax
% \protect == BEGIN \noexpand\protect\noexpand END
% \@startpbox == \relax
% \@endpbox == \relax
% \@expast{TOKENLIST}
% for \@nextchar := expand(\reserved@a)
% do \@testpach{\@nextchar}
% case of \@chclass
% 0 -> \@classz
% 1 -> \@classi
% ...
% 5 -> \@classv
% end case
% \@lastchclass := \@chclass
% od
% case of \@lastchclass
% 0 -> \hskip \arraycolsep % lrc
% 1 -> % |
% 2 -> \@preamerr1 % 'Missing @-exp' % @
% 3 -> \@preamerr2 % 'Missing p-arg' % p
% 4 -> % @-exp
% 5 -> \hskip \arraycolsep % p-exp
% end case
% END
%
% \@arrayclassz ==
% BEGIN
% \@preamble := \@preamble *
% case of \@lastchclass
% 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
% 1 -> \@addamp \hskip \arraycolsep
% 2 -> % impossible
% 3 -> % impossible
% 4 -> \@addamp
% 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
% 6 -> \@addamp \hskip \arraycolsep
% end case
% * case of \@chnum
% 0 -> \hfil$\relax\@sharp$\hfil
% 1 -> $\relax\@sharp$\hfil
% 2 -> \hfil$\relax\@sharp$
% end case
% END
%
% \@tabclassz == similar to \@arrayclassz
%
% \@classi ==
% BEGIN
% \@preamble := \@preamble *
% case of \@lastchclass
% 0 -> \hskip \arraycolsep \@arrayrule
% 1 -> \hskip \doublerulesep \@arrayrule
% 2 -> % impossible
% 3 -> % impossible
% 4 -> \@arrayrule
% 5 -> \hskip \arraycolsep \@arrayrule
% 6 -> \@arrayrule
% end case
% END
%
% \@classii ==
% BEGIN
% \@preamble := \@preamble *
% case of \@lastchclass
% 0 ->
% 1 -> \hskip .5\arrayrulewidth
% 2 -> % impossible
% else ->
% end case
% END
%
% \@classiii ==
% BEGIN
% \@preamble := \@preamble *
% case of \@lastchclass
% 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
% 1 -> \@addamp \hskip \arraycolsep
% 2 -> % impossible
% 3 -> % impossible
% 4 -> \@addamp
% 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
% 6 -> \@addamp \hskip \arraycolsep
% end case
% END
%
% \@arrayclassiv ==
% BEGIN \@preamble := \@preamble * $ \@nextchar$ END
%
% \@tabclassiv == same as \@arrayclassv except without the $ ... $
%
% \@classv ==
% BEGIN
% \@preamble :=
% \@preamble * \@startpbox{\@nextchar}\ignorespaces\@sharp
% \@endpbox
% END
%
% \@expast{S}:
% Sets \reserved@a := S with all instances of *{N}{STRING}
% replaced by N copies of STRING, where N > 0. An *
% appearing inside braces is ignored, but *-expressions
% inside STRING are expanded, so nested *-expressions are
% handled properly.
%
% \@expast{S} == BEGIN \@xexpast S *0x\@@ END
%
% \@xexpast S1 *{N}{S2} S3 \@@ ==
% BEGIN
% \reserved@a := S1
% \@tempcnta := N
% if \@tempcnta > 0
% then while \@tempcnta > 0 do \reserved@a := \reserved@a S2
% \@tempcnta := \@tempcnta - 1 od
% \reserved@b == \@xexpast
% else \reserved@b == \@xexnoop
% fi
% \expandafter \reserved@b \reserved@a S3 \@@
% END
% \end{oldcomments}
%
%
% \begin{macro}{\@xexnoop}
% \begin{macrocode}
\def\@xexnoop #1\@@{}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@expast}
% \begin{macrocode}
\def\@expast#1{\@xexpast #1*0x\@@}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xexpast}
% \begin{macrocode}
\def\@xexpast#1*#2#3#4\@@{%
\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}
% \end{macro}
%
% \begin{macro}{\if@firstamp}
% \begin{macro}{\@addamp}
% \begin{macrocode}
\newif\if@firstamp
% \end{macrocode}
%
% \begin{macrocode}
\def\@addamp{%
\if@firstamp
\@firstampfalse
\else
\edef\@preamble{\@preamble &}%
\fi}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@arrayacol}
% \begin{macro}{\@tabacol}
% \begin{macro}{\@ampacol}
% \begin{macro}{\@acolampacol}
% \begin{macrocode}
\def\@arrayacol{\edef\@preamble{\@preamble \hskip \arraycolsep}}
\def\@tabacol{\edef\@preamble{\@preamble \hskip \tabcolsep}}
\def\@ampacol{\@addamp \@acol}
\def\@acolampacol{\@acol\@addamp\@acol}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@mkpream}
% \changes{v1.0h}{1994/11/04}{(ASAJ) Added \cs{@unexpandable@protect}
% to \cs{@mkpream}.}
% \begin{macrocode}
\def\@mkpream#1{\@firstamptrue\@lastchclass6
\let\@preamble\@empty
\let\protect\@unexpandable@protect
\let\@sharp\relax
\let\@startpbox\relax\let\@endpbox\relax
\@expast{#1}%
\expandafter\@tfor \expandafter
\@nextchar \expandafter:\expandafter=\reserved@a\do
{\@testpach\@nextchar
\ifcase \@chclass \@classz \or \@classi \or \@classii \or \@classiii
\or \@classiv \or\@classv \fi\@lastchclass\@chclass}%
\ifcase \@lastchclass \@acol
\or \or \@preamerr \@ne\or \@preamerr \tw@\or \or \@acol \fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arrayclassz}
% \begin{macrocode}
\def\@arrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or
\or \or \@addamp \or
\@acolampacol \or \@firstampfalse \@acol \fi
\edef\@preamble{\@preamble
\ifcase \@chnum
\hfil$\relax\@sharp$\hfil \or $\relax\@sharp$\hfil
\or \hfil$\relax\@sharp$\fi}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabclassz}
% RmS 91/08/14 inserted extra braces around entry for NFSS
% \begin{macrocode}
\def\@tabclassz{%
\ifcase\@lastchclass
\@acolampacol
\or
\@ampacol
\or
\or
\or
\@addamp
\or
\@acolampacol
\or
\@firstampfalse\@acol
\fi
\edef\@preamble{%
\@preamble{%
\ifcase\@chnum
\hfil\ignorespaces\@sharp\unskip\hfil
\or
% \end{macrocode}
% \changes{v1.1g}{1996/04/22}
% {(DPC) Extra \cs{hskip} keeps tabcolsep in empty columns
% internal/2122}
% \changes{v1.1h}{1996/06/14}
% {(DPC) Change both\cs{z@skip} to 1sp for latex/2160}
% \begin{macrocode}
\hskip1sp\ignorespaces\@sharp\unskip\hfil
\or
\hfil\hskip1sp\ignorespaces\@sharp\unskip
\fi}}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classi}
% \begin{macrocode}
\def\@classi{%
\ifcase\@lastchclass
\@acol\@arrayrule
\or
\@addtopreamble{\hskip \doublerulesep}\@arrayrule
\or
\or
\or
\@arrayrule
\or
\@acol\@arrayrule
\or
\@arrayrule
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classii}
% \begin{macrocode}
\def\@classii{%
\ifcase\@lastchclass
\or
\@addtopreamble{\hskip .5\arrayrulewidth}%
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classiii}
% \begin{macrocode}
\def\@classiii{\ifcase \@lastchclass \@acolampacol \or
\@addamp\@acol \or
\or \or \@addamp \or
\@acolampacol \or \@ampacol \fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabclassiv}
% \begin{macrocode}
\def\@tabclassiv{\@addtopreamble\@nextchar}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arrayclassiv}
% \begin{macrocode}
\def\@arrayclassiv{\@addtopreamble{$\@nextchar$}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classv}
% \begin{macrocode}
\def\@classv{\@addtopreamble{\@startpbox{\@nextchar}\ignorespaces
\@sharp\@endpbox}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@addtopreamble}
% \begin{macrocode}
\def\@addtopreamble#1{\edef\@preamble{\@preamble #1}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@chclass}
% \begin{macro}{\@lastchclass}
% \begin{macro}{\@chnum}
% \begin{macrocode}
\newcount\@chclass
\newcount\@lastchclass
\newcount\@chnum
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\arraycolsep}
% \begin{macro}{\tabcolsep}
% \begin{macro}{\arrayrulewidth}
% \begin{macro}{\doublerulesep}
% \begin{macrocode}
\newdimen\arraycolsep
\newdimen\tabcolsep
\newdimen\arrayrulewidth
\newdimen\doublerulesep
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\arraystretch}
% \begin{macrocode}
\def\arraystretch{1} % Default value.
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arstrutbox}
% \begin{macro}{\@arstrut}
% \begin{macrocode}
\newbox\@arstrutbox
% \end{macrocode}
%
% \begin{macrocode}
\def\@arstrut{%
\relax\ifmmode\copy\@arstrutbox\else\unhcopy\@arstrutbox\fi}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@arrayrule}
% \begin{macrocode}
\def\@arrayrule{\@addtopreamble{\hskip -.5\arrayrulewidth
\vrule \@width \arrayrulewidth\hskip -.5\arrayrulewidth}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@testpatch}
% \begin{macrocode}
\def\@testpach#1{\@chclass \ifnum \@lastchclass=\tw@ 4 \else
\ifnum \@lastchclass=3 5 \else
\z@ \if #1c\@chnum \z@ \else
\if #1l\@chnum \@ne \else
\if #1r\@chnum \tw@ \else
\@chclass \if #1|\@ne \else
\if #1@\tw@ \else
\if #1p3 \else \z@ \@preamerr 0\fi
\fi \fi \fi \fi \fi \fi
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\hline}
% \begin{macrocode}
\def\hline{%
\noalign{\ifnum0=`}\fi\hrule \@height \arrayrulewidth \futurelet
\reserved@a\@xhline}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xhline}
% \begin{macrocode}
\def\@xhline{\ifx\reserved@a\hline
\vskip\doublerulesep
% \end{macrocode}
% Measure from the middle of the rules.
% \changes{latex2e}{1993/12/16}{Measure from middle of vertical rules}
% \begin{macrocode}
\vskip-\arrayrulewidth
\fi
\ifnum0=`{\fi}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vline}
% \begin{macrocode}
\def\vline{\vrule \@width \arrayrulewidth}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\cline}
% \changes{v1.1c}{1995/09/14}
% {(DPC) New implementation}
% \begin{macro}{\@cline}
% The old \LaTeX2.09 implementation of |\cline| used up quite
% a lot of memory and two precious count registers.
% This new (1995/09/14) implementation does not use any count registers.
% It is coded in a way that depends heavily on the definition of
% |\multispan| so that command has been moved here from the file
% |ltplain.dtx|.
%
% These counters are no longer declared.
%\begin{verbatim}
% \newcount\@cla
% \newcount\@clb
%\end{verbatim}
%
% \begin{macrocode}
\def\cline#1{\@cline#1\@nil}
% \end{macrocode}
%
% \changes{v1.1e}{1995/10/17}
% {(DPC) Use \cs{@multicnt}}
% \begin{macrocode}
\def\@cline#1-#2\@nil{%
\omit
% \end{macrocode}
% Use the counter from |\multispan|.
% \begin{macrocode}
\@multicnt#1%
\advance\@multispan\m@ne
\ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
\@multicnt#2%
\advance\@multicnt-#1%
\advance\@multispan\@ne
% \end{macrocode}
% The original had |\unskip| at this point,
% but how could a skip get here ???
% \begin{macrocode}
\leaders\hrule\@height\arrayrulewidth\hfill
\cr
% \end{macrocode}
% This is back spacing is fairly horrible,
% but it is what happened in the old version\ldots\
% An alternative would be to make |\cline| look ahead for a following
% |\cline| as does |\hline|. This would alter the spacing in existing
% documents so keep the old version in the kernel. Perhaps a package
% should do this differently.
% \begin{macrocode}
\noalign{\vskip-\arrayrulewidth}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\mscount}
% The |\mscount| counter is no longer declared, saving a csname and a
% register. It is declared in compatibility mode.
% \end{macro}
%
% \begin{macro}{\multispan}
% \begin{macro}{\@multispan}
% \changes{v1.1e}{1995/10/17}
% {(DPC) Macro added.}
% \begin{macro}{\sp@n}
% Modify |\multispan| slightly from its plain \TeX\ definition
% to allow more efficient code sharing with |\multicolumn|.
% Also share a count register with |\multiput|.
% \begin{macrocode}
\def\multispan{\omit\@multispan}
% \end{macrocode}
%
% \begin{macrocode}
\def\@multispan#1{%
\@multicnt#1\relax
\loop\ifnum\@multicnt>\@ne \sp@n\repeat}
% \end{macrocode}
%
% \begin{macrocode}
\def\sp@n{\span\omit\advance\@multicnt\m@ne}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\@startpbox}
% \begin{macro}{\@endpbox}
% Helper macros for `p' columns.
%
% |\@startpbox|\marg{width} \emph{text} |\egroup| is essentially
% |\parbox|\marg{width}\marg{text}
%
% |\@endpbox| is essentially |\unskip \strut \par \egroup\hfil|
% (Changed 14 Jan 89) (changed again 1994/05/13)
%
% \changes{v1.0d}{1994/05/03}
% {Use \cs{@finalstrut} based on depth of \cs{@arstrutbox}}
% \changes{v1.1j}{1998/05/18}{Use \cs{setlength} to set \cs{hsize},
% so that the changes in the calc package apply here.}
% \begin{macrocode}
\def\@startpbox#1{\vtop\bgroup \setlength\hsize{#1}\@arrayparboxrestore}
% \end{macrocode}
%
% \begin{macrocode}
\def\@endpbox{\@finalstrut\@arstrutbox\par\egroup\hfil}
% \end{macrocode}
%
% 14 Jan 89: Def of |\@endpbox| changed from\\
% |\def\@endpbox{\par\vskip\dp\@arstrutbox\egroup\hfil}|\\
% so vertical spacing works out right if the last line of a `p' entry
% has a descender.
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@@startpbox}
% \begin{macro}{\@@endpbox}
% \begin{macrocode}
\let\@@startpbox=\@startpbox
\let\@@endpbox=\@endpbox
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
%</2ekernel|autoload>
% \end{macrocode}
%
% \Finale
%
|