1 % \iffalse meta-comment
5 % The LaTeX3 Project and any individual authors listed elsewhere
8 % This file is part of the Standard LaTeX `Tools Bundle'.
9 % -------------------------------------------------------
11 % It may be distributed and/or modified under the
12 % conditions of the LaTeX Project Public License, either version 1.3c
13 % of this license or (at your option) any later version.
14 % The latest version of this license is in
15 % http://www.latex-project.org/lppl.txt
16 % and version 1.3c or later is part of all distributions of LaTeX
17 % version 2005/12/01 or later.
19 % The list of all files belonging to the LaTeX `Tools Bundle' is
20 % given in the file `manifest.txt'.
23 %\iffalse % this is a METACOMMENT !
25 %% Package `array' to use with LaTeX 2e
26 %% Copyright (C) 1989-1998 Frank Mittelbach, all rights reserved.
27 %<+package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
28 %<+package>\ProvidesPackage{array}
29 %<+package> [2016/10/06 v2.4d Tabular extension package (FMi)]
36 % \changes{v2.4c}{2008/09/09}{(WR) Typo fix in documentation}
38 % \changes{v2.3c}{1995/11/02}{(DPC) minor doc changes}
40 % \changes{v2.3a}{1994/10/16}{Added code for \cs{firsthline} and
43 % \changes{v2.2c}{1994/03/14}{removed check for \cs{@tfor} bug}
45 % \changes{v1.0b}{1987/06/04}{`@classi (faster),
46 % `@classvi (new) A in preamble means
49 % \changes{v1.1a}{1987/07/05}{New concept:
50 % preamblechar: c,l,r,C,L,R,A,p,t,{\tt !|},@,!!}
51 % \changes{v1.1b}{1987/09/21}{Again p like original \LaTeX{} and z for
54 % \changes{v1.2a}{1987/09/27}{Completely new implementation.}
55 % \changes{v1.2b}{1987/10/06}{{\tt !|} does no longer generate space at
56 % start or end of the preamble. Otherwise `hline
58 % \changes{v1.2b}{1987/10/06}{Enlarged `@arstrutbox by 1pt (Test-Impl)
59 % with dimen `@strutheight.}
60 % \changes{v1.2c}{1987/10/22}{New dimen parameter `extrarowheight
62 % \changes{v1.2c}{1987/10/22}{Enlarged `@arstrutbox by `extrarowheight.
63 % Thus you may avoid large characters to
64 % overprint a `hline.}
65 % \changes{v1.2c}{1987/10/22}{Introduced `m@th in `@array to allow
66 % non-zero values of `mathsurround.}
67 % \changes{v1.2d}{1987/11/02}{Completed the documentation.}
68 % \changes{v1.2e}{1987/11/03}{Bug fixed: A at start of preamble resulted
69 % in an error since `@mkpream generated
70 % `@arstrut \& ... as a preamble.}
71 % \changes{v1.2f}{1987/11/09}{`@testpach documented.}
73 % \changes{v1.3a}{1987/11/11}{Again a new implementation, with a new
74 % concept (cf. the documentation).}
75 % \changes{v1.3b}{1988/03/17}{`@decl expands now into `@empty, i.e., it
76 % disappears when the preamble is generated,
77 % except when the user specifies A\{\} or
80 % \changes{v1.4a}{1988/03/18}{Test implementation of use of token
81 % registers in order to do without `protect.}
82 % \changes{v1.4b}{1988/03/19}{Changed erroneous class numbers:
86 % Corresponding changes in the macros.}
87 % \changes{v1.4c}{1988/03/19}{Everything except p,z now works with token
90 % \changes{v1.9a}{1988/03/20}{Last (so I hope) major change: 1) Options
91 % B,A now called !>,<. These options now point
92 % to the column they modify.}
93 % \changes{v1.9a}{1988/03/20}{2) `protect is no longer necessary. But
94 % still the macro `@expast needs top be
95 % modified. `multicolumn still does not work.}
96 % \changes{v1.9b}{1988/04/29}{inserted missing `fi in `@testpach.
97 % Corrected \LaTeX bug in `@tfor.}
98 % \changes{v1.9c}{1988/05/07}{Re-introduced `@endpbox.
99 % `multicolumn now works!! Version number still
100 % 1.9 since the documentation is still not
102 % \changes{v1.9c}{1988/05/07}{1) `def `the@toks \{`the ...\} remaining
103 % only in `@mkpream. 2) Removed `@classiii and
104 % replaced by `save@decl.}
105 % \changes{v1.9c}{1988/05/07}{3) `insert@column contains only `@tempcnta
106 % and `count@ counters. 4) `@@startpbox and
107 % `@@endpbox now totally obsolete.}
108 % \changes{v1.9d}{1988/05/10}{Replaced `number by `the where the `toks
109 % registers' contents are used.}
110 % \changes{v1.9e}{1988/05/11}{Re-introduced `@xargarraycr and
111 % `@yargarraycr, since `endtemplate seems to
113 % \changes{v1.9f}{1988/05/20}{Small changes finally carried out:
115 % 2) \{..ifnum0!=!`\}... $\to$ `bgroup and
116 % analogously `egroup.}
117 % \changes{v1.9g}{1988/02/24}{Inserted again \{..ifnum0!=!`\}..,
118 % c.f. Appendix D of the \protect\TeX{}book.}
119 % \changes{v1.9h}{1988/06/28}{No longer necessary to read in the file
121 % \changes{v1.9i}{1988/06/28}{Corrected typo in german version.}
122 % \changes{v1.9j}{1988/11/23}{In a `r' column an extra `kern`z@ is
124 % \changes{v1.9j}{1988/11/23}{Otherwise the `hfil on the left side
125 % will be removed by the `unskip in
126 % `insert@column if the entry is empty.}
127 % \changes{v1.9k}{1988/06/28}{Corrected typo in german version.}
128 % \changes{v1.9k}{1989/01/16}{`begin{Macro} changed to `begin{macro} in
131 % \changes{v2.0a}{1989/05/12}{{\tt\textbackslash @thetoks} changed to
132 % {\tt\textbackslash the@toks}.}
133 % \changes{v2.0a}{1989/05/12}{source changed to reflect new doc.sty
135 % \changes{v2.0a}{1989/05/12}{t option renamed to p to be compatible to
137 % \changes{v2.0a}{1989/05/12}{File renamed from arraye.sty to
139 % \changes{v2.0b}{1989/05/17}{Three forgotten end macro added.}
140 % \changes{v2.0b}{1989/05/17}{All lines shortened to 72 or less.}
141 % \changes{v2.2a}{1994/02/03}{Upgrade to \LaTeXe}
143 % \DoNotIndex{\@depth,\@ehc,\@fortmp,\@height,\@ifnextchar,\@ifstar}
144 % \DoNotIndex{\@ifundefined,\@ne,\@nil,\@tempa,\@tempb}
145 % \DoNotIndex{\@tempcnta,\@tempd,\@tempdima,\@whilenum,\@width,\\}
146 % \DoNotIndex{\@tforloop}
147 % \DoNotIndex{\advance}
148 % \DoNotIndex{\baselineskip,\begingroup,\bgroup}
149 % \DoNotIndex{\cr,\crcr,\csname}
150 % \DoNotIndex{\def,\do,\docdate,\dp}
151 % \DoNotIndex{\edef,\egroup,\else,\endcsname,\endinput,\expandafter}
152 % \DoNotIndex{\fi,\filedate,\fileversion}
154 % \DoNotIndex{\hbox,\hfil,\hsize,\hskip,\ht}
155 % \DoNotIndex{\if,\ifcase,\ifdim,\ifnum,\ifx,\ignorespaces}
157 % \DoNotIndex{\leavevmode,\let,\lineskip}
158 % \DoNotIndex{\m@ne,\multispan}
159 % \DoNotIndex{\newcount,\newdimen,\noalign}
161 % \DoNotIndex{\relax}
162 % \DoNotIndex{\setbox,\space,\strutbox}
163 % \DoNotIndex{\tabskip,\thr@@,\the,\toks,\toks@,\tw@,\typeout}
164 % \DoNotIndex{\unhcopy,\unskip}
165 % \DoNotIndex{\vbox,\vcenter,\vline,\vrule,\vtop,\vskip}
169 % \GetFileInfo{array.sty}
171 % \title{A new implementation of \LaTeX's \textsf{tabular}
172 % and \textsf{array} environment\thanks{This file
173 % has version number \fileversion, last
174 % revised \filedate.}}
175 % \author{Frank Mittelbach
177 % David Carlisle\thanks{David kindly agreed on the inclusion
178 % of the \texttt{\textbackslash{}newcolumntype} implementation,
180 % \texttt{newarray.sty} into this package }}
182 % \date{Printed \today}
184 % \MaintainedByLaTeXTeam{tools}
190 % This article describes an extended implementation of the \LaTeX\
191 % \textsf{array}-- and \textsf{tabular}--environments. The special
192 % merits of this implementation are further options to format columns
193 % and the fact that fragile \LaTeX--commands don't have to be
194 % =\protect='ed any more within those environments.
196 % The major part of the code for this package dates back to 1988---so
197 % does some of its documentation.
202 % \section{Introduction}
204 % This new implementation of the \textsf{array}-- and
205 % \textsf{tabular}--environments is part of a larger project in which
206 % we are trying to improve the \LaTeX\--code in some aspects and to
207 % make \LaTeX\ even easier to handle.
209 % The reader should be familiar with the general structure of the
211 % mentioned above. Further information can be found in
212 % \cite{bk:lamport} and \cite{bk:GMS94}.
213 % The additional options which can be used in the
214 % preamble as well as those which now have a slightly different meaning
215 % are described in table~\ref{tab:opt}.
217 % \DescribeMacro\extrarowheight
218 % Additionally we introduce a new
219 % parameter called =\extrarowheight=. If it takes a positive
220 % length, the value of the parameter is added to the normal height of
221 % every row of the table, while
222 % the depth will remain the same. This is important for tables
223 % with horizontal lines because those lines normally touch the
225 % For example, we used =\setlength{\extrarowheight}{1pt}=
226 % in table~\ref{tab:opt}.
230 % \setlength{\extrarowheight}{1pt}
231 % \begin{tabular}{|>{\tt}c|m{9cm}|}
233 % \multicolumn{2}{|c|}{Unchanged options}\\
235 % l & Left adjusted column. \\
236 % c & Centered adjusted column. \\
237 % r & Right adjusted column. \\
238 % p\{width\} & Equivalent to =\parbox[t]{width}=. \\
239 % @\{decl.\} & Suppresses inter-column space and inserts
240 % \texttt{decl.}\ instead. \\
242 % \multicolumn{2}{|c|}{New options}\\
244 % m\{width\} & Defines a column of width \texttt{width}.
245 % Every entry will be centered in proportion to
246 % the rest of the line. It is somewhat like
247 % =\parbox{width}=. \\
249 % b\{width\} & Coincides with =\parbox[b]{width}=. \\
251 % >\{decl.\} & Can be used before an \texttt{l}, \texttt{r},
252 % \texttt{c}, \texttt{p}, \texttt{m} or a
253 % \texttt{b} option. It inserts \texttt{decl.}\
254 % directly in front of the entry of the column.
257 % <\{decl.\} & Can be used after an \texttt{l}, \texttt{r},
258 % \texttt{c}, =p{..}=, =m{..}= or a =b{..}=
259 % option. It inserts \texttt{decl.}\ right
260 % after the entry of the column. \\
262 % | & Inserts a vertical line. The distance between
263 % two columns will be enlarged by the width of
265 % in contrast to the original definition of
268 % !\{decl.\} & Can be used anywhere and corresponds with the
269 % \texttt{|} option. The difference is that
270 % \texttt{decl.} is inserted instead of a
271 % vertical line, so this option doesn't
272 % suppress the normally inserted space between
273 % columns in contrast to =@{...}=.\\
277 % \caption{The preamble options.} \label{tab:opt}
281 % We will discuss a few examples using the new preamble options before
282 % dealing with the implementation.
285 % If you want to use a special font (for example =\bfseries=) in a
286 % flushed left column, this can be done with =>{\bfseries}l=. You
287 % do not have to begin every entry of the column with =\bfseries=
290 % In columns which have been generated with \texttt{p}, \texttt{m}
291 % or \texttt{b}, the default value of =\parindent= is
293 % This can be changed with \\
294 % =>{\setlength{\parindent}{1cm}}p=.
296 % The \texttt{>}-- and \texttt{<}--options were originally
297 % developed for the following application:
298 % =>{$}c<{$}= generates a column in math
299 % mode in a \textsf{tabular}--environment. If you use this type
300 % of a preamble in an \textsf{array}--environment, you get a
301 % column in LR mode because the additional \$'s cancel the
304 % One can also think of more complex applications. A problem
306 % been mentioned several times in \TeX{}hax can be solved with
307 % =>{\centerdots}c=\linebreak[0]=<{\endcenterdots}=.
308 % To center decimals at their
309 % decimal points you (only?) have to define the following macros:
311 %{\catcode`\.\active\gdef.{\egroup\setbox2\hbox\bgroup}}
312 %\def\centerdots{\catcode`\.\active\setbox0\hbox\bgroup}
313 %\def\endcenterdots{\egroup\ifvoid2 \setbox2\hbox{0}\fi
314 % \ifdim \wd0>\wd2 \setbox2\hbox to\wd0{\unhbox2\hfill}\else
315 % \setbox0\hbox to\wd2{\hfill\unhbox0}\fi
316 % \catcode`\.12 \box0.\box2}
318 % Warning: The code is bad, it doesn't work with more than one
319 % dot in a cell and doesn't work when the tabular is used in the
320 % argument of some other command. A much better version is
321 % provided in the \texttt{dcolumn.sty} by David Carlisle.
323 % Using =c!{\hspace{1cm}}c= you get space between two
324 % columns which is enlarged by one centimeter, while
325 % =c@{\hspace{1cm}}c= gives you exactly one centimeter
326 % space between two columns.
329 % \subsection{Defining new column specifiers}
331 % \DeleteShortVerb{\=}
333 % \DescribeMacro{\newcolumntype}
334 % Whilst it is handy to be able to type
336 % ">{"\meta{some declarations}"}{c}<{"\meta{some more
339 % if you have a one-off column in a table, it is rather inconvenient
340 % if you often use columns of this form. The new version allows you
341 % to define a new column specifier, say \texttt{x}, which will expand to
342 % the primitives column specifiers.\footnote{This command was named
343 % \texttt{\textbackslash{}newcolumn} in the \texttt{newarray.sty}.
344 % At the moment \texttt{\textbackslash{}newcolumn} is still supported
345 % (but gives a warning). In later releases it will vanish.} Thus we
348 % "\newcolumntype{x}{>{"\meta{some declarations}"}{c}<{"\meta{some
349 % more declarations}"}}"\hspace*{-3cm} ^^A no overfull from this line
351 % One can then use the \texttt{x} column specifier in the preamble
352 % arguments of all \texttt{array} or \texttt{tabular} environments in
353 % which you want columns of this form.
355 % It is common to need math-mode and LR-mode columns in the same
356 % alignment. If we define:
358 % "\newcolumntype{C}{>{$}c<{$}}" \\
359 % "\newcolumntype{L}{>{$}l<{$}}" \\
360 % "\newcolumntype{R}{>{$}r<{$}}"
362 % Then we can use \texttt{C} to get centred LR-mode in an
363 % \texttt{array}, or centred math-mode in a \texttt{tabular}.
365 % The example given above for `centred decimal points' could be
366 % assigned to a \texttt{d} specifier with the following command.
368 % "\newcolumntype{d}{>{\centerdots}c<{\endcenterdots}}"
371 % The above solution always centres the dot in the
372 % column. This does not look too good if the column consists of large
373 % numbers, but to only a few decimal places. An alternative definition
374 % of a \texttt{d} column is
376 % "\newcolumntype{d}[1]{>{\rightdots{#1}}r<{\endrightdots}}"
378 % where the appropriate macros in this case are:\footnote{The package
379 % \texttt{dcolumn.sty} contains more robust macros based on these
382 % \def\coldot{.}% Or if you prefer, \def\coldot{\cdot}
383 % {\catcode`\.=\active
384 % \gdef.{$\egroup\setbox2=\hbox to \dimen0 \bgroup$\coldot}}
386 % \setbox0=\hbox{$1$}\dimen0=#1\wd0
387 % \setbox0=\hbox{$\coldot$}\advance\dimen0 \wd0
388 % \setbox2=\hbox to \dimen0 {}%
389 % \setbox0=\hbox\bgroup\mathcode`\.="8000 $}
390 % \def\endrightdots{$\hfil\egroup\box0\box2}
392 % Note that "\newcolumntype" takes the same optional argument as
393 % "\newcommand" which declares the number of arguments of the column
394 % specifier being defined. Now we can specify "d{2}" in our preamble
395 % for a column of figures to at most two decimal places.
397 % A rather different use of the "\newcolumntype" system takes
398 % advantage of the fact that the replacement text in the
399 % "\newcolumntype" command may refer to more than one column. Suppose
400 % that a document contains a lot of \texttt{tabular} environments that
401 % require the same preamble, but you wish to experiment with different
402 % preambles. Lamport's original definition allowed you to do the
403 % following (although it was probably a mis-use of the system).
405 % "\newcommand{\X}{clr}"\\
406 % "\begin{tabular}{\X}" \ldots
408 % \texttt{array.sty} takes great care \textbf{not} to expand the
409 % preamble, and so the above does not work with the new scheme. With
410 % the new version this functionality is returned:
412 % "\newcolumntype{X}{clr}"\\
413 % "\begin{tabular}{X}" \ldots
416 % The replacement text in a "\newcolumntype" command may refer to any of
417 % the primitives of \texttt{array.sty} see table \ref{tab:opt} on page
418 % \pageref{tab:opt}, or to any new letters defined in other
419 % "\newcolumntype" commands.
422 % \DescribeMacro{\showcols}A list of all the currently active
423 % "\newcolumntype" definitions is sent to the terminal and log file if
424 % the "\showcols" command is given.
427 % \subsection{Special variations of \texttt{\textbackslash hline}}
429 % The family of \texttt{tabular} environments allows
430 % vertical positioning with respect to the baseline of
431 % the text in which the environment appears. By default the
432 % environment appears centered, but this can be changed to
433 % align with the first or last line in the environment by
434 % supplying a \texttt{t} or \texttt{b} value to the
435 % optional position argument. However, this does not work
436 % when the first or last element in the environment is a
437 % "\hline" command---in that case the environment is
438 % aligned at the horizontal rule.
442 % Here is an example:
444 % \begin{minipage}[t]{.4\linewidth}
446 % \begin{tabular}[t]{l}
447 % with no\\ hline \\ commands \\ used
448 % \end{tabular} versus \\ tables
449 % \begin{tabular}[t]{|l|}
451 % with some \\ hline \\ commands \\
453 % \end{tabular} used.
455 % \begin{minipage}[t]{.5\linewidth}
458 % \begin{tabular}[t]{l}
459 % with no\\ hline \\ commands \\ used
460 % \end{tabular} versus tables
461 % \begin{tabular}[t]{|l|}
463 % with some \\ hline \\ commands \\
465 % \end{tabular} used.
470 % \DescribeMacro\firsthline
471 % \DescribeMacro\lasthline
472 % Using "\firsthline" and "\lasthline" will
473 % cure the problem, and the tables will align properly as long
474 % as their first or last line does not contain extremely large
477 % \begin{minipage}[t]{.4\linewidth}
479 % \begin{tabular}[t]{l}
480 % with no\\ line \\ commands \\ used
481 % \end{tabular} versus \\ tables
482 % \begin{tabular}[t]{|l|}
484 % with some \\ line \\ commands \\
486 % \end{tabular} used.
488 % \begin{minipage}[t]{.5\linewidth}
491 % \begin{tabular}[t]{l}
492 % with no\\ line \\ commands \\ used
493 % \end{tabular} versus tables
494 % \begin{tabular}[t]{|l|}
496 % with some \\ line \\ commands \\
498 % \end{tabular} used.
502 % \DescribeMacro\extratabsurround
503 % The implementation of these two commands contains an extra
504 % dimension, which is called "\extratabsurround", to add some
505 % additional space at the top and the bottom of such an environment.
506 % This is useful if such tables are nested.
508 % \section{Final Comments}
510 % \subsection{Handling of rules}
512 % There are two possible approaches to the handling of horizontal and
513 % vertical rules in tables:
515 % \item rules can be placed into the available space without
516 % enlarging the table, or
517 % \item rules can be placed between columns or rows thereby enlarging
520 % \texttt{array.sty} implements the second possibility while the
521 % default implementation in the \LaTeX{} kernel implements the first
522 % concept. Both concepts have their merits but one has to be aware of
523 % the individual implications.
526 % With standard \LaTeX{} adding rules to a table will not affect the
527 % width or height of the table (unless double rules are used), e.g.,
528 % changing a preamble from \verb=lll= to \verb=l|l|l= does not
529 % affect the document other than adding rules to the table. In
530 % contrast, with \texttt{array.sty} a table that just fit the
531 % \verb=\textwidth= might now produce an overfull box.
533 % With standard \LaTeX{} modifying the width of rules could result
534 % in ugly looking tables because without adjusting the
535 % \verb=\tabcolsep=, etc.\ the space between rule and column could
536 % get too small (or too large). In fact even overprinting of text is
537 % possible. In contrast, with \texttt{array.sty} modifying any such
538 % length usually works well as the actual visual white space (from
539 % \verb=\tabcolsep=, etc.) does not depend on the width of the
542 % With standard \LaTeX{} boxed tabulars actually have strange
543 % corners because the horizontal rules end in the middle of the
544 % vertical ones. This looks very unpleasant when a large
545 % \verb=\arrayrulewidth= is chosen. In that case a simple table like
547 %\setlength{\arrayrulewidth}{5pt}
548 %\begin{tabular}{|l|}
552 % will produce something like
554 %\setlength{\arrayrulewidth}{5pt}
555 %\begin{tabular}{@{}l@{}}
556 % \hline \null\hskip-.5\arrayrulewidth\vline
559 % \vline\hskip-.5\arrayrulewidth\null \\ \hline
564 %\begin{tabular}{|l|}
570 % \subsection{Comparisons with older versions of \texttt{array.sty}}
572 % There are some differences in the way version 2.1 treats incorrect
573 % input, even if the source file does not appear to use any of the
574 % extra features of the new version.
576 % \item A preamble of the form "{wx*{0}{abc}yz}" was treated by
577 % versions prior to 2.1 as "{wx}". Version 2.1 treats it as "{wxyz}"
578 % \item An incorrect positional argument such as \texttt{[Q]} was
579 % treated as \texttt{[c]} by \texttt{array.sty}, but is now treated as
581 % \item A preamble such as "{cc*{2}}" with an error in
582 % a $*$-form will generate different errors in the new version. In
583 % both cases the error message is not particularly helpful to the
585 % \item Repeated \texttt{<} or \texttt{>} constructions
586 % generated an error in earlier versions, but are now allowed in
587 % this package. ">{"\meta{decs1}"}>{"\meta{decs2}"}" is treated the
588 % same as ">{"\meta{decs2}\meta{decs1}"}".
589 % \item The "\extracolsep"
590 % command does not work with the old versions of \texttt{array.sty},
591 % see the comments in \texttt{array.bug}. With version 2.1
592 % "\extracolsep" may again be used in \texttt{@}-expressions as in
593 % standard \LaTeX, and also in \texttt{!}-expressions (but see the
598 % \subsection{Bugs and Features}
601 % \item Error messages generated when parsing the column specification
602 % refer to the preamble argument \textbf{after} it has been re-written
603 % by the "\newcolumntype" system, not to the preamble entered by the
604 % user. This seems inevitable with any system based on
605 % pre-processing and so is classed as a \textbf{feature}.
607 % \item The treatment of multiple \texttt{<} or \texttt{>}
608 % declarations may seem strange at first. Earlier implementations
609 % treated ">{"\meta{decs1}"}>{"\meta{decs2}"}" the same as
610 % ">{"\meta{decs1}\meta{decs2}"}". However this did not give the
611 % user the opportunity of overriding the settings of a
612 % "\newcolumntype" defined using these declarations. For example,
613 % suppose in an \texttt{array} environment we use a \texttt{C}
614 % column defined as above. The \texttt{C} specifies a centred text
615 % column, however ">{\bfseries}C", which re-writes to
616 % ">{\bfseries}>{$}c<{$}" would not specify a bold column as might
617 % be expected, as the preamble would essentially expand to
618 % "\hfil$\bfseries$#$ $\hfil" and so the column entry would not be in the
619 % scope of the "\bfseries"\,! The present version switches the order
620 % of repeated declarations, and so the above example now produces a
621 % preamble of the form "\hfil$" "$\bfseries#$" "$\hfil", and the
622 % dollars cancel each other out without limiting the scope of the
625 % \item The use of "\extracolsep" has been subject to the following
626 % two restrictions. There must be at most one "\extracolsep"
627 % command per "@", or "!" expression and the command must be
628 % directly entered into the "@" expression, not as part of a macro
629 % definition. Thus "\newcommand{\ef}{\extracolsep{\fill}}" \ldots
630 % "@{\ef}" does not work with this package. However you can use
632 % "\newcolumntype{e}{@{\extracolsep{\fill}}" instead.
634 % \item As noted by the \LaTeX{} book, for the purpose of
635 % "\multicolumn" each column with the exception of the first one
636 % consists of the entry and the \emph{following} inter-column
637 % material. This means that in a tabular with the preamble
638 % "|l|l|l|l|" input such as "\multicolumn{2}{|c|}" in
639 % anything other than the first column is incorrect.
641 % In the standard array/tabular implementation this error is not so
642 % noticeable as that version contains negative spacing so that each
643 % "|" takes up no horizontal space. But since in this package the
644 % vertical lines take up their natural width one sees two lines if
651 % \changes{v2.2b}{1994/02/04}{Removed interactive prompt}
656 % \begin{thebibliography}{1}
657 % \bibitem{bk:GMS94} \textsc{M.~Goossens}, \textsc{F.~Mittelbach}
658 % and \textsc{A.~Samarin}.
659 % \newblock The \LaTeX{} Companion.
661 % Addison-Wesley, Reading, Massachusetts, 1994.
662 % \bibitem{bk:knuth} \textsc{D. E. Knuth}.
663 % \newblock The \TeX{}book (Computers \& Typesetting Volume A).
665 % Addison-Wesley, Reading, Massachusetts, 1986.
666 % \bibitem{bk:lamport} \textsc{L. Lamport}.
668 % \LaTeX\ --- A Document Preparation System.
670 % Addison-Wesley, Reading, Massachusetts, 1986.
671 % \end{thebibliography}
673 % } ^^A end of \StopEventually
678 % \section{The documentation driver file}
680 % The first bit of code contains the documentation driver file for
681 % \TeX{}, i.e., the file that will produce the documentation you are
682 % currently reading. It will be extracted from this file by the
683 % \texttt{docstrip} program.
686 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
687 \documentclass{ltxdoc}
689 \AtBeginDocument{\DeleteShortVerb{\|}} % undo the default is not used
693 % Allow large table at bottom
694 \renewcommand{\bottomfraction}{0.7}
697 %\DisableCrossrefs % Say \DisableCrossrefs if index is ready
699 \RecordChanges % Gather update information
701 \CodelineIndex % Index code by line number
703 %\OnlyDescription % comment out for implementation details
704 %\OldMakeindex % use if your MakeIndex is pre-v2.9
712 % \section{The construction of the preamble}
714 % \DeleteShortVerb{\"}
717 % It is obvious that those environments will consist mainly of an
718 % =\halign=, because \TeX\ typesets tables using this primitive.
719 % That is why we will now take a look at the algorithm which determines
720 % a preamble for a =\halign= starting with a given user preamble
721 % using the options mentioned above.
724 % The current version is defined at the top of the file looking
725 % something like this
728 %\NeedsTeXFormat{LaTeX2e}[1994/05/13]
729 %\ProvidesPackage{array}[\filedate\space version\fileversion]
732 % The most interesting macros of this implementation are without doubt
733 % those which are responsible for the construction of the preamble for
734 % the =\halign=. The underlying algorithm was developed by
735 % \textsc{Lamport} (resp.\ \textsc{Knuth}, see texhax V87\#??), and it
736 % has been extended and improved.
738 % The user preamble will be read \textsf{token} by \textsf{token}. A
739 % \textsf{token} is a single character like \texttt{c} or a block
740 % enclosed in ={...}=. For example the preamble of
741 % =\begin{tabular}=\linebreak[0]={lc||c@{\hspace{1cm}}}= consists of
742 % the \textsf{token} \texttt{l}, \texttt{c}, \texttt{|}, \texttt{|},
743 % \texttt{@} and =\hspace{1cm}=.
745 % The currently used \textsf{token} and the one, used before, are needed
746 % to decide on how the construction of the preamble has to be
748 % In the example mentioned above the \texttt{l} causes the preamble
749 % to begin with =\hskip\tabcolsep=. Furthermore
750 % =# \hfil= would be appended to define a flush left column.
751 % The next \textsf{token} is a \texttt{c}. Because it was preceded by an
752 % \texttt{l} it generates a new column. This is done with
753 % =\hskip \tabcolsep & \hskip \tabcolsep=. The column which is to
754 % be centered will be appended with =\hfil # \hfil=.
755 % The \textsf{token} \texttt{|} would then add a space of
756 % =\hskip \tabcolsep=
757 % and a vertical line because the last
758 % \textsf{tokens} was a \texttt{c}.
759 % The following \textsf{token} \texttt{|} would only add a space
760 % =\hskip \doublerulesep= because it was preceded by the
761 % \textsf{token} \texttt{|}. We will not discuss our example further but
762 % rather take a look at the general case of constructing preambles.
764 % The example shows that the desired preamble for the
765 % =\halign= can be constructed as soon as the action of all
767 % of the preamble \textsf{tokens} are specified. There are 18 such
769 % so we have $19 \cdot 18 \string= 342$ combinations if we count the
771 % the preamble as a special \textsf{token}. Fortunately, there are many
772 % combinations which generate the same spaces, so we can define
773 % \textsf{token} classes. We will identify a
774 % \textsf{token} within a class with a number, so we can insert the
775 % formatting (for example of a column).
776 % Table~\ref{tab:Klassen} lists all \textsf{token} classes and
777 % their corresponding numbers.
780 % \begin{tabular}[t]{>{\ttfamily}ccc}
781 % \textsf{token} & =\@chclass= & =\@chnum= \\[2mm]
793 % \kern3mm \vrule \kern3mm%
794 % \begin{tabular}[t]{>{\ttfamily}ccc}
795 % \textsf{token} & =\@chclass= & =\@chnum= \\[2mm]
807 % \caption{Classes of preamble \textsf{tokens}}
808 % \label{tab:Klassen}
812 % \begin{macro}{\@chclass}
813 % \begin{macro}{\@chnum}
814 % \begin{macro}{\@lastchclass}
815 % The class and the number of the current \textsf{token} are saved in
817 % \textsf{count} registers =\@chclass=
818 % and =\@chnum=, while the class of the previous
819 % \textsf{token} is stored in the
820 % \textsf{count} register =\@lastchclass=.
821 % All of the mentioned registers are already allocated in
822 % \texttt{latex.tex},
823 % which is the reason why the following three lines of code are
825 % Later throughout the text I will not mention it again explicitly
826 % whenever I use a =%= sign. These parts are already defined in
827 % \texttt{latex.tex}.
829 % \newcount \@chclass
831 % \newcount \@lastchclass
839 % \begin{macro}{\@addtopreamble}
840 % We will save the already constructed preamble for
842 % in the global macro =\@preamble=. This will then be
844 % the command =\@addtopreamble=.
846 \def\@addtopreamble#1{\xdef\@preamble{\@preamble #1}}
854 % \subsection{The character class of a \textsf{token}}
856 % \begin{macro}{\@testpach}
857 % \changes{v2.0a}{1989/05/12}{p option renamed to m (middle).}
858 % \changes{v2.0a}{1989/05/12}{t option renamed to p to be compatible to
860 % With the help of =\@lastchclass= we can now define a macro
861 % which determines the class and the number of a given preamble
863 % and assigns them to the registers
864 % =\@chclass= and =\@chnum=.
865 % \changes{v2.0f}{1992/02/29}{Argument removed since implicitly known}
867 \def\@testpach{\@chclass
869 % First we deal with the cases in which the \textsf{token}
870 % (=#1=) is the argument of \texttt{!}, \texttt{@}, \texttt{<} or
871 % \texttt{>}. We can see this from the value of =\@lastchclass=:
873 \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
874 \ifnum \@lastchclass=7 5 \else
875 \ifnum \@lastchclass=8 \tw@ \else
876 \ifnum \@lastchclass=9 \thr@@
878 % Otherwise we will assume that the \textsf{token} belongs to the
880 % and assign the corresponding number to =\@chnum= if our
881 % assumption is correct.
885 % If the last \textsf{token} was a \texttt{p}, \texttt{m} or a
886 % \texttt{b}, =\@chnum= already has the right value. This is the
887 % reason for the somewhat curious choice of the \textsf{token}
888 % numbers in class $10$.
890 \ifnum \@lastchclass = 10 \else
892 % Otherwise we will check if =\@nextchar= is either a \texttt{c},
893 % \texttt{l} or an \texttt{r}. Some applications change the
894 % catcodes of certain characters like ``\texttt{@}'' in
895 % \texttt{amstex.sty}. As a result the tests below would fail since
896 % they assume non-active character tokens. Therefore we evaluate
897 % =\@nextchar= once thereby turning the first token of its
898 % replacement text into a char. At this point here this should have
899 % been the only char present in =\@nextchar= which put into via a
901 % \changes{v2.0f}{1992/02/29}{Ensure to test a char which is not active}
903 \edef\@nextchar{\expandafter\string\@nextchar}%
905 \if \@nextchar c\z@ \else
906 \if \@nextchar l\@ne \else
907 \if \@nextchar r\tw@ \else
909 % If it is a different \textsf{token}, we know that the class was
910 % not $0$. We assign the value $0$ to =\@chnum= because this value
911 % is needed for the \texttt{|}--\textsf{token}. Now we must check
912 % the remaining classes. Note that the value of =\@chnum= is
913 % insignificant here for most classes.
916 \if\@nextchar |\@ne \else
917 \if \@nextchar !6 \else
918 \if \@nextchar @7 \else
919 \if \@nextchar <8 \else
920 \if \@nextchar >9 \else
922 % The remaining permitted \textsf{tokens} are \texttt{p},
923 % \texttt{m} and \texttt{b} (class $10$).
927 \if \@nextchar m\thr@@\else
928 \if \@nextchar p4 \else
929 \if \@nextchar b5 \else
931 % Now the only remaining possibility is a forbidden \textsf{token},
932 % so we choose class $0$ and number $0$ and give an error message.
933 % Then we finish the macro by closing all =\if='s.
935 \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
936 \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}
944 % \subsection{Multiple columns ($*$--form)}
946 % \begin{macro}{\@xexpast}
947 % \begin{macro}{\the@toks}
948 % \begin{macro}{\the@toksz}
949 % \label{@xexpast} Now we discuss the macro that deletes all forms
950 % of type =*{=\textit{N\/}=}{=\textit{String\/}=}= from a user
951 % preamble and replaces them with \textit{N} copies of
952 % \textit{String}. Nested $*$--expressions are dealt with
953 % correctly, that means $*$--expressions are not substituted if
954 % they are in explicit braces, as in =@{*}=.
956 % This macro is called via
957 % =\@xexpast=\meta{preamble}=*0x\@@=.
958 % The $*$--expression =*0x= is being used to terminate the
960 % as we shall see later, and =\@@= serves as an argument
961 % delimiter. =\@xexpast= has four arguments. The first
962 % one is the part of the
963 % user preamble before the first $*$--expression while the second
964 % and third ones are the arguments of the first $*$--expression
965 % (that is \textit{N} and \textit{String} in the notation mentioned
967 % The fourth argument is the rest of the preamble.
969 \def\@xexpast#1*#2#3#4\@@{%
971 % The number of copies of \textit{String} (=#2=) that are to be
972 % produced will be saved in a \textsf{count} register.
976 % We save the part of the preamble which does not
977 % contain a $*$--form (=#1=)
978 % in a \PlainTeX\ \textsf{token} register.
979 % We also save \textit{String} (=#3=) using a \LaTeX\
980 % \textsf{token} register.
982 \toks@={#1}\@temptokena={#3}%
984 % Now we have to use a little trick to produce \textit{N} copies of
986 % We could try =\def\@tempa{#1}= and then
987 % \textit{N} times =\edef\@tempa{\@tempa#3}=. This would have the
988 % undesired effect that all macros within =#1= and =#3=
989 % would be expanded, although, for example, constructions like
990 % =@{..}= are not supposed to be changed.
991 % That is why we =\let= two control sequences to
992 % be equivalent to =\relax=.
994 \let\the@toksz\relax \let\the@toks\relax
996 % Then we ensure that =\@tempa= contains
997 % ={\the@toksz\the@toks...\the@toks}= (the macro
998 % =\the@toks= exactly \textit{N\/} times) as substitution text.
1000 \def\@tempa{\the@toksz}%
1001 \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do
1002 {\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}%
1004 % If \textit{N\/} was greater than zero we prepare for another call
1005 % of =\@xexpast=. Otherwise we assume we have reached the end of
1006 % the user preamble, because we had appended =*0x\@@= when we first
1007 % called =\@xexpast=. In other words: if the user inserts
1008 % =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it.
1010 \let \@tempb \@xexpast \else
1011 \let \@tempb \@xexnoop \fi
1013 % Now we will make sure that the part of the user preamble, which
1014 % was already dealt with, will be saved again in =\@tempa=.
1016 \def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}%
1017 \edef\@tempa{\@tempa}%
1019 % We have now evaluated the first $*$--expression, and the user
1020 % preamble up to this point
1021 % is saved in =\@tempa=. We will put the contents of
1022 % =\@tempa= and the rest of the user preamble together and work
1023 % on the result with =\@tempb=. This macro either corresponds
1024 % to =\@xexpast=, so that the next
1025 % $*$--expression is handled, or to the macro =\@xexnoop=,
1026 % which only ends the recursion by deleting its argument.
1028 \expandafter \@tempb \@tempa #4\@@}
1034 % \begin{macro}{\@xexnoop}
1035 % So the first big problem is solved. Now it is easy to
1036 % specify =\@xexnoop=.
1037 % Its argument is delimited by =\@@= and it simply expands to
1040 % \def\@xexnoop#1\@@{}
1047 % \section{The insertion of declarations
1048 % (\texttt{>}, \texttt{<}, \texttt{!}, \texttt{@})}
1051 % The preamble will be enlarged with the help of =\xdef=, but the
1052 % arguments of \texttt{>}, \texttt{<},~\texttt{!}\ and \texttt{@} are
1053 % not supposed to be expanded during the construction (we want an
1054 % implementation that doesn't need a =\protect=). So we have to find a
1055 % way to inhibit the expansion of those arguments.
1057 % We will solve this problem with \textsf{token} registers. We need
1058 % one register for every \texttt{!}\ and \texttt{@}, while we need two
1059 % for every \texttt{c}, \texttt{l}, \texttt{r}, \texttt{m}, \texttt{p}
1060 % or \texttt{b}. This limits the number of columns of a table because
1061 % there are only 256 \textsf{token} registers. But then, who needs
1062 % tables with more than 100 columns?
1064 % One could also find a solution which only needs two or three
1065 % \textsf{token} registers by proceeding similarly as in the macro
1066 % =\@xexpast= (see page \pageref{@xexpast}). The advantage of our
1067 % approach is the fact that we avoid some of the problems that arise
1068 % with the other method\footnote{Maybe there are also historical
1071 % So how do we proceed? Let us assume that we had =!{foo}= in the
1072 % user preamble and say we saved \texttt{foo} in
1073 % \textsf{token} register $5$. Then we call
1074 % =\@addtopreamble{\the@toks5}= where
1075 % =\the@toks= is defined in a way that it does not expand
1076 % (for example it could be equivalent to =\relax=). Every
1078 % of =\@addtopreamble= leaves =\the@toks5= unchanged in
1079 % =\@preamble=. If the construction of the preamble is completed
1080 % we change the definition of =\the@toks= to
1081 % =\the\toks= and expand =\@preamble= for the last time.
1082 % During this process all parts of the form
1083 % =\the@toks=\meta{Number}
1084 % will be substituted by the contents of the respective \textsf{token}
1087 % As we can see from this informal discussion the construction of the
1088 % preamble has to take place within a group, so that the
1089 % \textsf{token} registers we use will be freed later on. For that
1090 % reason we keep all assignments to =\@preamble= global; therefore the
1091 % replacement text of this macro will remain the same after we leave
1094 % \begin{macro}{\count@}
1095 % We further need a \textsf{count} register to remember which
1096 % \textsf{token} register is to be used next. This will be
1097 % initialized with $-1$ if we want to begin with the \textsf{token}
1098 % register $0$. We use the \PlainTeX\ scratch register =\count@=
1099 % because everything takes place locally. All we have to do is
1100 % insert =\the@toks= =\the= =\count@= into the preamble.
1101 % =\the@toks= will remain unchanged and =\the\count@= expands into
1105 % \begin{macro}{\prepnext@tok}
1106 % The macro =\prepnext@tok= is in charge of preparing the next
1107 % \textsf{token} register. For that purpose we increase
1110 \def\prepnext@tok{\advance \count@ \@ne
1112 % Then we locally delete any contents the
1113 % \textsf{token} register might have.
1119 % \begin{macro}{\save@decl}
1120 % During the construction of the preamble the current
1121 % \textsf{token} is always saved in the macro =\@nextchar= (see the
1122 % definition of =\@mkpream= on page \pageref{@mkpream}). The macro
1123 % =\save@decl= saves it into the next free \textsf{token} register,
1124 % i.e.\ in =\toks\count@=.
1125 % \changes{v2.0c}{1990/08/14}{\cs{relax} removed and added elsewhere.}
1127 \def\save@decl{\toks\count@ \expandafter{\@nextchar}}
1129 % The reason for the use of =\relax= is the following
1130 % hypothetical situation in the preamble:
1131 % \quad =..\the\toks1\the\toks2..= \quad \TeX\ expands
1132 % =\the\toks2= first in order to find out if the digit =1=
1133 % is followed by other digits. E.g.\ a =5= saved in the
1134 % \textsf{token} register $2$ would lead \TeX\ to insert the contents
1135 % of \textsf{token} register $15$ instead of $1$ later on.
1137 % The example above referred to an older version of =\save@decl= which
1138 % inserted a =\relex= inside the token register. This is now moved to
1139 % the places where the actual token registers are inserted (look for
1140 % =\the@toks=) because the old version would still make =@=
1141 % expressions to moving arguments since after expanding the second
1142 % register while looking for the end of the number the contents of the
1143 % token register is added so that later on the whole register will be
1144 % expanded. This serious bug was found after nearly two years
1145 % international use of this package by Johannes Braams.
1150 % How does the situation look like, if we want to add another column
1151 % to the preamble, i.e.\ if we have found a \texttt{c}, \texttt{l},
1152 % \texttt{r}, \texttt{p}, \texttt{m} or \texttt{b} in the user
1153 % preamble? In this case we have the problem of the \textsf{token}
1154 % register from =>{..}= and =<{..}= having to be inserted at this
1155 % moment because formatting instructions like =\hfil= have to be set
1156 % around them. On the other hand it is not known yet, if any =<{..}=
1157 % instruction will appear in the user preamble at all.
1159 % We solve this problem by adding two \textsf{token} registers at a
1160 % time. This explains, why we have freed the \textsf{token} registers
1161 % in =\prepnext@tok=.
1163 % \begin{macro}{\insert@column}
1164 % \begin{macro}{\@sharp}
1165 % We now define the macro =\insert@column= which will do
1168 \def\insert@column{%
1170 % Here, we assume that the \textsf{count} register
1171 % =\@tempcnta= has saved the value $=\count@= - 1$.
1173 \the@toks \the \@tempcnta
1175 % Next follows the =#= sign which specifies the place
1176 % where the text of the column shall be inserted. To avoid
1177 % errors during the expansions in
1178 % =\@addtopreamble= we hide this sign in the command
1179 % =\@sharp= which is temporarily occupied with
1180 % =\relax= during the build-up of the preamble.
1181 % To remove unwanted spaces before and after the column text, we set
1182 % an =\ignorespaces= in front and a =\unskip= afterwards.
1183 % \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel}
1184 % \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of
1187 \ignorespaces \@sharp \unskip
1189 % Then the second \textsf{token} register follows whose number should
1190 % be saved in =\count@=.
1191 % We make sure that there will be no further expansion after reading
1192 % the number, by finishing with =\relax=. The case above is not
1193 % critical since it is ended by =\ignorespaces=.
1194 % \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
1195 % \cs{the}\cs{toks0}\cs{the}\cs{toks1}.}
1197 \the@toks \the \count@ \relax}
1205 % \subsection{The separation of columns}
1207 % \begin{macro}{\@addamp}
1208 % In the preamble a =&= has to be inserted between any two columns;
1209 % before the first column there should not be a =&=. As the user
1210 % preamble may start with a \texttt{|} we have to remember somehow
1211 % if we have already inserted a =#= (i.e.\ a column). This is done
1212 % with the boolean variable =\if@firstamp= that we test in
1213 % =\@addamp=, the macro that inserts the =&=.
1215 % \newif \@iffirstamp
1216 % \def\@addamp{\if@firstamp \@firstampfalse
1217 % \else \@addtopreamble &\fi}
1221 % \begin{macro}{\@acol}
1222 % \begin{macro}{\@acolampacol}
1223 % \begin{macro}{\col@sep}
1224 % We will now define some abbreviations for the extensions,
1225 % appearing most often in the preamble build-up.
1226 % Here =\col@sep= is a \textsf{dimen} register which is set
1227 % equivalent to =\arraycolsep= in an \textsf{array}--environment,
1228 % otherwise it is set equivalent to =\tabcolsep=.
1231 \def\@acol{\@addtopreamble{\hskip\col@sep}}
1232 % \def\@acolampacol{\@acol\@addamp\@acol}
1239 % \subsection{The macro \texttt{\textbackslash @mkpream}}
1241 % \begin{macro}{\@mkpream}
1242 % \begin{macro}{\the@toks}
1244 % Now we can define the macro which builds up the preamble for the
1246 % First we initialize =\@preamble=, =\@lastchclass=
1247 % and the boolean variable =\if@firstamp=.
1249 \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
1251 % During the build-up of the preamble we cannot directly use the
1252 % =#= sign; this would lead to an error message in the next
1253 % =\@addtopreamble= call.
1254 % Instead, we use the command =\@sharp= at places where later
1256 % This command is at first given the meaning =\relax=;
1257 % therefore it will not be expanded when the preamble
1259 % In the macro =\@array=, shortly before the =\halign=
1260 % is carried out, =\@sharp= is given its final meaning.
1263 % we deal with the commands =\@startpbox= and
1264 % =\@endpbox=, although the reason is different here: these
1265 % macros expand in many \textsf{tokens} which would delay the
1266 % build-up of the preamble.
1268 \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
1270 % Now we remove possible $*$-forms in the user preamble with the
1271 % command =\@xexpast=. As we already know, this command saves
1272 % its result in the macro =\@tempa=.
1276 % Afterwards we initialize all registers and macros, that we need
1277 % for the build-up of the preamble.
1278 % Since we want to start with the \textsf{token} register $0$,
1279 % =\count@= has to contain the value $-1$.
1284 % Then we call up =\prepnext@tok= in order to prepare the
1285 % \textsf{token} register $0$ for use.
1289 % To evaluate the user preamble (without stars) saved in
1290 % =\@tempa= we use the \LaTeX--macro =\@tfor=.
1291 % The strange appearing construction with =\expandafter= is
1292 % based on the fact that we have to put the replacement text of
1293 % =\@tempa= and not the macro =\@tempa= to this
1296 \expandafter \@tfor \expandafter \@nextchar
1297 \expandafter :\expandafter =\@tempa \do
1299 % The body of this loop (the group after the =\do=)
1300 % is executed for one \textsf{token} at a time, whereas
1301 % the current \textsf{token} is saved in =\@nextchar=.
1302 % At first we evaluate the current \textsf{token} with the already
1303 % defined macro =\@testpach=, i.e.\ we assign to
1304 % =\@chclass= the character class and to =\@chnum=
1305 % the character number of this \textsf{token}.
1306 % \changes{v2.0f}{1992/02/29}{\cs{@testpach} now without arg}
1310 % Then we branch out depending on the value of =\@chclass= into
1311 % different macros that extend the preamble respectively.
1313 \ifcase \@chclass \@classz \or \@classi \or \@classii
1314 \or \save@decl \or \or \@classv \or \@classvi
1315 \or \@classvii \or \@classviii \or \@classix
1318 % Two cases deserve our special attention: Since the current
1319 % \textsf{token} cannot have the character class $4$ (start) we
1320 % have skipped this possibility. If the character class is $3$,
1321 % only the content of =\@nextchar= has to be saved into the current
1322 % \textsf{token} register; therefore we call up =\save@decl=
1323 % directly and save a macro name. After the preamble has been
1324 % extended we assign the value of =\@chclass= to the counter
1325 % =\@lastchclass= to assure that this information will be available
1326 % during the next run of the loop.
1328 \@lastchclass\@chclass}%
1330 % After the loop has been finished space must still be added to
1331 % the created preamble, depending on the last \textsf{token}.
1332 % Depending on the value of =\@lastchclass= we perform
1333 % the necessary operations.
1335 \ifcase\@lastchclass
1337 % If the last class equals $0$ we add a
1338 % =\hskip \col@sep=.
1342 % If it equals $1$ we do not add any additional space so that the
1343 % horizontal lines do not exceed the vertical ones.
1347 % Class $2$ is treated like class $0$ because a =<{...}= can
1348 % only directly follow after class $0$.
1352 % Most of the other possibilities can only appear if the user
1353 % preamble was defective. Class $3$ is not allowed since after a
1354 % =>{..}= there must always follow a \texttt{c}, \texttt{l},
1355 % \texttt{r}, \texttt{p},\texttt{m} or \texttt{b}. We report an
1356 % error and ignore the declaration given by ={..}=.
1358 \@preamerr \thr@@ \or
1360 % If =\@lastchclass= is $4$ the user preamble has been empty.
1361 % To continue, we insert a =#= in the preamble.
1363 \@preamerr \tw@ \@addtopreamble\@sharp \or
1365 % Class $5$ is allowed again. In this case
1366 % (the user preamble ends with =@{..}=) we need not
1371 % Any other case means that the arguments to =@=, \texttt{!},
1372 % \texttt{<}, \texttt{>}, \texttt{p}, \texttt{m} or \texttt{b} have
1373 % been forgotten. So we report an error and ignore the last
1376 \else \@preamerr \@ne \fi
1378 % Now that the build-up of the preamble is almost finished we can
1379 % insert the \textsf{token} registers and therefore redefine
1380 % =\the@toks=. The actual insertion, though, is performed
1383 \def\the@toks{\the\toks}}
1390 % \section{The macros \texttt{\textbackslash @classz}
1391 % to \texttt{\textbackslash @classx}}
1393 % The preamble is extended by the macros =\@classz= to
1394 % =\@classx= which are called by =\@mkpream=
1395 % depending on =\@lastchclass=
1396 % (i.e. the character class of the last \textsf{token}).
1397 % \begin{macro}{\@classx}
1398 % First we define =\@classx= because of its important r\^ole.
1399 % When it is called we find that the current
1400 % \textsf{token} is \texttt{p}, \texttt{m} or \texttt{b}.
1401 % That means that a new column has to start.
1405 % Depending on the value of =\@lastchclass= different actions
1408 \ifcase \@lastchclass
1410 % If the last character class was $0$ we separate the columns by
1411 % =\hskip\col@sep= followed by =&= and another
1416 % If the last class was class $1$ --- that means that a vertical
1418 % drawn, --- before this line a =\hskip\col@sep= was inserted.
1419 % Therefore there has to be only a =&= followed by
1420 % =\hskip\col@sep=. But this =&= may be inserted only
1421 % if this is not the first column. This process is controlled
1422 % by =\if@firstamp= in the macro =\addamp=.
1426 % Class $2$ is treated like class $0$ because =<{...}= can only
1427 % follow after class $0$.
1431 % Class $3$ requires no actions because all things necessary have
1432 % been done by the preamble \textsf{token} \texttt{>}.
1436 % Class $4$ means that we are at the beginning of the preamble.
1437 % Therefore we start the preamble with =\hskip\col@sep= and
1438 % then call =\@firstampfalse=. This makes sure that a later
1439 % =\@addamp= inserts the character
1440 % =&= into the preamble.
1442 \@acol \@firstampfalse \or
1444 % For class $5$ \textsf{tokens} only the character =&= is inserted
1445 % as a column separator. Therefore we call =\@addamp=.
1449 % Other cases are impossible. For an example
1450 % $=\@lastchclass= \string= 6$---as it might appear in a
1451 % preamble of the form =...!p...=---\texttt{p} would have
1452 % been taken as an argument of \texttt{!}\ by =\@testpach=.
1459 % \begin{macro}{\@classz}
1460 % If the character class of the last \textsf{token} is $0$ we have
1461 % \texttt{c}, \texttt{l}, \texttt{r} or an argument of \texttt{m},
1462 % \texttt{b} or\ \texttt{p}. In the first three cases the preamble
1463 % must be extended the same way as if we had class $10$. The
1464 % remaining two cases do not require any action because the space
1465 % needed was generated by the last \textsf{token} (i.e.\
1466 % \texttt{m}, \texttt{b} or \texttt{p}). Since =\@lastchclass= has
1467 % the value $10$ at this point nothing happens when =\@classx= is
1468 % called. So the macro =\@chlassz= may start like this:
1470 \def\@classz{\@classx
1472 % According to the definition of =\insert@column= we must store
1473 % the number of the \textsf{token} register in which a preceding
1474 % =>{..}= might have stored its argument into
1479 % To have $=\count@= \string= =\@tmpcnta= + 1$ we prepare
1480 % the next \textsf{token} register.
1484 % Now the preamble must be extended with the column whose format
1485 % can be determined by =\@chnum=.
1487 \@addtopreamble{\ifcase \@chnum
1489 % If =\@chnum= has the value $0$ a centered column has to be
1491 % So we begin with stretchable space.
1495 % The command =\d@llarbegin= follows expanding into =\begingroup=
1496 % (in the \textsf{tabular}--environment) or into =$=. Doing this
1497 % (provided an appropriate setting of =\d@llarbegin=) we achieve
1498 % that the contents of the columns of an \textsf{array}--environment
1499 % are set in math mode while those of a \textsf{tabular}--environment
1500 % are set in LR mode.
1504 % Now we insert the contents of the two \textsf{token} registers
1506 % for the column entry (i.e.\ =#= or
1507 % more precise =\@sharp=) using =\insert@column=.
1511 % We end this case with =\d@llarend= and =\hfil= where =\d@llarend=
1512 % again is either =$= or =\endgroup=.
1514 \d@llarend \hfil \or
1516 % The templates for \texttt{l} and \texttt{r} (i.e.\ =\@chnum= $1$
1517 % or $2$) are generated the same way. Since one =\hfil= is
1518 % missing the text is moved to the relevant side.
1519 % The =\kern\z@= is needed in case of an empty column
1521 % the =\unskip= in =\insert@column= removes the
1522 % =\hfil=. Changed to =\hskip1sp= so that it interacts better with
1524 % \changes{v2.3f}{1996/04/22}
1525 % {(DPC) Extra \cs{kern} keeps tabcolsep in empty l columns
1527 % \changes{v2.3i}{1996/06/14}
1528 % {Change both \cs{kern}\cs{z@} to \cs{hskip}1sp for latex/2160}
1530 \hskip1sp\d@llarbegin \insert@column \d@llarend \hfil \or
1531 \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend \or
1533 % The templates for \texttt{p}, \texttt{m} and \texttt{b} mainly
1534 % consist of a \textsf{box}. In case of \texttt{m} it is generated
1535 % by =\vcenter=. This command is allowed only in math
1536 % mode. Therefore we start with a~=$=.
1540 % The part of the templates which is the same in all three cases
1541 % (\texttt{p}, \texttt{m} and \texttt{b})
1542 % is built by the macros =\@startpbox= and
1543 % =\@endpbox=. =\@startpbox= has an argument:
1544 % the width of the column which is stored in the current
1545 % \textsf{token} (i.e.\ =\@nextchar=).
1546 % Between these two macros we find the well known
1549 \@startpbox{\@nextchar}\insert@column \@endpbox $\or
1551 % The templates for \texttt{p} and \texttt{b} are generated in the
1552 % same way though we do not need the =$= characters because we use
1553 % =\vtop= or =\vbox=.
1555 \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
1556 \vbox \@startpbox{\@nextchar}\insert@column \@endpbox
1558 % Other values for =\@chnum= are impossible. Therefore we
1559 % end the arguments to =\@addtopreamble= and =\ifcase=.
1560 % Before we come to the end of =\@classz= we have to
1561 % prepare the next \textsf{token} register.
1568 % \begin{macro}{\@classix}
1569 % In case of class $9$ (\texttt{>}--\textsf{token}) we first check
1570 % if the character class of the last
1571 % \textsf{token} was $3$. In this case we have a
1572 % user preamble of the form =..>{...}>{...}..= which
1573 % is not allowed. We only give an error message and continue.
1574 % So the declarations defined by the first =>{...}=
1577 \def\@classix{\ifnum \@lastchclass = \thr@@
1578 \@preamerr \thr@@ \fi
1580 % Furthermore, we call up =\@class10= because afterwards always a
1581 % new column is started by \texttt{c}, \texttt{l}, \texttt{r},
1582 % \texttt{p}, \texttt{m} or \texttt{b}.
1590 % \begin{macro}{\@classviii}
1591 % If the current \textsf{token} is a \texttt{<} the last character
1592 % class must be $0$. In this case it is not necessary to extend the
1593 % preamble. Otherwise we output an error message, set =\@chclass=
1594 % to $6$ and call =\@classvi=. By doing this we achieve that
1595 % \texttt{<} is treated like \texttt{!}.
1597 \def\@classviii{\ifnum \@lastchclass >\z@
1598 \@preamerr 4\@chclass 6 \@classvi \fi}
1602 % \begin{macro}{\@arrayrule}
1603 % There is only one incompatibility with the original definition:
1604 % the definition of =\@arrayrule=. In the original a line without
1605 % width\footnote{So the space between \texttt{cc} and \texttt{c|c}
1606 % is equal.} is created by multiple insertions of
1607 % =\hskip .5\arrayrulewidth=.
1608 % We only insert a vertical line into the
1609 % preamble. This is done to prevent problems with \TeX's main
1610 % memory when generating tables with many vertical lines in them
1611 % (especially in the case of \textsf{floats}).
1613 \def\@arrayrule{\@addtopreamble \vline}
1617 % \begin{macro}{\@classvii}
1618 % As a consequence it follows that in case of class $7$
1619 % (=@= \textsf{token}) the preamble need not to be extended.
1620 % In the original definition $=\@lastchclass= \string= 1$
1621 % is treated by inserting =\hskip .5\arrayrulewidth=.
1622 % We only check if the last \textsf{token} was of class $3$ which is
1625 \def\@classvii{\ifnum \@lastchclass = \thr@@
1627 % If this is true we output an error message and
1628 % ignore the declarations stored
1629 % by the last =>{...}=, because these are overwritten
1630 % by the argument of \texttt{@}.
1632 \@preamerr \thr@@ \fi}
1637 % \begin{macro}{\@classvi}
1638 % If the current \textsf{token} is a regular \texttt{!}\ and the
1639 % last class was $0$ or $2$ we extend the preamble with
1640 % =\hskip\col@sep=. If the last \textsf{token} was of class $1$
1641 % (for instance \texttt{|}) we extend with =\hskip \doublerulesep=
1642 % because the construction =!{...}= has to be treated like
1645 \def\@classvi{\ifcase \@lastchclass
1647 \@addtopreamble{\hskip \doublerulesep}\or
1650 % Now =\@preamerr...= should follow because a
1651 % user preamble of the form =..>{..}!.= is not allowed.
1652 % To save memory we call =\@classvii= instead which also
1653 % does what we want.
1657 % If =\@lastchclass= is $4$ or $5$ nothing has to be done.
1658 % Class $6$ to $10$ are not possible.
1659 % So we finish the macro.
1665 % \begin{macro}{\@classii}
1666 % \begin{macro}{\@classiii}
1667 % In the case of character classes $2$ and $3$ (i.e.\ the argument
1668 % of \texttt{<} or \texttt{>}) we only have to store the current
1669 % \textsf{token} (=\@nextchar=) into the corresponding
1670 % \textsf{token} register since the preparation and
1671 % insertion of these registers
1672 % are done by the macro =\@classz=.
1673 % This is equivalent to calling =\save@decl= in the case of
1674 % class $3$. To save command identifiers we do this call up
1675 % in the macro =\@mkpream=.
1677 % Class $2$ exhibits a more complicated situation: the
1678 % \textsf{token} registers have already been inserted by
1679 % =\@classz=. So the value of =\count@= is too high
1680 % by one. Therefore we decrease =\count@= by $1$.
1682 \def\@classii{\advance \count@ \m@ne
1684 % Next we store the current \textsf{token} into the correct
1685 % \textsf{token} register by calling =\save@decl= and then
1686 % increase the value of =\count@= again. At this point we
1687 % can save memory once more (at the cost of time) if we use the
1688 % macro =\prepnext@tok=.
1690 \save@decl\prepnext@tok}
1696 % \begin{macro}{\@classv}
1697 % If the current \textsf{token} is of class $5$ then it is an
1698 % argument of a \texttt{@} \textsf{token}. It must be stored into a
1699 % \textsf{token} register.
1701 \def\@classv{\save@decl
1703 % We extend the preamble with a command which inserts this
1704 % \textsf{token} register into the preamble when its construction
1705 % is finished. The user expects that this argument is worked out in
1706 % math mode if it was used in an
1707 % \textsf{array}--environment. Therefore we surround it with
1709 % \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
1710 % `the`toks0`the`toks1.}
1712 \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
1714 % Finally we must prepare the next \textsf{token} register.
1720 % \begin{macro}{\@classi}
1721 % In the case of class $0$ we were able to generate the necessary
1722 % space between columns by using the macro =\@classx=.
1723 % Analogously the macro =\@classvi= can be used for class $1$.
1725 \def\@classi{\@classvi
1727 % Depending on =\@chnum= a vertical line
1729 \ifcase \@chnum \@arrayrule \or
1731 % or (in case of =!{...}=) the current \textsf{token} --- stored
1732 % in =\@nextchar= --- has to be inserted into the preamble.
1733 % This corresponds to calling =\@classv=.
1741 % \begin{macro}{\@startpbox}
1742 % In =\@classz= the macro =\@startpbox= is used.
1743 % The width of the \textsf{parbox} is passed as an argument.
1744 % =\vcenter=, =\vtop= or =\vbox= are already in the
1745 % preamble. So we start with the braces for the wanted box.
1747 \def\@startpbox#1{\bgroup
1749 % The argument is the width of the box. This information has to be
1750 % assigned to =\hsize=.
1751 % Then we assign default values to several parameters used in a
1753 % \changes{v2.3k}{1998/05/12}{Use \cs{setlength} to set \cs{hsize},
1754 % so that the calc package can be applied here (pr/2793)}
1756 \setlength\hsize{#1}\@arrayparboxrestore
1758 % Our main problem is to obtain the same distance between succeeding
1759 % lines of the \textsf{parbox}.
1760 % We have to remember that the distance between two \textsf{parboxes}
1761 % should be defined by =\@arstrut=. That means that it can be
1762 % greater than the distance in a \textsf{parbox}.
1763 % Therefore it is not enough to set a =\@arstrut= at the
1764 % beginning and at the end of the \textsf{parbox}. This would
1765 % dimension the distance
1766 % between first and second line and the distance between the two
1767 % last lines of the \textsf{parbox} wrongly.
1768 % To prevent this we set an invisible rule of height
1770 % at the beginning of the \textsf{parbox}. This has no effect on the
1771 % depth of the first line. At the end of the \textsf{parbox} we set
1772 % analogously another invisible rule which only affects the depth
1773 % of the last line. It is necessary to wait inserting this strut
1774 % until the paragraph actually starts to allow for things like
1775 % =\parindent= changes via =>{...}=.
1776 % \changes{v2.1c}{1992/12/14}{Use `everypar to insert strut}
1779 \vrule \@height \ht\@arstrutbox \@width \z@
1785 % \begin{macro}{\@endpbox}
1786 % If there are any declarations defined by =>{...}=
1788 % they now follow in the macro =\@classz= --- the contents
1789 % of the column in between.
1790 % So the macro =\@endpbox= must insert the \textsf{specialstrut}
1791 % mentioned earlier and then close the group opened by
1793 % \changes{v2.2d}{1994/05/16}{Use \LaTeXe \cs{@finalstrut}}
1794 % \changes{v2.3g}{1996/05/07}{Add \cs{hfil} for tools/2120}
1796 \def\@endpbox{\@finalstrut\@arstrutbox \egroup\hfil}
1801 % \section{Building and calling \texttt{\textbackslash halign}}
1803 % \begin{macro}{\@array}
1804 % After we have discussed the macros needed for the evaluation
1805 % of the user preamble we can define the macro =\@array=
1806 % which uses these macros to create a =\halign=.
1807 % It has two arguments. The first one is a position argument
1808 % which can be \texttt{t}, \texttt{b} or \texttt{c}; the
1809 % second one describes the wanted preamble,
1810 % e.g.\ it has the form =|c|c|c|=.
1814 % First we define a \textsf{strut} whose size basically corresponds
1815 % to a normal \textsf{strut} multiplied by the factor
1817 % This \textsf{strut} is then inserted into every row and enforces
1818 % a minimal distance between two rows.
1819 % Nevertheless, when using horizontal lines, large letters
1820 % (like accented capital letters) still collide with such lines.
1821 % Therefore at first we add to the height of a normal \textsf{strut}
1822 % the value of the parameter =\extrarowheight=.
1824 \@tempdima \ht \strutbox
1825 \advance \@tempdima by\extrarowheight
1826 \setbox \@arstrutbox \hbox{\vrule
1827 \@height \arraystretch \@tempdima
1828 \@depth \arraystretch \dp \strutbox
1831 % Then we open a group, in which the user preamble is evaluated by
1832 % the macro =\@mkpream=. As we know this must happen locally.
1833 % This macro creates a preamble for a =\halign= and saves
1834 % its result globally in the control sequence =\@preamble=.
1839 % We again redefine =\@preamble= so that a call up of =\@preamble=
1840 % now starts the =\halign=. Thus also the arguments of \texttt{>},
1841 % \texttt{<}, \texttt{@} and \texttt{!}, saved in the
1842 % \textsf{token} registers are inserted into the preamble. The
1843 % =\tabskip= at the beginning and end of the preamble is set to
1844 % \textsf{0pt} (in the beginning by the use of =\ialign=). Also the
1845 % command =\@arstrut= is build in, which inserts the
1846 % =\@arstrutbox=, defined above. Of course, the opening brace after
1847 % =\ialign= has to be implicit as it will be closed in =\endarray=
1849 % \changes{v2.3m}{1998/12/31}{Added \cs{noexpand} in front of \cs{ialign}
1850 % to guard against interesting :-) changes to \cs{halign} done to support
1851 % text glyphs in math}
1853 % The =\noexpand= in front of =\ialign= does no harm in standard \LaTeX{}
1854 % and was added since some experimental support for using text glyphs in math
1855 % redefines =\halign= with the result that is becomes expandable with
1856 % disastrous results in cases like this.
1857 % In the kernel definition for this macro the problem does
1858 % not surface because there =\protect= is set (which is not necessary in this
1859 % implementation as there is no arbitrary user input that can get expanded) and
1860 % the experimental code made the redefinition robust. Whether this is the right
1861 % approach is open to question; consider the =\noexpand= a courtesy to allow an
1862 % unsupported redefinition of a \TeX{} primitive for the moment (as people rely
1863 % on that experimental code).
1865 \xdef\@preamble{\noexpand \ialign \@halignto
1866 \bgroup \@arstrut \@preamble
1869 % What we have not explained yet is the macro =\@halignto=
1870 % that was just used. Depending on its replacement text the
1871 % =\halign= becomes a =\halign= \texttt{to} \meta{dimen}.
1872 % Now we close the group again. Thus
1873 % =\@startpbox= and =\@endpbox= as well as all
1874 % \textsf{token} registers get their former meaning back.
1878 % To support the \texttt{delarray.sty} package we include a hook
1879 % into this part of the code which is a no-op in the main package.
1880 % \changes{v2.1a}{1992/07/03}{Hook for delarray added}
1884 % Now we decide depending on the position argument in which
1885 % \textsf{box} the =\halign= is to be put. (=\vcenter= may be used
1886 % because we are in math mode.)
1887 % \changes{v2.1a}{1992/07/03}{Wrong spec is now equiv to [t]}
1889 \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
1891 % Now another implicit opening brace appears; then definitions
1892 % which shall stay local follow. While constructing the
1893 % =\@preamble= in =\@mkpream= the =#= sign must be
1894 % hidden in the macro =\@sharp= which is =\let= to
1895 % =\relax= at that moment (see definition of =\@mkpream=
1896 % on page~\pageref{@mkpream}).
1897 % All these now get their actual meaning.
1900 \let \@sharp ##\let \protect \relax
1902 % With the above defined \textsf{struts} we fix down the distance
1903 % between rows by setting =\lineskip= and =\baselineskip=
1904 % to \textsf{0pt}. Since there have to be set =$='s
1905 % around every column in the \textsf{array}--environment
1906 % the parameter =\mathsurround= should
1907 % also be set to \textsf{0pt}. This prevents additional space between
1909 % \PlainTeX--macro =\m@th= does this.
1915 % Beside, we have to assign a special meaning (which we still have
1916 % to specify) to the line separator =\\=. We also have to
1917 % redefine the command =\par= in such a way that empty lines in
1918 % =\halign= cannot do any damage. We succeed in doing so
1919 % by choosing something that will disappear when expanding.
1920 % After that we only have to call up =\@preamble= to
1921 % start the wanted =\halign=.
1922 % \changes{1994/12/08}{v2.3b}{add \cs{tabularnewline}}
1924 \let\\\@arraycr \let\tabularnewline\\\let\par\@empty \@preamble}
1928 % \begin{macro}{\arraybackslash}
1929 % \changes{v2.4a}{2003/12/17}{(DPC) Macro added (from tabularx)}
1930 % Restore =\\= for use in array and tabular environment (after
1931 % =\raggedright= etc.).
1933 \def\arraybackslash{\let\\\tabularnewline}
1937 % \begin{macro}{\extrarowheight}
1938 % The \textsf{dimen} parameter used above also needs to be
1939 % allocated. As a default value we use \textsf{0pt}, to ensure
1940 % compatibility with standard \LaTeX.
1942 \newdimen \extrarowheight
1947 % \begin{macro}{\@arstrut}
1948 % Now the insertion of =\@arstrutbox= through =\@arstut=
1949 % is easy since we know exactly in which mode \TeX\ is while working
1950 % on the =\halign= preamble.
1952 \def\@arstrut{\unhcopy\@arstrutbox}
1957 % \section{The line separator \texttt{\textbackslash\textbackslash}}
1959 % \begin{macro}{\@arraycr}
1960 % In the macro =\@array= the line separator =\\= is
1961 % =\let= to the command =\@arraycr=.
1962 % Its definition starts with a special brace which I have directly
1963 % copied from the original definition. It is
1964 % necessary, because the =\futurlet= in =\@ifnextchar=
1966 % expand a following =&= \textsf{token} in a construction like
1967 % =\\ &=. This would otherwise end the alignment template at a
1968 % wrong time. On the other hand we have to be careful to avoid
1969 % producing a real group, i.e.\ ={}=, because the command will also
1970 % be used for the array environment, i.e.\ in math mode. In that
1971 % case an extra ={}= would produce an ord atom which could mess up
1972 % the spacing. For this reason we use a combination that does not
1973 % really produce a group at all but modifies the master counter so
1974 % that a =&= will not be considered belonging to the current
1975 % =\halign= while we are looking for a =*= or =[=.
1976 % For further information see
1977 % \cite[Appendix D]{bk:knuth}.
1978 % \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
1980 \def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi
1982 % Then we test whether the user is using the star form and ignore
1983 % a possible star (I also disagree with this procedure, because a
1984 % star does not make any sense here).
1986 \@ifstar \@xarraycr \@xarraycr}
1990 % \begin{macro}{\@xarraycr}
1991 % In the command =\@xarraycr= we test if an optional argument
1994 \def\@xarraycr{\@ifnextchar [%
1996 % If it does, we branch out into the macro =\@argarraycr= if
1997 % not we close the special brace (mentioned above) and end the row
1998 % of the =\halign= with a =\cr=.
1999 % \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
2001 \@argarraycr {\ifnum 0=`{}\fi\cr}}
2006 % \begin{macro}{\@argarraycr}
2007 % If additional space is requested by the user this case is treated
2008 % in the macro =\@argarraycr=. First we close the special brace
2009 % and then we test if the additional space is positive.
2010 % \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
2012 \def\@argarraycr[#1]{\ifnum0=`{}\fi\ifdim #1>\z@
2014 % If this is the case we create an invisible vertical rule with
2015 % depth =\dp\@arstutbox=${}+{}$\meta{wanted\ space}.
2016 % Thus we achieve that all vertical lines specified
2017 % in the user preamble by a \texttt{|} are now
2019 % Then the row ends with a =\cr=.
2021 % If the space is negative we end the row at once with a =\cr=
2022 % and move back up with a =\vskip=.
2024 % While testing these macros I found out that the
2026 % created by =\cr= and =&= is something like an
2027 % =\outer= primitive and therefore it should not appear in
2028 % incomplete =\if= statements. Thus the following solution was
2029 % chosen which hides the =\cr= in other macros when \TeX\
2030 % is skipping conditional text.
2031 % \changes{v2.3c}{1995/04/23}{Use \cs{expandafter}'s in conditional}
2033 \expandafter\@xargarraycr\else
2034 \expandafter\@yargarraycr\fi{#1}}
2038 % \begin{macro}{\@xargarraycr}
2039 % \begin{macro}{\@yargarraycr}
2040 % The following macros were already explained above.
2042 \def\@xargarraycr#1{\unskip
2043 \@tempdima #1\advance\@tempdima \dp\@arstrutbox
2044 \vrule \@depth\@tempdima \@width\z@ \cr}
2045 \def\@yargarraycr#1{\cr\noalign{\vskip #1}}
2053 % \section{Spanning several columns}
2055 % \begin{macro}{\multicolumn}
2056 % If several columns should be held together with a special format
2057 % the command =\multicolumn= must be used. It has three
2058 % arguments: the number of columns to be covered; the format for
2059 % the result column and the actual column entry.
2060 % \changes{v2.3j}{1998/01/29}{Command made \cs{long} to match
2061 % kernel change for pr/2180}
2063 \long\def\multicolumn#1#2#3{%
2065 % First we combine the given number of columns into a single one;
2066 % then we start a new block so that the following definition is kept
2069 \multispan{#1}\begingroup
2071 % Since a =\multicolumn= should only describe the format of a
2072 % result column, we redefine =\@addamp= in such a way that one gets
2073 % an error message if one uses more than one \texttt{c},
2074 % \texttt{l}, \texttt{r}, \texttt{p}, \texttt{m} or \texttt{b} in
2075 % the second argument. One should consider that this definition is
2076 % local to the build-up of the preamble; an \textsf{array}-- or
2077 % \textsf{tabular}--environment in the third argument of the
2078 % =\multicolumn= is therefore worked through correctly as well.
2080 \def\@addamp{\if@firstamp \@firstampfalse \else
2083 % Then we evaluate the second argument with the help of
2085 % Now we still have to insert the contents of the \textsf{token}
2086 % register into the =\@preamble=, i.e.\ we have to say
2087 % =\xdef\@preamble{\@preamble}=. This is achieved shorter by
2090 \@mkpream{#2}\@addtopreamble\@empty
2092 % After the =\@preamble= is created we forget all local
2093 % definitions and occupations of the \textsf{token} registers.
2097 % In the special situation of =\multicolumn= =\@preamble=
2098 % is not needed as preamble for a =\halign= but it is directly
2099 % inserted into our table. Thus instead of =\sharp=
2100 % there has to be the column entry (=#3=) wanted by the user.
2104 % Now we can pass the =\@preamble= to \TeX\ . For safety
2105 % we start with an =\@arstrut=. This should usually be in the
2106 % template for the first column however we do not know if this
2107 % template was overwritten by our =\multicolumn=.
2108 % We also add a =\null= at the right end to prevent any following
2109 % =\unskip= (for example from =\\[..]=) to remove the =\tabcolsep=.
2110 % \changes{v2.2e}{1994/06/01}{Added \cs{null}}
2112 \@arstrut \@preamble
2120 % \section{The Environment Definitions}
2122 % After these preparations we are able to define the environments. They
2123 % only differ in the initialisations of =\d@llar...=, =\col@sep=
2126 % \begin{macro}{\@halignto}
2127 % \begin{macro}{\d@llarbegin}
2128 % \begin{macro}{\d@llarend}
2129 % =\d@llar= has to be
2130 % locally asigned since otherwise nested \textsf{tabular} and \textsf{array}
2131 % environments (via =\multicolumn=) are impossible.
2132 % For 25 years or so =\@halignto= was set globally (to save space on the
2133 % save stack, but that was a mistake: if there is a tabular in the
2134 % output routine (e.g., in the running header) then that tabular is
2135 % able overwrite the =\@halignto=
2136 % setting of a tabular in the main text resulting in a very weird error.
2137 % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
2138 % \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on toplevel.}
2139 % When the new font selection scheme is in force we have to
2140 % we surround all =\halign= entries
2141 % with braces. See remarks in TUGboat 10\#2. Actually we are going
2142 % to use =\begingroup= and =\endgroup=. However, this is only
2143 % necessary when we are in text mode. In math the surrounding
2144 % dollar signs will already serve as the necessary extra grouping
2145 % level. Therefore we switch the settings of =\d@llarbegin= and
2146 % =\d@llarend= between groups and dollar signs.
2148 \let\d@llarbegin\begingroup
2149 \let\d@llarend\endgroup
2156 % \begin{macro}{\array}
2157 % Our new definition of =\array= then reads:
2158 % \changes{v2.0d}{1990/08/20}{`d@llar local to preamble.}
2159 % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
2161 \def\array{\col@sep\arraycolsep
2162 \def\d@llarbegin{$}\let\d@llarend\d@llarbegin\def\@halignto{}%
2164 % Since there might be an optional argument we call another
2165 % macro which is also used by the other environments.
2171 % \begin{macro}{\@tabarray}
2172 % This macro tests for a optional bracket and then calls up
2173 % =\@array= or =\@array[c]= (as default).
2175 \def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}}
2180 % \begin{macro}{\tabular}
2181 % \begin{macro}{\tabular*}
2182 % The environments \textsf{tabular} and \textsf{tabular$*$} differ
2183 % only in the initialisation of the command =\@halignto=. Therefore
2185 % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
2187 \def\tabular{\def\@halignto{}\@tabular}
2189 % and analogously for the star form. We evaluate the argument first
2190 % using =\setlength= so that users of the \texttt{calc} package can
2191 % write code like\\ =\begin{tabular*}{(\columnwidth-1cm)/2}...=
2192 % \changes{v2.3l}{1998/05/13}{Use \cs{setlength} evaluate arg
2193 % so that the calc package can be applied here (pr/2793)}
2194 % \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
2196 \expandafter\def\csname tabular*\endcsname#1{%
2197 \setlength\dimen@{#1}%
2198 \edef\@halignto{to\the\dimen@}\@tabular}
2203 % \begin{macro}{\@tabular}
2204 % The rest of the job is carried out by the =\@tabular= macro:
2208 % First of all we have to make sure that we start out in
2209 % \textsf{hmode}. Otherwise we might find our table dangling by
2214 % It should be taken into consideration that the macro =\@array=
2215 % must be called in math mode. Therefore we open a \textsf{box},
2216 % insert a =$= and then assign the correct values to =\col@sep= and
2218 % \changes{v2.0d}{1990/08/20}{`d@llar local to preamble.}
2220 \hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup
2221 \let\d@llarend\endgroup
2223 % Now everything \textsf{tabular} specific is done and we are able to
2224 % call the =\@tabarray= macro.
2230 % \begin{macro}{\endarray}
2231 % When the processing of \textsf{array} is finished we have to
2232 % close the =\halign=
2233 % and afterwards the surrounding \textsf{box} selected by
2234 % =\@array=. To save \textsf{token} space we then redefine
2236 % because its replacement text isn't longer needed.
2238 \def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
2242 % \begin{macro}{\endtabular}
2243 % \begin{macro}{\endtabular*}
2244 % To end a \textsf{tabular} or \textsf{tabular$*$} environment we
2245 % call up =\endarray=, close the math mode and then the surrounding
2248 \def\endtabular{\endarray $\egroup}
2249 \expandafter\let\csname endtabular*\endcsname=\endtabular
2256 % \section{Last minute definitions}
2259 % If this file is used as a package file we should =\let= all macros
2260 % to =\relax= that were used in the original but are no longer
2263 \let\@ampacol=\relax \let\@expast=\relax
2264 \let\@arrayclassiv=\relax \let\@arrayclassz=\relax
2265 \let\@tabclassiv=\relax \let\@tabclassz=\relax
2266 \let\@arrayacol=\relax \let\@tabacol=\relax
2267 \let\@tabularcr=\relax \let\@@endpbox=\relax
2268 \let\@argtabularcr=\relax \let\@xtabularcr=\relax
2271 % \begin{macro}{\@preamerr}
2272 % We also have to redefine the error routine =\@preamerr= since
2273 % new kind of errors are possible.
2274 % The code for this macro is not perfect yet;
2275 % it still needs too much memory.
2277 \def\@preamerr#1{\def\@tempd{{..} at wrong position: }%
2278 \PackageError{array}{%
2279 \ifcase #1 Illegal pream-token (\@nextchar): `c' used\or %0
2280 Missing arg: token ignored\or %1
2281 Empty preamble: `l' used\or %2
2282 >\@tempd token ignored\or %3
2283 <\@tempd changed to !{..}\or %4
2284 Only one column-spec. allowed.\fi}\@ehc} %5
2291 % [Defining your own column specifiers]
2292 % {Defining your own column specifiers\footnotemark}
2294 % \footnotetext{The code and the documentation in this section was
2295 % written by David. So far only the code from newarray was plugged
2296 % into array so that some parts of the documentation still claim
2297 % that this is newarray and even worse, some parts of the code are
2298 % unnecessarily doubled. This will go away in a future release. For
2299 % the moment we thought it would be more important to bring both
2300 % packages together.}
2301 % \changes{v2.1a}{1992/07/03}{Newcolumn stuff added}
2303 % \DeleteShortVerb{\=}
2304 % \MakeShortVerb{\"}
2306 % \begin{macro}{\newcolumn}
2307 % In \texttt{newarray.sty} the macro for specifying new columns was
2308 % named "\newcolumn". When the functionality was added to
2309 % \texttt{array.sty} the command was renamed "\newcolumntype".
2310 % Initially both names were supported, but now (In versions of this
2311 % package distributed for \LaTeXe) the old name is not defined.
2312 % \changes{v2.2a}{1994/02/03}{Now made `newcolumn an error}
2313 % \changes{v2.2a}{1994/02/04}{Removed `newcolumn}
2319 % \begin{macro}{\newcolumntype}
2320 % \changes{v2.1b}{1992/06/07}{Macro renamed from `newcolumn} As
2321 % described above, the "\newcolumntype" macro gives users the chance
2322 % to define letters, to be used in the same way as the primitive
2323 % column specifiers, `c' `p' etc.
2325 \def\newcolumntype#1{%
2327 % "\NC@char" was added in V2.01 so that active characters, like "@" in
2328 % AMS\LaTeX\ may be used. This trick was stolen from \texttt{array.sty}
2329 % 2.0h. Note that we need to use the possibly active token,
2330 % "#1", in several places, as that is the token that actually
2331 % appears in the preamble argument.
2333 \edef\NC@char{\string#1}%
2335 % First we check whether there is already a definition for this column.
2336 % Unlike "\newcommand" we give a warning rather than an error if it is
2337 % defined. If it is a new column, add "\NC@do" \meta{column} to
2338 % the list "\NC@list".
2340 \@ifundefined{NC@find@\NC@char}%
2341 {\@tfor\next:=<>clrmbp@!|\do{\if\noexpand\next\NC@char
2342 \PackageWarning{array}%
2343 {Redefining primitive column \NC@char}\fi}%
2344 \NC@list\expandafter{\the\NC@list\NC@do#1}}%
2345 {\PackageWarning{array}{Column \NC@char\space is already defined}}%
2347 % Now we define a macro with an argument delimited by the new column
2348 % specifier, this is used to find occurrences of this specifier in the
2351 \@namedef{NC@find@\NC@char}##1#1{\NC@{##1}}%
2353 % If an optional argument was not given, give a default argument of 0.
2355 \@ifnextchar[{\newcol@{\NC@char}}{\newcol@{\NC@char}[0]}}
2358 % \begin{macro}{\newcol@}
2359 % We can now define the macro which does the rewriting,
2360 % "\@reargdef" takes the same arguments as "\newcommand", but
2361 % does not check that the command is new. For a column, say `D' with
2362 % one argument, define a command "\NC@rewrite@D" with one
2363 % argument, which recursively calls "\NC@find" on the user preamble
2364 % after replacing the first token or group with the replacement text
2365 % specified in the "\newcolumntype" command. "\NC@find" will find the
2366 % next occurrence of `D' as it will be "\let" equal to
2367 % "\NC@find@D" by "\NC@do".
2369 \def\newcol@#1[#2]#3{\expandafter\@reargdef
2370 \csname NC@rewrite@#1\endcsname[#2]{\NC@find#3}}
2373 % \begin{macro}{\NC@}
2374 % Having found an occurrence of the new column, save the preamble
2375 % before the column in "\@temptokena", then check to see if we
2376 % are at the end of the preamble. (A dummy occurrence of the column
2377 % specifier will be placed at the end of the preamble by "\NC@do".
2380 \@temptokena\expandafter{\the\@temptokena#1}\futurelet\next\NC@ifend}
2383 % \begin{macro}{\NC@ifend}
2384 % We can tell that we are at the end as "\NC@do" will place a "\relax"
2385 % after the dummy column.
2389 % If we are at the end, do nothing. (The whole preamble will now be in
2394 % Otherwise set the flag "\if@tempswa", and rewrite the column.
2395 % "\expandafter" introduced 1n V2.01
2397 \else\@tempswatrue\expandafter\NC@rewrite\fi}
2400 % \begin{macro}{\NC@do}
2401 % If the user has specified `C' and `L' as new columns, the list of
2402 % rewrites (in the token register "\NC@list") will look like
2403 % "\NC@do *" "\NC@do C" "\NC@do L".
2404 % So we need to define "\NC@do" as a one argument macro which
2405 % initialises the rewriting of the specified column. Let us assume that
2406 % `C' is the argument.
2410 % First we let "\NC@rewrite" and "\NC@find" be
2411 % "\NC@rewrite@C" and "\NC@find@C" respectively.
2413 \expandafter\let\expandafter\NC@rewrite
2414 \csname NC@rewrite@\string#1\endcsname
2415 \expandafter\let\expandafter\NC@find
2416 \csname NC@find@\string#1\endcsname
2418 % Clear the token register "\@temptokena" after putting the present
2419 % contents of the register in front of the token "\NC@find". At the
2420 % end we place the tokens `"C\relax"' which "\NC@ifend" will use
2421 % to detect the end of the user preamble.
2423 \expandafter\@temptokena\expandafter{\expandafter}%
2424 \expandafter\NC@find\the\@temptokena#1\relax}
2428 % \begin{macro}{\showcols}
2429 % This macro is useful for debugging "\newcolumntype" specifications,
2430 % it is the equivalent of the primitive "\show" command for macro
2431 % definitions. All we need to do is locally redefine "\NC@do" to take
2432 % its argument (say `C') and then "\show" the (slightly modified)
2433 % definition of "\NC@rewrite@C". Actually as the the list always
2434 % starts off with "\NC@do *" and we do not want to print the
2435 % definition of the $*$-form, define "\NC@do" to throw away the first
2436 % item in the list, and then redefine itself to print the rest of the
2439 \def\showcols{{\def\NC@do##1{\let\NC@do\NC@show}\the\NC@list}}
2442 % \begin{macro}{\NC@show}
2443 % If the column `C' is defined as above, then
2444 % "\show\NC@rewrite@C" would output\\
2445 % "\long macro: ->\NC@find >{$}c<{$}".
2446 % We want to strip the "long macro: ->" and the "\NC@find". So first we
2447 % use "\meaning" and then apply the macro "\NC@strip" to the tokens so
2448 % produced and then "\typeout" the required string.
2451 \typeout{Column #1\expandafter\expandafter\expandafter\NC@strip
2452 \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@}}
2455 % \begin{macro}{\NC@strip}
2456 % Delimit the arguments to "\NC@strip" with `\texttt{:}', `\texttt{->}',
2457 % a space, and "\@@" to pull out the required parts of the output from
2460 \def\NC@strip#1:#2->#3 #4\@@{#2 -> #4}
2463 % \begin{macro}{\NC@list}
2464 % Allocate the token register used for the rewrite list.
2470 % \subsection{The $*$--form}
2471 % We view the $*$-form as a slight generalisation of the system
2472 % described in the previous subsection. The idea is to define a $*$
2473 % column by a command of the form:
2475 % \newcolumntype{*}[2]{%
2476 % \count@=#1\ifnum\count@>0
2477 % \advance\count@ by -1 #2*{\count@}{#2}\fi}
2479 % \begin{macro}{\NC@rewrite@*}\label{NC@rewrite@*}
2480 % \changes{v2.4b}{2005/08/23}{Fix occasional spurious space (PR/3755)}
2481 % This does not work however as "\newcolumntype" takes great care not
2482 % to expand anything in the preamble, and so the "\if" is never
2483 % expanded. "\newcolumntype" sets up various other parts of the
2484 % rewrite correctly though so we can define:
2486 \newcolumntype{*}[2]{}
2488 % Now we must correct the definition of "\NC@rewrite@*". The
2489 % following is probably more efficient than a direct translation of
2490 % the idea sketched above, we do not need to put a $*$ in the preamble
2491 % and call the rewrite recursively, we can just put "#1" copies of
2492 % "#2" into "\@temptokena". (Nested $*$ forms will be expanded
2493 % when the whole rewrite list is expanded again, see "\@mkpream")
2495 \long\@namedef{NC@rewrite@*}#1#2{%
2501 % Put "#1" copies of "#2" in the token register.
2505 \advance\count@\m@ne
2506 \@temptokena\expandafter{\the\@temptokena#2}%
2509 % "\NC@do" will ensure that "\NC@find" is "\let" equal
2516 % \subsection{Modifications to internal macros of \texttt{array.sty}}
2518 % \begin{macro}{\@xexpast}
2519 % \begin{macro}{\@xexnoop}
2520 % These macros are used to expand $*$-forms in
2521 % \texttt{array.sty}. "\let" them to "\relax" to save space.
2529 % \begin{macro}{\save@decl}
2530 % We do not assume that the token register is free, we add the new
2531 % declarations to the front of the register. This is to allow user
2532 % preambles of the form, ">{foo}>{bar}..". Users are not encouraged to
2533 % enter such expressions directly, but they may result from the
2534 % rewriting of "\newcolumntype"'s.
2536 \def\save@decl{\toks \count@ = \expandafter\expandafter\expandafter
2537 {\expandafter\@nextchar\the\toks\count@}}
2540 % \begin{macro}{\@mkpream}
2541 % The main modification to "\@mkpream" is to replace the call to
2542 % "\@xexpast" (which expanded $*$-forms) by a loop which expands
2543 % all "\newcolumntype" specifiers.
2545 \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
2546 \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
2548 % Now we remove possible $*$-forms and user-defined column
2549 % specifiers in the user preamble by repeatedly executing the list
2550 % "\NC@list" until the re-writes have no more effect. The
2551 % expanded preamble will then be in the token register
2552 % "\@temptokena". Actually we need to know at this point that
2553 % this is not "\toks0".
2555 \@temptokena{#1}\@tempswatrue
2556 \@whilesw\if@tempswa\fi{\@tempswafalse\the\NC@list}%
2558 % Afterwards we initialize all registers and macros, that we need
2559 % for the build-up of the preamble.
2565 % Having expanded all tokens defined using "\newcolumntype" (including
2566 % "*"), we evaluate the remaining tokens, which are saved in
2567 % "\@temptokena". We use the \LaTeX--macro "\@tfor" to inspect each
2570 \expandafter \@tfor \expandafter \@nextchar
2571 \expandafter :\expandafter =\the\@temptokena \do
2573 % "\@testpatch" does not take an argument since \texttt{array.sty} 2.0h.
2576 \ifcase \@chclass \@classz \or \@classi \or \@classii
2577 \or \save@decl \or \or \@classv \or \@classvi
2578 \or \@classvii \or \@classviii
2580 % In \texttt{newarray.sty} class 9 is equivalent to class 10.
2584 \@lastchclass\@chclass}%
2585 \ifcase\@lastchclass
2589 \@preamerr \thr@@ \or
2590 \@preamerr \tw@ \@addtopreamble\@sharp \or
2592 \else \@preamerr \@ne \fi
2593 \def\the@toks{\the\toks}}
2597 % \begin{macro}{\@classix}
2598 % \texttt{array.sty} does not allow repeated \texttt{>}
2599 % declarations for the same column. This is allowed in
2600 % \texttt{newarray.sty} as documented in the introduction. Removing
2601 % the test for this case makes class 9 equivalent to class 10, and
2602 % so this macro is redundant. It is "\let" to "\relax" to save
2609 % \begin{macro}{\@classviii}
2610 % In \texttt{newarray.sty} explicitly allow class 2, as repeated
2611 % \texttt{<} expressions are accepted by this package.
2613 \def\@classviii{\ifnum \@lastchclass >\z@\ifnum\@lastchclass=\tw@\else
2614 \@preamerr 4\@chclass 6 \@classvi \fi\fi}
2618 % \begin{macro}{\@classv}
2619 % Class 5 is \texttt{@}-expressions (and is also called by class 1)
2620 % This macro was incorrect in Version~1. Now we do not expand the
2621 % "@"-expression, but instead explicitly replace an
2622 % "\extracolsep" command by an assignment to "\tabskip" by a
2623 % method similar to the "\newcolumntype" system described above.
2624 % "\d@llarbegin" "\d@llarend" were introduced in V2.01 to match
2625 % \texttt{array.sty} 2.0h.
2627 \def\@classv{\save@decl
2628 \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@
2629 \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
2634 % \begin{macro}{\NC@ecs}
2635 % Rewrite the first occurrence of "\extracolsep{1in}" to
2636 % "\tabskip1in\relax". As a side effect discard any tokens after a
2637 % second "\extracolsep", there is no point in the user entering two of
2638 % these commands anyway, so this is not really a restriction.
2640 \def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}%
2641 \ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi}
2647 % \subsection{Support for the \texttt{delarray.sty}}
2649 % The \texttt{delarray.sty} package extends the array syntax by
2650 % supporting the notation of delimiters. To this end we extend the
2651 % array parsing mechanism to include a hook which can be used by this
2652 % (or another) package to do some additional parsing.
2654 % \begin{macro}{\@tabarray}
2655 % This macro tests for an optional bracket and then calls up
2656 % "\@@array" or "\@@array[c]" (as default).
2659 \def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}}
2662 % \begin{macro}{\@@array}
2663 % This macro tests could then test an optional delimiter before the
2664 % left brace of the main preamble argument. Here in the main package
2665 % it simply is let to be "\@array".
2671 % \begin{macro}{\endarray}
2672 % \begin{macro}{\@arrayright}
2673 % We have to declare the hook we put into "\@array" above.
2674 % A similar hook `"\@arrayright"' will be inserted into the
2675 % "\endarray" to gain control. Both defaults to empty.
2677 \def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
2678 \let\@arrayleft\@empty
2679 \let\@arrayright\@empty
2684 % \subsection{Support for \texttt{\textbackslash firsthline} and
2685 % \texttt{\textbackslash lasthline}}
2687 % The Companion~\cite[p.137]{bk:GMS94} suggests two additional
2688 % commands to control the alignments in case of tabulars with
2689 % horizontal lines. They are now added to this package.
2691 % \begin{macro}{\extratabsurround}
2692 % The extra space around a table when "\firsthline" or "\lasthline"
2695 \newlength{\extratabsurround}
2696 \setlength{\extratabsurround}{2pt}
2700 % \begin{macro}{\backup@length}
2701 % This register will be used internally by "\firsthline" and
2704 \newlength{\backup@length}
2708 % \begin{macro}{\firsthline}
2709 % \changes{v2.3h}{1996/05/25}{Complete reimplementation}
2710 % This code can probably be improved but for the moment it should
2713 % We start by producing a single tabular row without any visible
2714 % content that will produce the external reference point in case
2717 \newcommand{\firsthline}{%
2720 % Within this row we calculate "\backup@length" to be the height
2721 % plus depth of a standard line. In addition we have to add the
2722 % width of the "\hline", something that was forgotten in the
2723 % original definition.
2725 \global\backup@length\ht\@arstrutbox
2726 \global\advance\backup@length\dp\@arstrutbox
2727 \global\advance\backup@length\arrayrulewidth
2729 % Finally we do want to make the height of this first line be a bit
2730 % larger than usual, for this we place the standard array strut
2731 % into it but raised by "\extratabsurround"
2733 \raise\extratabsurround\copy\@arstrutbox
2735 % Having done all this we end the line and back up by the value of
2736 % "\backup@length" and then finally place our "\hline". This should
2737 % place the line exactly at the right place but keep the reference
2738 % point of the whole tabular at the baseline of the first row.
2740 }\\[-\backup@length]\hline
2745 % \begin{macro}{\lasthline}
2746 % \changes{v2.3h}{1996/05/25}{Complete reimplementation}
2747 % For "\lasthline" the situation is even worse and I got it
2748 % completely wrong initially.
2750 % The problem in this case is that if the optional argument "[b]"
2751 % is used we do want the reference point of the tabular be at the
2752 % baseline of the last row but at the same time do want the the
2753 % depth of this last line increased by "\extratabsurround" without
2754 % changing the placement "\hline".
2756 % We start by placing the rule followed by an invisible row.
2758 \newcommand{\lasthline}{\hline\multicolumn1c{%
2760 % We now calculate "\backup@length" to be the height and depth of
2761 % two lines plus the width of the rule.
2763 \global\backup@length2\ht\@arstrutbox
2764 \global\advance\backup@length2\dp\@arstrutbox
2765 \global\advance\backup@length\arrayrulewidth
2767 % This will bring us back to the baseline of the second last row:
2769 }\\[-\backup@length]%
2771 % Thus if we now add another invisible row the reference point of
2772 % that row will be at the baseline of the last row (and will be the
2773 % reference for the whole tabular). Since this row is invisible we
2774 % can enlarge its depth by the desired amount.
2777 \lower\extratabsurround\copy\@arstrutbox
2784 % \subsection{Getting the spacing around rules right}
2786 % Beside a larger functionality \texttt{array.sty} has one
2787 % important difference to the standard \texttt{tabular} and
2788 % \texttt{array} environments: horizontal and vertical rules make a
2789 % table larger or wider, e.g., \verb=\doublerulesep= really denotes
2790 % the space between two rules and isn't measured from the middle of
2793 % \begin{macro}{\@xhline}
2794 % For vertical rules this is implemented by the definitions above,
2795 % for horizontal rules we have to take out the backspace.
2796 % \changes{v2.3d}{1995/11/19}{fix space between double rules pr/1945}
2798 \CheckCommand*\@xhline{\ifx\reserved@a\hline
2799 \vskip\doublerulesep
2800 \vskip-\arrayrulewidth
2803 \renewcommand*\@xhline{\ifx\reserved@a\hline
2804 \vskip\doublerulesep