1 % \iffalse meta-comment
4 % The LaTeX3 Project and any individual authors listed elsewhere
7 % This file is part of the LaTeX base system.
8 % -------------------------------------------
10 % It may be distributed and/or modified under the
11 % conditions of the LaTeX Project Public License, either version 1.3c
12 % of this license or (at your option) any later version.
13 % The latest version of this license is in
14 % http://www.latex-project.org/lppl.txt
15 % and version 1.3c or later is part of all distributions of LaTeX
16 % version 2005/12/01 or later.
18 % This file has the LPPL maintenance status "maintained".
20 % The list of all files belonging to the LaTeX base distribution is
21 % given in the file `manifest.txt'. See also `legal.txt' for additional
24 % The list of derived (unpacked) files belonging to the distribution
25 % and covered by LPPL is defined by the unpacking scripts (with
26 % extension .ins) which are part of the distribution.
31 %%% From File: lttab.dtx
34 \ProvidesFile{lttab.dtx}[2015/02/21 v1.1n LaTeX Kernel (Columns)]
36 \documentclass{ltxdoc}
37 \GetFileInfo{lttab.dtx}
50 \MaintainedByLaTeXTeam{latex}
59 % \changes{v1.0l}{1995/05/07}{Use \cs{hb@xt@}}
60 % \changes{v1.1a}{1995/05/22}{Support autoloading feature}
61 % \changes{v1.1b}{1995/06/14}{Use \cs{ProvidesFile} in autoload}
62 % \changes{v1.1d}{1995/10/04}{Modify autoload support}
63 % \changes{v1.1k}{1998/06/18}{Small addition to documentation}
64 % \changes{v1.1l}{1998/07/06}{Small correction to documentation}
65 % \changes{v1.1n}{2015/02/21}{Removed autoload code}
67 % \section{Tabbing, Tabular and Array Environments}
68 % This section deals with `Lining It Up in Columns'. First the
69 % |tabbing| environment is defined, and then in second part, |tabular|
70 % together with its variants, |tabular*| and |array|.
72 % Note that the |tabular| defined here is essentially the original
73 % \LaTeX~2.09 version, not the extended version described in \emph{The
74 % \LaTeX\ Companion}. Use the |array| package to obtain the extended
80 % \changes{v1.0a}{1994/03/04}{Initial version, split from latex.dtx}
81 % \changes{v1.0a}{1994/03/07}{Long lines wrapped to 72 columns}
82 % \changes{v1.0b}{1994/03/28}{Improve documentation}
83 % \changes{v1.0c}{1994/05/07}{Removed definition of \cs{+}}
84 % \changes{v1.0c}{1994/05/07}{Removed surplus braces from
85 % \cs{@ifnextchar} constructs}
86 % \changes{v1.0f}{1994/05/21}{Use new error commands}
87 % \changes{v1.0j}{1994/11/17}
88 % {\cs{@tempa} to \cs{reserved@a}}
90 % \subsection{tabbing}
94 % \dimen(\@firsttab + i) = distance of tab stop i from left margin
97 % \dimen\@firsttab is initialized to \@totalleftmargin, so it starts
98 % at the prevailing left margin.
100 % \@maxtab = number of highest defined tab register
101 % probably = \@firsttab + 12
102 % \@nxttabmar = tab stop number of next line's left margin
103 % \@curtabmar = tab stop number of current line's left margin
104 % \@curtab = number of the current tab. At start of line,
105 % it equals \@curtabmar
106 % \@hightab = largest tab number currently defined.
107 % \@tabpush = depth of \pushtab's
109 % \box\@curline = contents of current line, excluding left margin
110 % skip, and excluding contents of current field
111 % \box\@curfield = contents of current field
113 % @rjfield = switch: T iff the last field of the line should
114 % be right-justified at the right margin.
116 % \tabbingsep = distance left by the \' command between the
117 % current position and the field that is
121 % \@stopfield : closes the current field
122 % \@addfield : adds the current field to the current line.
123 % \@contfield : continues the current field
124 % \@startfield : begins the next field
125 % \@stopline : closes the current line and outputs it
126 % \@startline : starts the next line
127 % \@ifatmargin : an \if that is true iff the current line.
132 % \@curtabmar :=G \@nxttabmar
133 % \@curtab :=G \@curtabmar
134 % \box\@curline :=G null
144 % then @rjfield :=G F
145 % \@tempdima := \@totalleftmargin + \linewidth
146 % \hb@xt@ \@tempdima{\@itemfudge
147 % \hskip \dimen\@curtabmar
153 % \hskip \dimen\@curtabmar
160 % \box\@curfield :=G \hbox {
170 % \box\@curfield :=G \hbox { \unhbox\@currfield %%} brace matching
174 % \box\@curline :=G \unbox\@curline * \unbox\@curfield
179 % if dim of box\@curline = 0pt then
193 % \\ == BEGIN \@stopline \@startline END
195 % \@stopline \vskip DIST \@startline\ignorespaces END
196 % \\* == BEGIN \@stopline \penalty 10000 \@startline END
197 % \\*[DIST] == BEGIN \@stopline \penalty 10000 \vskip DIST
198 % \@startline\ignorespaces END
199 % \@hightab := \@nxttabmar :=G \@firsttab
201 % \dimen\@firsttab := \@totalleftmargin
203 % \trivlist \item\relax
204 % if @minipage = F then \vskip \parskip fi
205 % \box\@tabfbox = \rlap{\indent\the\everypar}
206 % % note: \the\everypar sets @inlabel :=G F
207 % \@itemfudge == BEGIN \box\@tabfbox END
215 % if \@tabpush > 0 then error message: ''unmatched \poptabs'' fi
223 % if \@curtab < \@hightab
224 % then \@curtab :=G \@curtab + 1
225 % else error message ``Undefined Tab'' fi
226 % \@tempdima := \dimen\@curtab - \dimen\@curtabmar
227 % - width of box \@curline
228 % \box\@curline :=G \hbox{\unhbox\@curline + \hskip\@tempdima}
236 % if \@curtab < \@maxtab
237 % then \@curtab :=G \@curtab+1
238 % else error message: ``Too many tabs'' fi
239 % if \@curtab > \@hightab
240 % then \@hightab :=L \@curtab fi
241 % \dimen\@curtab :=L \dimen\@curtabmar + width of \box\@curline
248 % then if \@curtabmar > \@firsttab
249 % then \@curtab :=G \@curtab - 1
250 % \@curtabmar :=G \@curtabmar - 1
251 % else error message ``Too many untabs'' fi
252 % else error message ``Left tab in middle of line''
258 % if \@nxttabmar < \@hightab
259 % then \@nxttabmar :=G \@nxttabmar+1
260 % else error message ``Undefined tab''
266 % if \@nxttabmar > \@firsttab
267 % then \@nxttabmar :=G \@nxttabmar-1
268 % else error message ``Too many untabs''
281 % \box\@curline G:= \hbox{\box\@curline %% `G' added 17 Jun 86
282 % \hskip - width of \box\@curfield
283 % \hskip -\tabbingsep
285 % \hskip \tabbingsep }
292 % \@tabpush :=G \@tabpush + 1
302 % \@tabpush :=G \@tabpush - 1
303 % else error message: ``Too many \poptabs''
311 % The accents |\`| , |\'| , and |\=| that have been redefined inside a
312 % tabbing environment can be called by typing |\a`| , |\a'| , and |\a=|.
313 % The macro |\a| is defined in |ltoutenc.dtx|.
314 % \changes{v1.0d}{1994/05/13}
315 % {moved to ltoutenc}
319 % The `2ekernel' code ensures that a |\usepackage{autotabg}| is
320 % essentially ignored if a `full' format is being used that has
321 % picture mode already in the format.
323 %<2ekernel>\expandafter\let\csname ver@autotabg.sty\endcsname\fmtversion
326 % \begin{macro}{\@firsttab}
327 % \begin{macro}{\@maxtab}
328 % \changes{v1.0c}{1994/05/07}{Changed \cs{@firsttab} to \cs{chardef}}
329 % \changes{v1.0c}{1994/05/07}{Changed \cs{@maxtab} to \cs{chardef}}
333 \chardef\@firsttab=\the\allocationnumber
334 \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
335 \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
336 \newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa\newdimen\@gtempa
338 \chardef\@maxtab=\the\allocationnumber
344 % \begin{macro}{\@nxttabmar}
345 % \begin{macro}{\@curtabmar}
346 % \begin{macro}{\@curtab}
347 % \begin{macro}{\@hightab}
348 % \begin{macro}{\@tabpush}
362 % \begin{macro}{\@curline}
363 % \begin{macro}{\@curfield}
364 % \begin{macro}{\@tabfbox}
375 % \begin{macro}{\if@rjfield}
381 % \begin{macro}{\@startline}
382 % \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@nxttabmar} is never
383 % larger than \cs{@hightab}}
384 % It is, in some sense, an error if the current margin
385 % tab setting is higher than the value of |\@hightab| (which is
386 % a local variable). That this is allowed is a fundamental design
387 % flaw which is not going to be corrected now.
390 \ifnum \@nxttabmar >\@hightab
392 \global\@nxttabmar \@hightab
394 \global\@curtabmar \@nxttabmar
395 \global\@curtab \@curtabmar
396 \global\setbox\@curline \hbox {}%
402 % \begin{macro}{\@stopline}
408 \global\@rjfieldfalse
409 \@tempdima\@totalleftmargin
410 \advance\@tempdima\linewidth
412 \@itemfudge\hskip\dimen\@curtabmar
418 \hbox{\@itemfudge\hskip\dimen\@curtabmar\box\@curline}%
423 % \begin{macro}{\@startfield}
424 % \changes{v1.0d}{1994/05/13}
428 \global\setbox\@curfield\hbox\bgroup\color@begingroup}
432 % \begin{macro}{\@stopfield}
433 % \changes{v1.0d}{1994/05/13}
437 \color@endgroup\egroup}
441 % \begin{macro}{\@contfield}
442 % \changes{v1.0d}{1994/05/13}
446 \global\setbox\@curfield\hbox\bgroup\color@begingroup
451 % \begin{macro}{\@addfield}
453 \gdef\@addfield{\global\setbox\@curline\hbox{\unhbox
454 \@curline\unhbox\@curfield}}
458 % \begin{macro}{\@ifatmargin}
460 \gdef\@ifatmargin{\ifdim \wd\@curline =\z@}
464 % \begin{macro}{\@tabcr}
466 \gdef\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
470 % \begin{macro}{\@xtabcr}
472 \gdef\@xtabcr{\@ifnextchar[\@itabcr{\@startline\ignorespaces}}
476 % \begin{macro}{\@itabcr}
478 \gdef\@itabcr[#1]{\vskip #1\@startline\ignorespaces}
482 \gdef\kill{\@stopfield\@startline\ignorespaces}
486 % \begin{macro}{\tabbing}
487 % \changes{v1.1f}{1995/10/23}{(CAR)Make \cs{@hightab} consistently a
489 % \changes{latex2e}{1993/12/13}{Removed optional argument of \cs{item}}
490 % We use |\relax| to prevent |\item| from scanning too far.
492 \gdef\tabbing{\lineskip \z@skip\let\>\@rtab\let\<\@ltab\let\=\@settab
493 \let\+\@tabplus\let\-\@tabminus\let\`\@tabrj\let\'\@tablab
496 \global\@nxttabmar\@firsttab
497 \dimen\@firsttab\@totalleftmargin
498 \global\@tabpush\z@ \global\@rjfieldfalse
499 \trivlist \item\relax
500 \if@minipage\else\vskip\parskip\fi
502 % \changes{v1.1i}{1996/10/21}{Moved the \cs{indent} so that the
503 % \cs{everypar} can remove it when necessary; this is needed because
504 % the code for items in lists has changed (see pr/22111)}
506 \setbox\@tabfbox\hbox{%
507 \rlap{\hskip\@totalleftmargin\indent\the\everypar}}%
508 \def\@itemfudge{\box\@tabfbox}%
509 \@startline\ignorespaces}
513 % \begin{macro}{\endtabbing}
516 \@stopline\ifnum\@tabpush >\z@ \@badpoptabs \fi\endtrivlist}
520 % \begin{macro}{\@rtab}
521 % Omitted |\global| added to |\@rtab| 17 Jun 86
523 \gdef\@rtab{\@stopfield\@addfield\ifnum \@curtab<\@hightab
524 \global\advance\@curtab \@ne \else\@badtab\fi
525 \@tempdima\dimen\@curtab
526 \advance\@tempdima -\dimen\@curtabmar
527 \advance\@tempdima -\wd\@curline
528 \global\setbox\@curline\hbox{\unhbox\@curline\hskip\@tempdima}%
529 \@startfield\ignorespaces}
533 % \begin{macro}{\@settab}
534 % \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@hightab} increases
537 \gdef\@settab{\@stopfield\@addfield
538 \ifnum \@curtab <\@maxtab
539 \ifnum\@curtab =\@hightab
540 \advance\@hightab \@ne
542 \global\advance\@curtab \@ne
544 \@latex@error{Tab overflow}\@ehd
546 \dimen\@curtab \dimen\@curtabmar
547 \advance\dimen\@curtab \wd\@curline
553 % \begin{macro}{\@ltab}
555 \gdef\@ltab{\@ifatmargin\ifnum\@curtabmar >\@firsttab
556 \global\advance\@curtab \m@ne \global\advance\@curtabmar\m@ne\else
558 \@latex@error{\string\<\space in mid line}\@ehd\fi\ignorespaces}
562 % \begin{macro}{\@tabplus}
565 \ifnum\@nxttabmar<\@hightab
566 \global\advance\@nxttabmar\@ne
574 % \begin{macro}{\@tabminus}
577 \ifnum\@nxttabmar>\@firsttab
578 \global\advance\@nxttabmar\m@ne
586 % \begin{macro}{\@tabrj}
589 \@stopfield\@addfield\global\@rjfieldtrue\@startfield\ignorespaces}
593 % \begin{macro}{\@tablab}
594 % |\setbox\@curline| made |\global| in |\@tablab|. 17 Jun 86
598 \global\setbox\@curline\hbox{%
600 \hskip-\wd\@curfield \hskip-\tabbingsep
608 % \begin{macro}{\pushtabs}
611 \@stopfield\@addfield\global\advance\@tabpush \@ne \begingroup
616 % \begin{macro}{\poptabs}
617 % \changes{v1.1f}{1995/10/23}{(CAR)Ensure that \cs{@curtab} is never
618 % larger than \cs{@hightab}}
619 % It is, in some sense, an error if, after the endgroup, the current
620 % tab setting is higher than the new value of |\@hightab| (which is
621 % a local variable). That this is allowed is a fundamental design
622 % flaw which is not going to be corrected now.
624 \gdef\poptabs{\@stopfield\@addfield
625 \ifnum \@tabpush >\z@
627 \global\advance\@tabpush \m@ne
628 \ifnum \@curtab >\@hightab
629 \global \@curtab \@hightab
640 % \begin{macro}{\tabbingsep}
648 % \subsection{array and tabular environments}
650 % \begin{oldcomments}
654 % : half the width separating columns in an array environment
656 % : half the width separating columns in a tabular environment
660 % : space between adjacent rules in array or tabular
662 % : line spacing in array and tabular environments is done by
663 % placing a strut in every row of height and depth
664 % \arraystretch times the height and depth of the strut
665 % produced by an ordinary \strut command.
668 % The PREAMBLE argument of an array or tabular environment can
669 % contain the following:
670 % l,r,c : indicate where entry is to be placed.
671 % | : for vertical rule
672 % @{EXP} : inserts the text EXP in every column.
673 % \arraycolsep or \tabcolsep spacing is suppressed.
674 % *{N}{PRE} : equivalent to writing N copies of PRE in the preamble.
675 % PRE may contain *{N'}{EXP'} expressions.
676 % p{LEN} : makes entry in parbox of width LEN.
678 % SPECIAL ARRAY COMMANDS:
679 % \multicolumn{N}{FORMAT}{ITEM} : replaces the next N column
680 % items by ITEM, formatted according to FORMAT.
681 % FORMAT should contain at most one l,r or c.
682 % If it contains none, then ITEM is ignored.
684 % \vline : draws a vertical line the height of the current row. May
685 % appear in an array element entry.
686 % \hline : draws a horizontal line between rows. Must appear either
687 % before the first entry (to appear above the first row) or
688 % right after a \\ command. If followed by another \hline,
689 % then adds a \vskip of \doublerulesep.
691 % \cline[i-j] : draws horizontal lines between rows covering columns
692 % i through j, inclusive. Multiple commands may follow
693 % one another to provide lines covering several disjoint
695 % \extracolsep{WIDTH} : for use inside an @ in the preamble. Causes
696 % a WIDTH space to be added between columns for the rest
697 % of the columns. This is in addition to the ordinary
702 % \@acol == \@arrayacol
703 % \@classz == \@arrayclassz
704 % \@classiv == \@arrayclassiv
710 % \endarray{NAME} == BEGIN \crcr }} END
718 % \tabular*{WIDTH} ==
720 % \@halignto == to WIDTH
728 % \@acol == \@tabacol
729 % \@classz == \@tabclassz
730 % \@classiv == \@tabclassiv
735 % \endtabular == BEGIN \crcr}} $} END
737 % \@tabarray == if next char = [ then \@array else \@array[c] fi
739 % \@array[POS]{PREAMBLE} ==
741 % define \@arstrutbox to make \@arstrut produce strut of height
742 % and depth \arraystretch times the height and
743 % depth of a normal strut.
744 % \@mkpream{PREAMBLE}
745 % \@preamble == \halign \@halignto {\tabskip=0pt\@arstrut
746 % eval{\@preamble}\tabskip = 0pt\cr %%}
747 % \@startpbox == \@@startpbox
748 % \@endpbox == \@@endpbox
749 % if POS = t then \vtop
750 % else if POS = b then \vbox
754 % \par ==L {} % changed 92/09/18
758 % \baselineskip :=L 0pt
765 % $ %% Prevents extra space at end of row's last entry.
768 % else $ \cr %% Needed to balance $
771 % \@argarraycr[LENGTH] ==
773 % $ %% Needed to balance $ of \@arraycr
775 % then \@tempdima := depth of \@arstrutbox + LENGTH
776 % \vrule height 0pt width 0pt depth \@tempdima
778 % else \cr \noalign{\vskip LENGTH}
781 % \@tabularcr and \@argtabularcr same as \@arraycr and \@argarraycr
782 % except without the extra $'s.
786 % \begin{macro}{\extracolsep}
788 \def\extracolsep#1{\tabskip #1\relax}
792 % \begin{macro}{\array}
794 \def\array{\let\@acol\@arrayacol \let\@classz\@arrayclassz
795 \let\@classiv\@arrayclassiv
796 \let\\\@arraycr\let\@halignto\@empty\@tabarray}
800 % \begin{macro}{\endarray}
801 % \begin{macro}{\endtabular}
802 % \begin{macro}{\endtabular*}
804 \def\endarray{\crcr\egroup\egroup}
805 \def\endtabular{\crcr\egroup\egroup $\egroup}
806 \expandafter \let \csname endtabular*\endcsname = \endtabular
812 % \begin{macro}{\tabular}
814 \def\tabular{\let\@halignto\@empty\@tabular}
818 % \begin{macro}{\tabular*}
819 % \changes{v1.1j}{1998/05/18}{Use \cs{setlength}, so that
820 % calc extensions apply.}
821 % Note that the change to use |\setlength| slightly alters the
822 % timing of the expansion and use of the length in |#1| but this is
823 % very unlikely to have any practical effect.
824 % \changes{latex2e}{1993/08/05}{Replaced \cs{expandafter}\cs{def}
827 \@namedef{tabular*}#1{%
828 \setlength\dimen@{#1}%
829 \edef\@halignto{to\the\dimen@}\@tabular}
833 % \begin{macro}{\@tabular}
835 \def\@tabular{\leavevmode \hbox \bgroup $\let\@acol\@tabacol
836 \let\@classz\@tabclassz
837 \let\@classiv\@tabclassiv \let\\\@tabularcr\@tabarray}
841 % \begin{macro}{\@tabarray}
842 % RmS 91/11/04 added |\m@th|.
844 \def\@tabarray{\m@th\@ifnextchar[\@array{\@array[c]}}
848 % RmS 1993/11/03 changed |\halign| to |\ialign| and removed superfluous
849 % |\tabskip| assignment
852 % \changes{v1.1i}{1996/10/21}{Moved the code associated with
853 % \cs{@mkpream} into the group provided by the box, for robustness
855 % \begin{macro}{\@array}
858 \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi
860 % \changes{LaTeX2.09}{1992/09/18}
861 % {Changed \cs{par} to \cs{@empty} to avoid starting new row
862 % e.g. after \cs{hline}}
866 % This next bit of code sets up the strut and then builds the halign
867 % and its preamble according to the specification in the second
870 % This code has been moved inside the box.
871 % A side effect of this has been to expose what was a buglet in the
872 % previous version: since the |\@arstrut| below is expanded and
873 % contains an |\ifmmode| then it could produce an unnecessary extra
874 % box in every row, thus wasting `lots of' main memory.
876 \setbox\@arstrutbox\hbox{%
877 \vrule \@height\arraystretch\ht\strutbox
878 \@depth\arraystretch \dp\strutbox
882 \ialign \noexpand\@halignto
883 \bgroup \@arstrut \@preamble \tabskip\z@skip \cr}%
885 % That is the end of setting up the preamble; now we reset
886 % things before executing the halign built-up in |\@preamble|.
887 % The restorations could be done by introducing an extra group,
888 % thus saving tokens.
889 % \changes{v1.0k}{1994/12/08}{Add \cs{tabularnewline}}
890 % \changes{v1.1i}{1996/10/21}{Use \cs{set@typeset@protect}}
892 \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox
893 \let\tabularnewline\\%
897 \lineskip\z@skip\baselineskip\z@skip
899 % If the parsing of the preamble goes wrong there my be some
900 % characters left which \TeX{} then tries to typeset, i.e., we
901 % would be in horizontal mode. That would produce an endless loop
902 % because the |\halign| expects vertical mode thus issues a |\par|
903 % but that is a no-op at this point. So we better test this case
904 % issue some error message and make a crude recovery by ending that
905 % horizontal mode with force.
906 % A better fix would be to ensure that we never pick up more than a
907 % single character token (not done).
908 % \changes{v1.1m}{1998/11/13}{Check for hmode to see if something
909 % went wrong during parsing (pr/2884)}
911 \ifhmode \@preamerr\z@ \@@par\fi
916 % \begin{macro}{\@arraycr}
917 % Array version of |\\|.
920 ${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr}
924 % \begin{macro}{\@arraycr}
926 \def\@xarraycr{\@ifnextchar[\@argarraycr{\ifnum0=`{\fi}${}\cr}}
930 % \begin{macro}{\@argarraycr}
932 \def\@argarraycr[#1]{%
933 \ifnum0=`{\fi}${}\ifdim #1>\z@ \@xargarraycr{#1}\else
934 \@yargarraycr{#1}\fi}
938 % \begin{macro}{\tabularnewline}
939 % \changes{v1.0i}{1994/11/14}{(DPC) Macro added}
940 % \changes{v1.0k}{1994/12/08}{(DPC) Made it \cs{relax}}
941 % Tabular version of |\\|.
943 \let\tabularnewline\relax
947 % \begin{macro}{\@tabularcr}
950 {\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr}
954 % \begin{macro}{\@xtabularcr}
956 \def\@xtabularcr{\@ifnextchar[\@argtabularcr{\ifnum0=`{\fi}\cr}}
960 % \begin{macro}{\@argtabularcr}
962 \def\@argtabularcr[#1]{%
965 \unskip\@xargarraycr{#1}%
972 % \begin{macro}{\@xargarraycr}
974 \def\@xargarraycr#1{\@tempdima #1\advance\@tempdima \dp \@arstrutbox
975 \vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr}
979 % \begin{macro}{\@yargarraycr}
981 \def\@yargarraycr#1{\cr\noalign{\vskip #1}}
985 % \begin{macro}{\multicolumn}
986 % \begin{oldcomments}
987 % \multicolumn{NUMBER}{FORMAT}{ITEM} ==
995 % \@startpbox == \@@startpbox
996 % \@endpbox == \@@endpbox
1003 % The command |\def\@addamp{}| was removed from |\multicolumn| on
1004 % 6 Dec 86 because it caused embedded array environments not to work. I
1005 % think that it was included originally to prevent an error message if
1006 % the 2nd argument to the |\multicolumn| command had two column
1009 % 8 Feb 89 --- |\hbox{}| added after |\@preamble| to correct bug that
1010 % occurred if |\multicolumn| preceded |\\[D]| with |D > 0|,
1011 % caused by |\\[]| command doing an |\unskip|, which removed
1012 % |\tabcolsep| glue inserted by |\multicolumn|.
1015 % \changes{v1.0h}{1994/11/04}{(ASAJ) added \cs{set@typeset@protect}.}
1016 % \changes{v1.1i}{1996/10/21}{Make \cs{multicolumn} long (latex/2180)}
1017 % This has been made long so that, for example, a |p|-column can
1018 % contain multiple paragraphs; maybe the arguments of |@|-expressions
1019 % should also be able to contain multiple paragraphs.
1021 \long\def\multicolumn#1#2#3{\multispan{#1}\begingroup
1023 \def\@sharp{#3}\set@typeset@protect
1024 \let\@startpbox\@@startpbox\let\@endpbox\@@endpbox
1025 \@arstrut \@preamble\hbox{}\endgroup\ignorespaces}
1029 % \begin{oldcomments}
1030 % Codes for classes and character numbers of array, tabular and
1031 % multicolumn arguments.
1033 % Character Class Number
1034 % --------- ----- ------
1045 % \@testpach \foo : expands \foo, which should be an array parameter
1046 % token, and sets \@chclass and \@chnum to its class and
1047 % number. Uses \@lastchclass to distinguish 4 and 5
1049 % Preamble error codes
1050 % 0: 'illegal character'
1051 % 1: 'Missing @-exp'
1052 % 2: 'Missing p-arg'
1055 % BEGIN if @firstamp = true then @firstamp := false
1059 % \@mkpream TOKENLIST ==
1062 % \@lastchclass := 6
1063 % \@preamble == null
1065 % \protect == BEGIN \noexpand\protect\noexpand END
1066 % \@startpbox == \relax
1067 % \@endpbox == \relax
1068 % \@expast{TOKENLIST}
1069 % for \@nextchar := expand(\reserved@a)
1070 % do \@testpach{\@nextchar}
1077 % \@lastchclass := \@chclass
1079 % case of \@lastchclass
1080 % 0 -> \hskip \arraycolsep % lrc
1082 % 2 -> \@preamerr1 % 'Missing @-exp' % @
1083 % 3 -> \@preamerr2 % 'Missing p-arg' % p
1085 % 5 -> \hskip \arraycolsep % p-exp
1091 % \@preamble := \@preamble *
1092 % case of \@lastchclass
1093 % 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
1094 % 1 -> \@addamp \hskip \arraycolsep
1098 % 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
1099 % 6 -> \@addamp \hskip \arraycolsep
1102 % 0 -> \hfil$\relax\@sharp$\hfil
1103 % 1 -> $\relax\@sharp$\hfil
1104 % 2 -> \hfil$\relax\@sharp$
1108 % \@tabclassz == similar to \@arrayclassz
1112 % \@preamble := \@preamble *
1113 % case of \@lastchclass
1114 % 0 -> \hskip \arraycolsep \@arrayrule
1115 % 1 -> \hskip \doublerulesep \@arrayrule
1119 % 5 -> \hskip \arraycolsep \@arrayrule
1126 % \@preamble := \@preamble *
1127 % case of \@lastchclass
1129 % 1 -> \hskip .5\arrayrulewidth
1137 % \@preamble := \@preamble *
1138 % case of \@lastchclass
1139 % 0 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
1140 % 1 -> \@addamp \hskip \arraycolsep
1144 % 5 -> \hskip \arraycolsep \@addamp \hskip \arraycolsep
1145 % 6 -> \@addamp \hskip \arraycolsep
1150 % BEGIN \@preamble := \@preamble * $ \@nextchar$ END
1152 % \@tabclassiv == same as \@arrayclassv except without the $ ... $
1157 % \@preamble * \@startpbox{\@nextchar}\ignorespaces\@sharp
1162 % Sets \reserved@a := S with all instances of *{N}{STRING}
1163 % replaced by N copies of STRING, where N > 0. An *
1164 % appearing inside braces is ignored, but *-expressions
1165 % inside STRING are expanded, so nested *-expressions are
1168 % \@expast{S} == BEGIN \@xexpast S *0x\@@ END
1170 % \@xexpast S1 *{N}{S2} S3 \@@ ==
1175 % then while \@tempcnta > 0 do \reserved@a := \reserved@a S2
1176 % \@tempcnta := \@tempcnta - 1 od
1177 % \reserved@b == \@xexpast
1178 % else \reserved@b == \@xexnoop
1180 % \expandafter \reserved@b \reserved@a S3 \@@
1185 % \begin{macro}{\@xexnoop}
1187 \def\@xexnoop #1\@@{}
1191 % \begin{macro}{\@expast}
1193 \def\@expast#1{\@xexpast #1*0x\@@}
1197 % \begin{macro}{\@xexpast}
1199 \def\@xexpast#1*#2#3#4\@@{%
1200 \edef\reserved@a{#1}%
1202 \ifnum\@tempcnta>\z@
1203 \@whilenum\@tempcnta>\z@\do
1204 {\edef\reserved@a{\reserved@a#3}\advance\@tempcnta \m@ne}%
1205 \let\reserved@b\@xexpast
1207 \let\reserved@b\@xexnoop
1209 \expandafter\reserved@b\reserved@a #4\@@}
1213 % \begin{macro}{\if@firstamp}
1214 % \begin{macro}{\@addamp}
1224 \edef\@preamble{\@preamble &}%
1230 % \begin{macro}{\@arrayacol}
1231 % \begin{macro}{\@tabacol}
1232 % \begin{macro}{\@ampacol}
1233 % \begin{macro}{\@acolampacol}
1235 \def\@arrayacol{\edef\@preamble{\@preamble \hskip \arraycolsep}}
1236 \def\@tabacol{\edef\@preamble{\@preamble \hskip \tabcolsep}}
1237 \def\@ampacol{\@addamp \@acol}
1238 \def\@acolampacol{\@acol\@addamp\@acol}
1245 % \begin{macro}{\@mkpream}
1246 % \changes{v1.0h}{1994/11/04}{(ASAJ) Added \cs{@unexpandable@protect}
1247 % to \cs{@mkpream}.}
1249 \def\@mkpream#1{\@firstamptrue\@lastchclass6
1250 \let\@preamble\@empty
1251 \let\protect\@unexpandable@protect
1253 \let\@startpbox\relax\let\@endpbox\relax
1255 \expandafter\@tfor \expandafter
1256 \@nextchar \expandafter:\expandafter=\reserved@a\do
1257 {\@testpach\@nextchar
1258 \ifcase \@chclass \@classz \or \@classi \or \@classii \or \@classiii
1259 \or \@classiv \or\@classv \fi\@lastchclass\@chclass}%
1260 \ifcase \@lastchclass \@acol
1261 \or \or \@preamerr \@ne\or \@preamerr \tw@\or \or \@acol \fi}
1265 % \begin{macro}{\@arrayclassz}
1267 \def\@arrayclassz{\ifcase \@lastchclass \@acolampacol \or \@ampacol \or
1268 \or \or \@addamp \or
1269 \@acolampacol \or \@firstampfalse \@acol \fi
1270 \edef\@preamble{\@preamble
1272 \hfil$\relax\@sharp$\hfil \or $\relax\@sharp$\hfil
1273 \or \hfil$\relax\@sharp$\fi}}
1277 % \begin{macro}{\@tabclassz}
1278 % RmS 91/08/14 inserted extra braces around entry for NFSS
1281 \ifcase\@lastchclass
1292 \@firstampfalse\@acol
1297 \hfil\ignorespaces\@sharp\unskip\hfil
1300 % \changes{v1.1g}{1996/04/22}
1301 % {(DPC) Extra \cs{hskip} keeps tabcolsep in empty columns
1303 % \changes{v1.1h}{1996/06/14}
1304 % {(DPC) Change both\cs{z@skip} to 1sp for latex/2160}
1306 \hskip1sp\ignorespaces\@sharp\unskip\hfil
1308 \hfil\hskip1sp\ignorespaces\@sharp\unskip
1313 % \begin{macro}{\@classi}
1316 \ifcase\@lastchclass
1319 \@addtopreamble{\hskip \doublerulesep}\@arrayrule
1332 % \begin{macro}{\@classii}
1335 \ifcase\@lastchclass
1337 \@addtopreamble{\hskip .5\arrayrulewidth}%
1342 % \begin{macro}{\@classiii}
1344 \def\@classiii{\ifcase \@lastchclass \@acolampacol \or
1346 \or \or \@addamp \or
1347 \@acolampacol \or \@ampacol \fi}
1351 % \begin{macro}{\@tabclassiv}
1353 \def\@tabclassiv{\@addtopreamble\@nextchar}
1357 % \begin{macro}{\@arrayclassiv}
1359 \def\@arrayclassiv{\@addtopreamble{$\@nextchar$}}
1363 % \begin{macro}{\@classv}
1365 \def\@classv{\@addtopreamble{\@startpbox{\@nextchar}\ignorespaces
1370 % \begin{macro}{\@addtopreamble}
1372 \def\@addtopreamble#1{\edef\@preamble{\@preamble #1}}
1376 % \begin{macro}{\@chclass}
1377 % \begin{macro}{\@lastchclass}
1378 % \begin{macro}{\@chnum}
1381 \newcount\@lastchclass
1388 % \begin{macro}{\arraycolsep}
1389 % \begin{macro}{\tabcolsep}
1390 % \begin{macro}{\arrayrulewidth}
1391 % \begin{macro}{\doublerulesep}
1393 \newdimen\arraycolsep
1395 \newdimen\arrayrulewidth
1396 \newdimen\doublerulesep
1403 % \begin{macro}{\arraystretch}
1405 \def\arraystretch{1} % Default value.
1409 % \begin{macro}{\@arstrutbox}
1410 % \begin{macro}{\@arstrut}
1417 \relax\ifmmode\copy\@arstrutbox\else\unhcopy\@arstrutbox\fi}
1422 % \begin{macro}{\@arrayrule}
1424 \def\@arrayrule{\@addtopreamble{\hskip -.5\arrayrulewidth
1425 \vrule \@width \arrayrulewidth\hskip -.5\arrayrulewidth}}
1429 % \begin{macro}{\@testpatch}
1431 \def\@testpach#1{\@chclass \ifnum \@lastchclass=\tw@ 4 \else
1432 \ifnum \@lastchclass=3 5 \else
1433 \z@ \if #1c\@chnum \z@ \else
1434 \if #1l\@chnum \@ne \else
1435 \if #1r\@chnum \tw@ \else
1436 \@chclass \if #1|\@ne \else
1438 \if #1p3 \else \z@ \@preamerr 0\fi
1439 \fi \fi \fi \fi \fi \fi
1444 % \begin{macro}{\hline}
1447 \noalign{\ifnum0=`}\fi\hrule \@height \arrayrulewidth \futurelet
1448 \reserved@a\@xhline}
1452 % \begin{macro}{\@xhline}
1454 \def\@xhline{\ifx\reserved@a\hline
1455 \vskip\doublerulesep
1457 % Measure from the middle of the rules.
1458 % \changes{latex2e}{1993/12/16}{Measure from middle of vertical rules}
1460 \vskip-\arrayrulewidth
1466 % \begin{macro}{\vline}
1468 \def\vline{\vrule \@width \arrayrulewidth}
1472 % \begin{macro}{\cline}
1473 % \changes{v1.1c}{1995/09/14}
1474 % {(DPC) New implementation}
1475 % \begin{macro}{\@cline}
1476 % The old \LaTeX2.09 implementation of |\cline| used up quite
1477 % a lot of memory and two precious count registers.
1478 % This new (1995/09/14) implementation does not use any count registers.
1479 % It is coded in a way that depends heavily on the definition of
1480 % |\multispan| so that command has been moved here from the file
1483 % These counters are no longer declared.
1490 \def\cline#1{\@cline#1\@nil}
1493 % \changes{v1.1e}{1995/10/17}
1494 % {(DPC) Use \cs{@multicnt}}
1496 \def\@cline#1-#2\@nil{%
1499 % Use the counter from |\multispan|.
1502 \advance\@multispan\m@ne
1503 \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
1505 \advance\@multicnt-#1%
1506 \advance\@multispan\@ne
1508 % The original had |\unskip| at this point,
1509 % but how could a skip get here ???
1511 \leaders\hrule\@height\arrayrulewidth\hfill
1514 % This is back spacing is fairly horrible,
1515 % but it is what happened in the old version\ldots\
1516 % An alternative would be to make |\cline| look ahead for a following
1517 % |\cline| as does |\hline|. This would alter the spacing in existing
1518 % documents so keep the old version in the kernel. Perhaps a package
1519 % should do this differently.
1521 \noalign{\vskip-\arrayrulewidth}}
1526 % \begin{macro}{\mscount}
1527 % The |\mscount| counter is no longer declared, saving a csname and a
1528 % register. It is declared in compatibility mode.
1531 % \begin{macro}{\multispan}
1532 % \begin{macro}{\@multispan}
1533 % \changes{v1.1e}{1995/10/17}
1534 % {(DPC) Macro added.}
1535 % \begin{macro}{\sp@n}
1536 % Modify |\multispan| slightly from its plain \TeX\ definition
1537 % to allow more efficient code sharing with |\multicolumn|.
1538 % Also share a count register with |\multiput|.
1540 \def\multispan{\omit\@multispan}
1546 \loop\ifnum\@multicnt>\@ne \sp@n\repeat}
1550 \def\sp@n{\span\omit\advance\@multicnt\m@ne}
1557 % \begin{macro}{\@startpbox}
1558 % \begin{macro}{\@endpbox}
1559 % Helper macros for `p' columns.
1561 % |\@startpbox|\marg{width} \emph{text} |\egroup| is essentially
1562 % |\parbox|\marg{width}\marg{text}
1564 % |\@endpbox| is essentially |\unskip \strut \par \egroup\hfil|
1565 % (Changed 14 Jan 89) (changed again 1994/05/13)
1567 % \changes{v1.0d}{1994/05/03}
1568 % {Use \cs{@finalstrut} based on depth of \cs{@arstrutbox}}
1570 % \changes{v1.1j}{1998/05/18}{Use \cs{setlength} to set \cs{hsize},
1571 % so that the changes in the calc package apply here.}
1573 \def\@startpbox#1{\vtop\bgroup \setlength\hsize{#1}\@arrayparboxrestore}
1577 \def\@endpbox{\@finalstrut\@arstrutbox\par\egroup\hfil}
1580 % 14 Jan 89: Def of |\@endpbox| changed from\\
1581 % |\def\@endpbox{\par\vskip\dp\@arstrutbox\egroup\hfil}|\\
1582 % so vertical spacing works out right if the last line of a `p' entry
1587 % \begin{macro}{\@@startpbox}
1588 % \begin{macro}{\@@endpbox}
1590 \let\@@startpbox=\@startpbox
1591 \let\@@endpbox=\@endpbox