home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / programs / amiga / pastex / macros / distribs / array / array.doc (.txt) < prev    next >
LaTeX Document  |  1992-10-11  |  99KB  |  2,314 lines

  1. % \iffalse meta-comment
  2. % Copyright (C) 1989-1992 by Frank Mittelbach.  All rights reserved.
  3. % This file is part of the array package.
  4. % IMPORTANT NOTICE:
  5. % You are not allowed to change this file.  You may however copy
  6. % this file to a file with a different name and then change the copy
  7. % if you obey the restrictions on file changes described in
  8. % readme.mz.
  9. % You are NOT ALLOWED to distribute this file alone.  You are NOT
  10. % ALLOWED to take money for the distribution or use of this file (or
  11. % a changed version) except for a nominal charge for copying etc.
  12. % You are allowed to distribute this file under the condition that
  13. % it is distributed together with all files mentioned in readme.mz5.
  14. % If you receive only some of these files from someone, complain!
  15. % However, if these files are distributed by established suppliers
  16. % as part of a complete TeX distribution, and the structure of the
  17. % distribution would make it difficult to distribute the whole set
  18. % of files, *those parties* are allowed to distribute only some of
  19. % the files provided that it is made clear that the user will get a
  20. % complete distribution-set upon request to that supplier (not me).
  21. % Notice that this permission is not granted to the end user.
  22. % For error reports in case of UNCHANGED versions see readme.mz
  23. % \fi
  24. \def\fileversion{v2.1b}
  25. \def\filedate{92/07/06}
  26. \def\docdate {92/09/12}
  27. %% \CheckSum{1070}
  28. %% \CharacterTable
  29. %%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
  30. %%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
  31. %%   Digits        \0\1\2\3\4\5\6\7\8\9
  32. %%   Exclamation   \!     Double quote  \"     Hash (number) \#
  33. %%   Dollar        \$     Percent       \%     Ampersand     \&
  34. %%   Acute accent  \'     Left paren    \(     Right paren   \)
  35. %%   Asterisk      \*     Plus          \+     Comma         \,
  36. %%   Minus         \-     Point         \.     Solidus       \/
  37. %%   Colon         \:     Semicolon     \;     Less than     \<
  38. %%   Equals        \=     Greater than  \>     Question mark \?
  39. %%   Commercial at \@     Left bracket  \[     Backslash     \\
  40. %%   Right bracket \]     Circumflex    \^     Underscore    \_
  41. %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
  42. %%   Right brace   \}     Tilde         \~}
  43. %\iffalse   % this is a METACOMMENT !
  44. %% Style-option `array' to use with LaTeX v2.09
  45. %% Copyright (C) 1989-1992 Frank Mittelbach, all rights reserved.
  46. % \fi
  47. % \changes{v1.0b}{87/06/04}{`@classi (faster),
  48. %                        `@classvi (new)   A in preamble means
  49. %                                         \&\& in `halign.}
  50. % \changes{v1.1a}{87/07/05}{New concept:
  51. %                        preamblechar: c,l,r,C,L,R,A,p,t,|,@,!!}
  52. % \changes{v1.1b}{87/09/21}{Again p like original \LaTeX{} and z for
  53. %                        centered `parbox.}
  54. % \changes{v1.2a}{87/09/27}{Completely new implementation.}
  55. % \changes{v1.2b}{87/10/06}{!| does no longer generate space at start
  56. %                        or end of the preamble. Otherwise `hline is
  57. %                        too long.}
  58. % \changes{v1.2b}{87/10/06}{Enlarged `@arstrutbox by 1pt (Test-Impl)
  59. %                         with dimen `@strutheight.}
  60. % \changes{v1.2c}{87/10/22}{New dimen parameter `extrarowheight
  61. %                        (default: 0pt).}
  62. % \changes{v1.2c}{87/10/22}{Enlarged `@arstrutbox by `extrarowheight.
  63. %                        Thus you may avoid large characters to
  64. %                        overprint a `hline.}
  65. % \changes{v1.2c}{87/10/22}{Introduced `m@th in `@array to allow
  66. %                         non-zero values of `mathsurround.}
  67. % \changes{v1.2d}{87/11/02}{Completed the documentation.}
  68. % \changes{v1.2e}{87/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}{87/11/09}{`@testpach documented.}
  72. % \changes{v1.3a}{87/11/11}{Again a new implementation, with a new
  73. %                        concept (cf. the documentation).}
  74. % \changes{v1.3b}{88/03/17}{`@decl expands now into `@empty, i.e. it
  75. %                        disappears when the preamble is generated,
  76. %                        except when the user specifies A{} or
  77. %                        B{}.}
  78. % \changes{v1.4a}{88/03/18}{Test implementation of use of token
  79. %                        registers in order to do without `protect.}
  80. % \changes{v1.4b}{88/03/19}{Changed erroneous class numbers:
  81. %                        5 -!> 6
  82. %                        6 -!> 7
  83. %                        7 -!> 5
  84. %                        Corresponding changes in the macros.}
  85. % \changes{v1.4c}{88/03/19}{Everything except p,z now works with token
  86. %                        registers.}
  87. % \changes{v1.9a}{88/03/20}{Last (so I hope) major change: 1) Options
  88. %                        B,A now called !>,<.  These options now point
  89. %                        to the column they modify.}
  90. % \changes{v1.9a}{88/03/20}{2) `protect is no longer necessary. But
  91. %                           still the macro `@expast needs top be
  92. %                          modified. `multicolumn still does not work.}
  93. % \changes{v1.9b}{88/04/29}{inserted missing `fi in `@testpach.
  94. %                        Corrected \LaTeX bug in `@tfor.}
  95. % \changes{v1.9c}{88/05/07}{Re-introduced `@endpbox.
  96. %                        `multicolumn now works! Version number still
  97. %                        1.9 since the documentation is still not
  98. %                        finished.}
  99. % \changes{v1.9c}{88/05/07}{1) `def `the@toks {`the ...} remaining only
  100. %                        in `@mkpream.  2) Removed `@classiii and
  101. %                        replaced by `save@decl.}
  102. % \changes{v1.9c}{88/05/07}{3) `insert@column contains only `@tempcnta
  103. %                        and `count@ counters.  4) `@@startpbox and
  104. %                        `@@endpbox now totally obsolete.}
  105. % \changes{v1.9d}{88/05/10}{Replaced `number by `the where the `toks
  106. %                        registers' contents are used.}
  107. % \changes{v1.9e}{88/05/11}{Re-introduced `@xargarraycr and
  108. %                        `@yargarraycr, since `endtemplate seems to
  109. %                        be `outer.}
  110. % \changes{v1.9f}{88/05/20}{Small changes finally carried out:
  111. %                        1) `par!=`@empty.
  112. %                        2) {..ifnum0!=!`}...  $\to$ `bgroup and
  113. %                           analoguously `egroup.}
  114. % \changes{v1.9g}{88/02/24}{Inserted again {..ifnum0!=!`}..,
  115. %                        c.f. Appendix D of the \protect\TeX{}book.}
  116. % \changes{v1.9h}{88/06/28}{No longer necessary to read in the file
  117. %                        twice.}
  118. % \changes{v1.9i}{88/06/28}{Corrected typo in german version.}
  119. % \changes{v1.9j}{88/11/23}{In a `r' column an extra `kern`z@ is
  120. %                        needed.}
  121. % \changes{v1.9j}{88/11/23}{Otherwise the `hfil on the left side
  122. %                        will be removed by the `unskip in
  123. %                        `insert@column if the entry is empty.}
  124. % \changes{v1.9k}{88/06/28}{Corrected typo in german version.}
  125. % \changes{v1.9k}{89/01/16}{`begin{Macro} changed to `begin{macro} in
  126. %                        documentation.}
  127. % \changes{v2.0a}{89/05/12}{{\tt\protect\bslash @thetoks} changed to
  128. %                          {\tt\protect\bslash the@toks}.}
  129. % \changes{v2.0a}{89/05/12}{source changed to reflect new doc.sty
  130. %                          conventions.}
  131. % \changes{v2.0a}{89/05/12}{t option renamed to p to be compatible to
  132. %                        the original.}
  133. % \changes{v2.0a}{89/05/12}{File renamed from arraye.sty to array.sty.}
  134. % \changes{v2.0b}{89/05/17}{Three forgotten end macro added.}
  135. % \changes{v2.0b}{89/05/17}{All lines shortened to 72 or less.}
  136. % \DoNotIndex{\@depth,\@ehc,\@fortmp,\@height,\@ifnextchar,\@ifstar}
  137. % \DoNotIndex{\@ifundefined,\@latexerr,\@ne,\@nil,\@tempa,\@tempb}
  138. % \DoNotIndex{\@tempcnta,\@tempd,\@tempdima,\@whilenum,\@width,\\}
  139. % \DoNotIndex{\@tforloop}
  140. % \DoNotIndex{\advance}
  141. % \DoNotIndex{\baselineskip,\begingroup,\bgroup}
  142. % \DoNotIndex{\cr,\crcr,\csname}
  143. % \DoNotIndex{\def,\do,\docdate,\dp}
  144. % \DoNotIndex{\edef,\egroup,\else,\endcsname,\endinput,\expandafter}
  145. % \DoNotIndex{\fi,\filedate,\fileversion}
  146. % \DoNotIndex{\gdef}
  147. % \DoNotIndex{\hbox,\hfil,\hsize,\hskip,\ht}
  148. % \DoNotIndex{\if,\ifcase,\ifdim,\ifnum,\ifx,\ignorespaces}
  149. % \DoNotIndex{\kern}
  150. % \DoNotIndex{\leavevmode,\let,\lineskip}
  151. % \DoNotIndex{\m@ne,\multispan}
  152. % \DoNotIndex{\newcount,\newdimen,\noalign}
  153. % \DoNotIndex{\or}
  154. % \DoNotIndex{\relax}
  155. % \DoNotIndex{\setbox,\space,\strutbox}
  156. % \DoNotIndex{\tabskip,\thr@@,\the,\toks,\toks@,\tw@,\typeout}
  157. % \DoNotIndex{\unhcopy,\unskip}
  158. % \DoNotIndex{\vbox,\vcenter,\vline,\vrule,\vtop,\vskip}
  159. % \DoNotIndex{\xdef}
  160. % \DoNotIndex{\z@}
  161. % \title{A new implementation of \LaTeX's {\sf tabular}
  162. %        and {\sf array} environment\thanks{This file
  163. %        has version number \fileversion, last
  164. %        revised \filedate, documentation dated \docdate.}}
  165. % \author{Frank Mittelbach
  166. %         \and
  167. %         David Carlisle\thanks{David kindly agreed on the inclusion
  168. %         of the {\tt\string\newcolumntype} implementation, formerly in
  169. %         {\tt newarray.sty} into this style option}}
  170. % \date{Printed \today}
  171. % \maketitle
  172. % \MakeShortVerb{\=}
  173. % \begin{abstract}
  174. % This article describes a new implementation of the \LaTeX\
  175. % {\sf array}-- and {\sf tabular}--environments. The special merits of
  176. % this
  177. % implementation are further options to format columns and the fact
  178. % that fragile \LaTeX--commands don't have to be =\protect='ed any
  179. % more within those environments.
  180. % At the same time it shows a new --- and in our opinion sensible ---
  181. % way of documenting \TeX\--macros: This article \underline{is the
  182. % style--file} that is to be used. All we need in addition to it is a
  183. % short \TeX--program which visualizes the comments and puts the
  184. % definitions in verbatim mode.
  185. % \end{abstract}
  186. % \section{Introduction}
  187. % This new implementation of the {\sf array}-- and {\sf
  188. % tabular}--environments is part of a larger project in which we are
  189. % trying to improve the \LaTeX\--code in some aspects and to make
  190. % \LaTeX\ even easier to handle.
  191. % The reader should be familiar with the general structure of the
  192. % environments
  193. % mentioned above. Further information can be found in {\sc Lamport}
  194. % \cite{bk:lamport}. The additional options which can be used in the
  195. % preamble as well as those which now have a slightly different meaning
  196. % are described in table~\ref{tab:opt}.
  197. % \DescribeMacro\extrarowheight
  198. % Additionally we introduce a new
  199. % parameter called =\extrarowheight=. If it takes a positive
  200. % length, the value of the parameter is added to the normal height of
  201. % every row of the table, while
  202. % the depth will remain the same. This is important for tables
  203. % with horizontal lines because those lines normally touch the
  204. % capital letters.
  205. % For example, we used =\setlength{\extrarowheight}{1pt}=
  206. % in table~\ref{tab:opt}.
  207. % \begin{table}[t]
  208. % \begin{center}
  209. %    \setlength{\extrarowheight}{1pt}
  210. %    \begin{tabular}{|>{\tt}c|m{9cm}|}
  211. %       \hline
  212. %     \multicolumn{2}{|c|}{Unchanged options}\\
  213. %       \hline
  214. %       l             &  Left adjusted column. \\
  215. %       c             &  Centered adjusted column. \\
  216. %       r             &  Right adjusted column. \\
  217. %       p\{width\}    &  Equivalent to =\parbox[t]{width}=. \\
  218. %       @\{decl.\}    &  Suppresses inter-column space and inserts
  219. %                        {\tt decl.}\ instead. \\
  220. %       \hline
  221. %     \multicolumn{2}{|c|}{New options}\\
  222. %       \hline
  223. %       m\{width\}    &  Defines a column of width {\tt width}.
  224. %                        Every entry will be centered in proportion to
  225. %                        the rest of the line. It is somewhat like
  226. %                        =\parbox{width}=. \\
  227. %       \hline
  228. %       b\{width\}    &  Coincides with =\parbox[b]{width}=. \\
  229. %       \hline
  230. %       >\{decl.\}    &  Can be used before an {\tt l}, {\tt r},
  231. %                        {\tt c}, {\tt p}, {\tt m} or a {\tt b}
  232. %                        option. It inserts
  233. %                        {\tt decl.}\ directly in front of the entry of
  234. %                        the column.   \\
  235. %       \hline
  236. %       <\{decl.\}    &  Can be used after an {\tt l}, {\tt r},
  237. %                        {\tt c}, =p{..}=, =m{..}= or a
  238. %                        =b{..}= option.
  239. %                        It inserts {\tt decl.}\ right after the entry
  240. %                        of the column.   \\
  241. %       \hline
  242. %       |             &  Inserts a vertical line. The distance between
  243. %                        two columns will be enlarged by the width of
  244. %                        the line
  245. %                        in contrast to the original definition of
  246. %                        \LaTeX.  \\
  247. %       \hline
  248. %       !\{decl.\}    &  Can be used anywhere and corresponds with the
  249. %                        {\tt |} option. The difference is that
  250. %                        {\tt decl.} is inserted instead of a vertical
  251. %                        line, so this option doesn't suppress the
  252. %                        normally inserted space between columns in
  253. %                        contrast to =@{...}=.\\
  254. %       \hline
  255. %    \end{tabular}
  256. % \end{center}
  257. % \caption{The  preamble options.} \label{tab:opt}
  258. % \end{table}
  259. % We will discuss a few examples using the new preamble options before
  260. % dealing with the implementation.
  261. % \begin{itemize}
  262. %    \item
  263. %       If you want to use a special font (for example =\bf=) in a
  264. %       flushed left column, this can be done with =>{\bf}l=. You
  265. %       do not have to begin every entry of the column with  =\bf=
  266. %       any more.
  267. %    \item
  268. %       In columns which have been generated with {\tt p}, {\tt m}
  269. %       or {\tt b}, the default value of =\parindent= is
  270. %       {\sf 0pt}.
  271. %       This can be changed with \\
  272. %       =>{\setlength{\parindent}{1cm}}p=.
  273. %    \item
  274. %       The {\tt <}--option was originally developed for the following
  275. %       application:
  276. %       =>{$}c<{$}= generates a column in math mode in a
  277. %       {\sf tabular}--environment. If you use this type of a preamble
  278. %       in an
  279. %       {\sf array}--environment, you get a column in LR mode because
  280. %       the additional \$'s cancel the existing \$'s.
  281. %    \item
  282. %       One can also think of more complex applications. A problem
  283. %       which has
  284. %       been mentioned several times in \TeX{}hax can be solved with
  285. %       =>{\centerdots}c=\linebreak[0]=<{\endcenterdots}=.
  286. %       To center decimals at their
  287. %       decimal points you (only?) have to define the following macros:
  288. %       \begin{verbatim}
  289. %{\catcode`\.\active\gdef.{\egroup\setbox2\hbox\bgroup}}
  290. %\def\centerdots{\catcode`\.\active\setbox0\hbox\bgroup}
  291. %\def\endcenterdots{\egroup\ifvoid2 \setbox2\hbox{0}\fi
  292. %   \ifdim \wd0>\wd2 \setbox2\hbox to\wd0{\unhbox2\hfill}\else
  293. %     \setbox0\hbox to\wd2{\hfill\unhbox0}\fi
  294. %   \catcode`\.12 \box0.\box2}
  295. %\end{verbatim}
  296. %      Warning: The code is bad, it doesn't work with more than one
  297. %      dot in a cell and doesn't work when the tabular is used in the
  298. %      argument of some other command. A much better version is
  299. %      provided in the {\tt dcolumn.sty} by David Carlisle.
  300. %    \item
  301. %       Using =c!{\hspace{1cm}}c= you get space between two
  302. %       columns which is enlarged by one centimeter, while
  303. %       =c@{\hspace{1cm}}c= gives you exactly one centimeter
  304. %       space between two columns.
  305. % \end{itemize}
  306. % \subsection{Defining new column specifiers}
  307. % \DeleteShortVerb{\=}
  308. % \MakeShortVerb{\"}
  309. % \DescribeMacro{\newcolumntype}
  310. % Whilst it is handy to be able to type
  311. % \begin{quote}
  312. %   ">{"\meta{some declarations}"}{c}<{"\meta{some more
  313. %   declarations}"}"
  314. % \end{quote}
  315. % if you have a one-off column in a table, it is rather inconvenient
  316. % if you often use columns of this form. The new version allows you
  317. % to define a new column specifier, say {\tt x}, which will expand to
  318. % the primitives column specifiers.\footnote{This command was named
  319. % {\tt\string\newcolumn} in the {\tt newarray.sty} option. At the
  320. % moment {\tt\string\newcolumn} is still supported (but gives a
  321. % warning). In later releases it will vanish.} Thus we
  322. % may define
  323. % \begin{quote}
  324. %   "\newcolumntype{x}{>{"\meta{some declarations}"}{c}<{"\meta{some
  325. %   more declarations}"}}"
  326. % \end{quote}
  327. % One can then use the {\tt x} column specifier in the preamble
  328. % arguments of all {\tt array} or {\tt tabular} environments in which
  329. % you want columns of this form.
  330. % It is common  to need math-mode and LR-mode columns in the same
  331. % alignment. If we define:
  332. % \begin{quote}
  333. %   "\newcolumntype{C}{>{$}c<{$}}" \\
  334. %   "\newcolumntype{L}{>{$}l<{$}}" \\
  335. %   "\newcolumntype{R}{>{$}r<{$}}"
  336. % \end{quote}
  337. % Then we can use {\tt C} to get centred LR-mode in an {\tt array}, or
  338. % centred math-mode in a {\tt tabular}.
  339. % The example given above for `centred decimal points' could be
  340. % assigned to a {\tt d} specifier with the following command.
  341. % \begin{quote}
  342. % "\newcolumntype{d}{>{\centerdots}c<{\endcenterdots}}"
  343. % \end{quote}
  344. % The above solution always centres the dot in the
  345. % column. This does not look too good if the column consists of large
  346. % numbers, but to only a few decimal places. An alternative definition
  347. % of a {\tt d} column is
  348. % \begin{quote}
  349. %   "\newcolumntype{d}[1]{>{\rightdots{#1}}r<{\endrightdots}}"
  350. % \end{quote}
  351. % where the appropriate macros in this case are:\footnote{The style {\tt
  352. % dcolumn.sty} contains more robust macros based on these ideas.}
  353. % \begin{verbatim}
  354. %   \def\coldot{.}% Or if you prefer, \def\coldot{\cdot}
  355. %   {\catcode`\.=\active
  356. %     \gdef.{$\egroup\setbox2=\hbox to \dimen0 \bgroup$\coldot}}
  357. %   \def\rightdots#1{%
  358. %     \setbox0=\hbox{$1$}\dimen0=#1\wd0
  359. %     \setbox0=\hbox{$\coldot$}\advance\dimen0 \wd0
  360. %     \setbox2=\hbox to \dimen0 {}%
  361. %     \setbox0=\hbox\bgroup\mathcode`\.="8000 $}
  362. %   \def\endrightdots{$\hfil\egroup\box0\box2}
  363. %\end{verbatim}
  364. % Note that "\newcolumntype" takes the same optional argument as
  365. % "\newcommand" which declares the number of arguments of the column
  366. % specifier being defined. Now we can specify "d{2}" in our preamble
  367. % for a column of figures to at most two decimal places.
  368. % A rather different use of the "\newcolumntype" system takes
  369. % advantage of the fact that the replacement text in the
  370. % "\newcolumntype" command may refer to more than one column. Suppose
  371. % that a document contains a lot of {\tt tabular} environments that
  372. % require the same preamble, but you wish to experiment with different
  373. % preambles. Lamport's original definition allowed you to do the
  374. % following (although it was probably a mis-use of the system).
  375. % \begin{quote}
  376. %   "\newcommand{\X}{clr}"\\
  377. %   "\begin{tabular}{\X}" \ldots
  378. % \end{quote}
  379. % {\tt array.sty} takes great care {\bf not} to expand the preamble, and
  380. % so the above does not work with the new scheme. With the new version
  381. % this functionality is returned:
  382. % \begin{quote}
  383. % "\newcolumntype{X}{clr}"\\
  384. % "\begin{tabular}{X}" \ldots
  385. % \end{quote}
  386. % The replacement text in a "\newcolumntype" command may refer to any of
  387. % the primitives of {\tt array.sty} see table \ref{tab:opt} on page
  388. % \pageref{tab:opt}, or to any new letters defined in other
  389. % "\newcolumntype" commands.
  390. % \DescribeMacro{\showcols}A list of all the currently active
  391. % "\newcolumntype" definitions is sent to the terminal and log file if
  392. % the "\showcols" command is given.
  393. % \section{Final Comments}
  394. % \subsection{Comparisons with older versions of {\tt array.sty}}
  395. % There are some differences in the way version 2.1 treat incorrect
  396. % input, even if the source file does not appear to use any of the
  397. % extra features of the new version.
  398. % \begin{itemize}
  399. % \item A preamble of the form "{wx*{0}{abc}yz}" was treated by
  400. % versions prior to 2.1 as "{wx}". Version 2.1 treats it as "{wxyz}"
  401. % \item An incorrect positional argument such as {\tt [Q]} is treated as
  402. % {\tt [c]} by {\tt array.sty}, but is now treated as {\tt [t]}.
  403. % \item A preamble such as "{cc*{2}}" with an error in a
  404. % $*$-form will generate different errors in the new version. In both
  405. % cases the error message is not particularly helpful to the casual
  406. % user.
  407. % \item Repeated {\tt <} or {\tt >} constructions did generate an error
  408. %  in earlier versions, but are new allowed in this style.
  409. % ">{"\meta{decs1}"}>{"\meta{decs2}"}" is treated
  410. % the same as ">{"\meta{decs2}\meta{decs1}"}".
  411. % \item The "\extracolsep" command does not work with the old versions
  412. % of {\tt array.sty},
  413. % see the comments in {\tt array.bug}. With version 2.1
  414. % "\extracolsep" may again be used in {\tt@}-expressions as in standard
  415. % \LaTeX, and also in {\tt!}-expressions (but see the note below).
  416. % \end{itemize}
  417. % \subsection{Bugs and Features}
  418. % \begin{itemize}
  419. % \item Error messages generated when parsing the column specification
  420. %   refer to the preamble argument {\bf after} it has been re-written
  421. %   by the "\newcolumntype" system, not to the preamble entered by the
  422. %   user.  This seems inevitable with any system based on
  423. %   pre-processing and so is classed as a {\bf feature}.
  424. % \item The treatment of multiple {\tt<} or {\tt>} declarations may
  425. %   seem strange at first. Earlier implementations treated
  426. %   ">{"\meta{decs1}"}>{"\meta{decs2}"}" the same as
  427. %   ">{"\meta{decs1}\meta{decs2}"}". However this did not give the
  428. %   user the opportunity of overriding the settings of a
  429. %   "\newcolumntype" defined using these declarations. For example,
  430. %   suppose in an {\tt array} environment we use a {\tt C} column
  431. %   defined as above. The {\tt C} specifies a centred text column,
  432. %   however ">{\bf}C", which re-writes to ">{\bf}>{$}c<{$}" would not
  433. %   specify a bold column as might be expected, as the preamble would
  434. %   essentially expand to "\hfil$\bf$#$ $\hfil" and so the column
  435. %   entry would not be in the scope of the "\bf"\,! The present
  436. %   version switches the order of repeated declarations, and so the
  437. %   above example now produces a preamble of the form "\hfil$"
  438. %   "$\bf#$" "$\hfil", and the dollars cancel each other out without
  439. %   limiting the scope of the "\bf".
  440. % \item The use of "\extracolsep" has been subject to the following
  441. %   two restrictions.  There must be at most one "\extracolsep"
  442. %   command per "@", or "!" expression and the command must be
  443. %   directly entered into the "@" expression, not as part of a macro
  444. %   definition. Thus "\newcommand{\ef}{\extracolsep{\fill}}" \ldots
  445. %   "@{\ef}" does not work with this style. However you can use
  446. %   something like
  447. %   "\newcolumntype{e}{@{\extracolsep{\fill}}" instead.
  448. % \end{itemize}
  449. % \typeout{^^JEnd of the Introduction and Examples.}
  450. % \typein[\answer]%
  451. %   {Do you want an annotated listing of the macro definitions (y/n) ?}
  452. % \def\next{y}\ifx\answer\next\else\OnlyDescription\fi
  453. % \StopEventually{
  454. % \begin{thebibliography}{1}
  455. %    \bibitem{bk:knuth}  {\sc D. E. Knuth}.
  456. %       \newblock  The \TeX{}book (Computers \& Typesetting Volume A).
  457. %       \newblock
  458. %       Addison-Wesley, Reading, Massachusetts, 1986.
  459. %    \bibitem{cd:knuth}  {\sc D. E. Knuth}.
  460. %       \newblock
  461. %       The \TeX{}program (Computers \& Typesetting Volume B).
  462. %       \newblock
  463. %       Addison-Wesley, Reading, Massachusetts, 1986.
  464. %    \bibitem{bk:lamport} {\sc L. Lamport}.
  465. %       \newblock
  466. %       \LaTeX\ -- A Document Preparation System.
  467. %       \newblock
  468. %       Addison-Wesley, Reading, Massachusetts, 1986.
  469. %    \bibitem{cd:lamport} {\sc L. Lamport}.
  470. %       \newblock
  471. %       {\tt latex.tex}, Version 2.09 of $\left\langle
  472. %                                            \mbox{15. Sept. 87}
  473. %                                         \right\rangle  $.
  474. % \end{thebibliography}
  475. % }   ^^A  end of \StopEventually
  476. % \section{The construction of the preamble}
  477. % \DeleteShortVerb{\"}
  478. % \MakeShortVerb{\=}
  479. % It is obvious that those environments will consist mainly of an
  480. % =\halign=, because \TeX\ typesets tables using this primitive.
  481. % That is why we will now take a look at the algorithm which determines
  482. % a preamble for a =\halign= starting with a given user preamble
  483. % using the options mentioned above.
  484. % First we will define the current version of this file:
  485. %    \begin{macrocode}
  486. %<*style>
  487. \@ifundefined{d@llarbegin}{}{\endinput}
  488. \typeout{Style-Option: `array' \fileversion 
  489.          \space\space <\filedate> (F.M.)}
  490. \typeout{English documentation dated \space <\docdate> (F.M.)}
  491. %    \end{macrocode}
  492. % The most interesting macros of this implementation are without doubt
  493. % those
  494. % which are responsible for the construction of the preamble
  495. % for the =\halign=. The underlying algorithm was developed by
  496. % {\sc Lamport} (resp.\ {\sc Knuth}, see texhax V87\#??), and it has
  497. % been
  498. % extended and improved.
  499. % The user preamble will be read {\sf token} by {\sf token}.
  500. % A {\sf token} is a single character like {\tt c} or a block enclosed
  501. % ={...}=. For example the preamble of
  502. % =\begin{tabular}=\linebreak[0]={lc||c@{\hspace{1cm}}}=
  503. % consists of the {\sf token}
  504. % {\tt l}, {\tt c}, {\tt |}, {\tt |}, {\tt @} and =\hspace{1cm}=.
  505. % The currently used {\sf token} and the one, used before, are needed
  506. % to decide on how the construction of the preamble has to be
  507. % continued.
  508. % In the example mentioned above the {\tt l} causes the preamble
  509. % to begin with =\hskip\tabcolsep=. Furthermore
  510. % =# \hfil= would be appended to define a flush left column.
  511. % The next {\sf token} is a {\tt c}. Because it was preceded by an
  512. % {\tt l} it generates a new column. This is done with
  513. % =\hskip \tabcolsep & \hskip \tabcolsep=. The column which is to
  514. % be centered will be appended with =\hfil # \hfil=.
  515. % The {\sf token} {\tt |} would then add a space of
  516. % =\hskip \tabcolsep=
  517. % and a vertical line because the last
  518. % {\sf tokens} was a {\tt c}.
  519. % The following {\sf token} {\tt |} would only add a space
  520. % =\hskip \doublerulesep= because it was preceded by the
  521. % {\sf token} {\tt |}. We will not discuss our example further but
  522. %  rather take a look at the general case of constructing preambles.
  523. % The example shows that the desired preamble for the
  524. % =\halign= can be constructed as soon as the action of all
  525. % combinations
  526. % of the preamble {\sf tokens} are specified. There are 18 such
  527. % {\sf tokens}
  528. % so we have $19 \cdot 18 \string= 342$ combinations if we count the
  529. % beginning of
  530. % the preamble as a special {\sf token}. Fortunately, there are many
  531. % combinations which generate the same spaces, so we can define
  532. % {\sf token} classes. We will identify a
  533. % {\sf token} within a class with a number, so we can insert the
  534. % formatting (for example of a column).
  535. % Table~\ref{tab:Klassen} lists all {\sf token} classes and
  536. % their corresponding numbers.
  537. % \begin{table}[ht]
  538. % \begin{center}
  539. %    \begin{tabular}[t]{>{\tt}ccc}
  540. %       {\sf token} & =\@chclass= & =\@chnum= \\[2mm]
  541. %       c   & 0  & 0 \\
  542. %       l   & 0  & 1 \\
  543. %       r   & 0  & 2 \\
  544. %       p-arg    & 0  & 3 \\
  545. %       t-arg    & 0  & 4 \\
  546. %       b-arg    & 0  & 5 \\
  547. %       |   & 1  & 0 \\
  548. %       !-arg    & 1  & 1 \\
  549. %       <-arg    & 2  & --- \\
  550. %       >-arg    & 3  & ---
  551. %    \end{tabular}
  552. %    \kern3mm \vrule \kern3mm%
  553. %    \begin{tabular}[t]{>{\tt}ccc}
  554. %       {\sf token} & =\@chclass= & =\@chnum= \\[2mm]
  555. %       Start    & 4  & --- \\
  556. %       @-arg    & 5  & --- \\
  557. %       !   & 6  & --- \\
  558. %       @   & 7  & --- \\
  559. %       <   & 8  & --- \\
  560. %       >   & 9  & --- \\
  561. %       p   & 10 & 3 \\
  562. %       t   & 10 & 4 \\
  563. %       b   & 10 & 5
  564. %    \end{tabular}
  565. % \end{center}
  566. % \caption{Classes of preamble {\sf tokens}}
  567. % \label{tab:Klassen}
  568. % \end{table}
  569. % \begin{macro}{\@chclass}
  570. % \begin{macro}{\@chnum}
  571. % \begin{macro}{\@lastchclass}
  572. %    The class and the number of the current {\sf token} are saved in
  573. %    the
  574. %    {\sf count} registers =\@chclass=
  575. %    and =\@chnum=, while the class of the previous
  576. %    {\sf token} is stored in the
  577. %    {\sf count} register =\@lastchclass=.
  578. %    All of the mentioned registers are already allocated in
  579. %    {\tt latex.tex},
  580. %    which is the reason why the following three lines of code are
  581. %    commented out.
  582. %    Later throughout the text I will not mention it again explicitely
  583. %    whenever I use a =%= sign. These parts are already defined in
  584. %    {\tt latex.tex}.
  585. %    \begin{macrocode}
  586. % \newcount \@chclass
  587. % \newcount \@chnum
  588. % \newcount \@lastchclass
  589. %    \end{macrocode}
  590. % \end{macro}
  591. % \end{macro}
  592. % \end{macro}
  593. % \begin{macro}{\@addtopreamble}
  594. %    We will save the already constructed preamble for
  595. %    the =\halign=
  596. %    in the global macro =\@preamble=. This will then be
  597. %     enlarged with
  598. %    the command =\@addtopreamble=.
  599. %    \begin{macrocode}
  600. \def\@addtopreamble#1{\xdef\@preamble{\@preamble #1}}
  601. %    \end{macrocode}
  602. % \end{macro}
  603. % \subsection{The character class of a {\sf token}}
  604. % \begin{macro}{\@testpach}
  605. % \changes{v2.0a}{89/05/12}{p option renamed to m (middle).}
  606. % \changes{v2.0a}{89/05/12}{t option renamed to p to be compatible to
  607. %                         the original.}
  608. %    With the help of =\@lastchclass= we can now define a macro
  609. %    which determines the class and the number of a given preamble
  610. %    {\sf token}
  611. %    and assigns them to the registers
  612. %    =\@chclass= and =\@chnum=.
  613. % \changes{v2.0f}{92/02/29}{Argument removed since implicitly known}
  614. %    \begin{macrocode}
  615. \def\@testpach{\@chclass
  616. %    \end{macrocode}
  617. %    First we deal with the cases in which the {\sf token}
  618. %    (=#1=) is the argument of {\tt !}, {\tt @}, {\tt <} or
  619. %    {\tt >}. We can see this from the value of =\@lastchclass=:
  620. %    \begin{macrocode}
  621.  \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
  622.   \ifnum \@lastchclass=7 5 \else
  623.    \ifnum \@lastchclass=8 \tw@ \else
  624.     \ifnum \@lastchclass=9 \thr@@
  625. %    \end{macrocode}
  626. %    Otherwise we will assume that the {\sf token} belongs to the
  627. %    class $0$
  628. %    and assign the corresponding number to =\@chnum= if our
  629. %    assumption is correct.
  630. %    \begin{macrocode}
  631.    \else \z@
  632. %    \end{macrocode}
  633. %    If the last {\sf token} was a {\tt p}, {\tt m} or a {\tt b},
  634. %    =\@chnum= already has the right value. This is the reason for
  635. %    the
  636. %    somewhat curious choice of the {\sf token} numbers in class $10$.
  637. %    \begin{macrocode}
  638.    \ifnum \@lastchclass = 10 \else
  639. %    \end{macrocode}
  640. %    Otherwise we will check if =\@nextchar= is either a {\tt c}, {\tt
  641. %    l} or an {\tt r}.  Some applications change the catcodes of
  642. %    certain characters like ``{\tt@}'' in {\tt amstex.sty}. As a
  643. %    result the tests below would fail since they assume non-active
  644. %    character tokens. Therefore we evaluate =\@nextchar= once thereby
  645. %    turning the first token of its replacement text into a char. At
  646. %    this point here this should have been the only char present in
  647. %    =\@nextchar= which put into via a =\def=.
  648. % \changes{v2.0f}{92/02/29}{Ensure to test a char which is not active}
  649. %    \begin{macrocode}
  650.    \edef\@nextchar{\expandafter\string\@nextchar}%
  651.    \@chnum
  652.    \if \@nextchar c\z@ \else
  653.     \if \@nextchar l\@ne \else
  654.      \if \@nextchar r\tw@ \else
  655. %    \end{macrocode}
  656. %    If it is a different {\sf token}, we know that the class was
  657. %    not $0$. We assign the
  658. %    value $0$ to =\@chnum= because this value is needed for the
  659. %    {\tt |}--{\sf token}. Now we must check the remaining classes.
  660. %    Note that the value of =\@chnum= is insignificant here for
  661. %    most classes.
  662. %    \begin{macrocode}
  663.    \z@ \@chclass
  664.    \if\@nextchar |\@ne \else
  665.     \if \@nextchar !6 \else
  666.      \if \@nextchar @7 \else
  667.       \if \@nextchar <8 \else
  668.        \if \@nextchar >9 \else
  669. %    \end{macrocode}
  670. %    The remaining permitted {\sf tokens} are {\tt p}, {\tt m} and
  671. %    {\tt b} (class $10$).
  672. %    \begin{macrocode}
  673.   \@chnum
  674.   \if \@nextchar m\thr@@\else
  675.    \if \@nextchar p4 \else
  676.     \if \@nextchar b5 \else
  677. %    \end{macrocode}
  678. %    Now the only remaining possibility is a forbidden {\sf token},
  679. %    so we choose class $0$ and number $0$ and give an error message.
  680. %    Then we finish the macro by closing all =\if='s.
  681. %    \begin{macrocode}
  682.    \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
  683.    \fi \fi  \fi  \fi  \fi  \fi  \fi \fi \fi \fi \fi \fi}
  684. %    \end{macrocode}
  685. % \end{macro}
  686. % \subsection{Multiple columns ($*$--form)}
  687. % \begin{macro}{\@xexpast}
  688. % \begin{macro}{\the@toks}
  689. % \begin{macro}{\the@toksz}
  690. %    \label{@xexpast}
  691. %    Now we discuss the macro that deletes all forms of type
  692. %    =*{={\it N\/}=}{={\it String\/}=}= from a user
  693. %    preamble and replaces them with {\it N} copies of {\it String}.
  694. %    Nested $*$--expressions are dealt with correctly, that means
  695. %    $*$--expressions are not substituted if they are in explicit
  696. %    braces, as in =@{*}=.
  697. %    This macro is called via
  698. %    =\@xexpast=$\left\langle
  699. %                          \it preamble
  700. %                     \right\rangle$=*0x\@@=.
  701. %    The $*$--expression =*0x= is being used to terminate the
  702. %    recursion,
  703. %    as we shall see later, and =\@@= serves as an argument
  704. %    delimiter. =\@xexpast= has four arguments. The first
  705. %    one is the part of the
  706. %    user preamble before the first $*$--expression while the second
  707. %    and third ones are the arguments of the first $*$--expression
  708. %    (that is {\it N} and {\it String} in the notation mentioned
  709. %    above).
  710. %    The fourth argument is the rest of the preamble.
  711. %    \begin{macrocode}
  712. \def\@xexpast#1*#2#3#4\@@{%
  713. %    \end{macrocode}
  714. %    The number of copies of {\it String} (=#2=) that are to be
  715. %    produced will be saved in a {\sf count} register.
  716. %    \begin{macrocode}
  717.    \@tempcnta #2
  718. %    \end{macrocode}
  719. %    We save the part of the preamble which does not
  720. %    contain a $*$--form (=#1=)
  721. %    in a \PlainTeX\ {\sf token} register.
  722. %    We also save {\it String} (=#3=) using a \LaTeX\
  723. %    {\sf token} register.
  724. %    \begin{macrocode}
  725.    \toks@={#1}\@temptokena={#3}%
  726. %    \end{macrocode}
  727. %    Now we have to use a little trick to produce {\it N} copies of
  728. %    {\it String}.
  729. %    We could try =\def\@tempa{#1}= and then
  730. %    {\it N} times =\edef\@tempa{\@tempa#3}=. This would have the
  731. %    undesired effect that all macros within =#1= and =#3=
  732. %    would be expanded, although, for example, constructions like
  733. %    =@{..}= are not supposed to be changed.
  734. %    That is why we =\let= two control sequences to
  735. %    be equivalent to =\relax=.
  736. %    \begin{macrocode}
  737.    \let\the@toksz\relax \let\the@toks\relax
  738. %    \end{macrocode}
  739. %    Then we ensure that =\@tempa= contains
  740. %    ={\the@toksz\the@toks...\the@toks}= (the macro
  741. %    =\the@toks= exactly {\it N\/} times) as substitution text.
  742. %    \begin{macrocode}
  743.    \def\@tempa{\the@toksz}%
  744.    \ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do
  745.      {\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}%
  746. %    \end{macrocode}
  747. %    If {\it N\/} was greater than zero we prepare for another call of
  748. %    =\@xexpast=. Otherwise we assume we have reached the end of
  749. %    the user preamble, because we had appended
  750. %    =*0x\@@= when we first called
  751. %     =\@xexpast=.
  752. %    In other words: if the user inserts
  753. %    =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it.
  754. %    \begin{macrocode}
  755.        \let \@tempb \@xexpast \else
  756.        \let \@tempb \@xexnoop \fi
  757. %    \end{macrocode}
  758. %    Now we will make sure that the part of the user preamble, which
  759. %    was already dealt with, will be saved again in =\@tempa=.
  760. %    \begin{macrocode}
  761.    \def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}%
  762.    \edef\@tempa{\@tempa}%
  763. %    \end{macrocode}
  764. %    We have now evaluated the first $*$--expression, and the user
  765. %    preamble up to this point
  766. %    is saved in =\@tempa=. We will put the contents of
  767. %    =\@tempa= and the rest of the user preamble together and work
  768. %    on the result with =\@tempb=. This macro either corresponds
  769. %    to =\@xexpast=, so that the next
  770. %    $*$--expression is handled, or to the macro =\@xexnoop=,
  771. %    which only ends the recursion by deleting its argument.
  772. %    \begin{macrocode}
  773.    \expandafter \@tempb \@tempa #4\@@}
  774. %    \end{macrocode}
  775. % \end{macro}
  776. % \end{macro}
  777. % \end{macro}
  778. % \begin{macro}{\@xexnoop}
  779. %    So the first big problem is solved. Now it is easy to
  780. %    specify =\@xexnoop=.
  781. %    Its argument is delimited by =\@@= and it simply expands to
  782. %    nothing.
  783. %    \begin{macrocode}
  784. %  \def\@xexnoop#1\@@{}
  785. %    \end{macrocode}
  786. % \end{macro}
  787. % \section{The insertion of declarations
  788. %           ({\tt >}, {\tt <}, {\tt !}, {\tt @})}
  789. % The preamble will be enlarged with the help of =\xdef=, but the
  790. % arguments of {\tt >}, {\tt <},~{\tt !}\ and {\tt @} are not supposed
  791. % to be expanded during the construction (we want an implementation
  792. % that doesn't need a =\protect=). So we have to find a way to
  793. % inhibit the expansion of those arguments.
  794. % We will solve this problem with {\sf token} registers. We need one
  795. % register for every {\tt !}\ and {\tt @}, while we need two for every
  796. % {\tt c}, {\tt l}, {\tt r}, {\tt m}, {\tt p} or {\tt b}. This limits
  797. % the number of columns of a table because there are only 256
  798. % {\sf token} registers. But then, who needs tables with more
  799. % than 100 columns?
  800. % One could also find a solution which only needs two or three
  801. % {\sf token} registers by proceeding similarly as in the macro
  802. % =\@xexpast= (see page \pageref{@xexpast}). The advantage of our
  803. % approach is the fact that we avoid some of the problems that arise
  804. % with the other method\footnote{Maybe there are also historical
  805. %  reasons.}.
  806. % So how do we proceed? Let us assume that we had =!{foo}= in the
  807. % user preamble and say we saved {\tt foo} in
  808. % {\sf token} register $5$. Then we call
  809. % =\@addtopreamble{\the@toks5}= where
  810. % =\the@toks= is defined in a way that it does not expand
  811. % (for example it could be equivalent to =\relax=). Every
  812. % following call
  813. % of =\@addtopreamble= leaves =\the@toks5= unchanged in
  814. % =\@preamble=. If the construction of the preamble is completed
  815. % we change the definition of =\the@toks= to
  816. % =\the\toks= and expand =\@preamble= for the last time.
  817. % During this process all parts of the form
  818. %    =\the@toks=$\left\langle
  819. %                        \it Number
  820. %                     \right\rangle  $
  821. % will be substituted by the contents of the respective {\sf token}
  822. % registers.
  823. % As we can see from this informal discussion the construction of the
  824. % preamble has to take place within a group, so that the
  825. % {\sf token} registers we use will be freed later on. For that reason
  826. % we keep all assignments to =\@preamble= global; therefore the
  827. % replacement text of this macro will remain the same after we leave
  828. % the group.
  829. % \begin{macro}{\count@}
  830. %    We further need a {\sf count} register to remember which
  831. %    {\sf token} register is to be used next. This will be initialized
  832. %    with $-1$ if we want to begin with the
  833. %    {\sf token} register $0$. We use the
  834. %    \PlainTeX\ scratch register =\count@= because everything
  835. %    takes place locally. All we have to do is insert
  836. %    =\the@toks= =\the= =\count@= into the preamble.
  837. %    =\the@toks= will remain unchanged and
  838. %    =\the\count@= expands into the saved number.
  839. % \end{macro}
  840. % \begin{macro}{\prepnext@tok}
  841. %    The macro =\prepnext@tok= is in charge of preparing the next
  842. %    {\sf token} register. For that purpose we increase
  843. %    =\count@= by $1$:
  844. %    \begin{macrocode}
  845. \def\prepnext@tok{\advance \count@ \@ne
  846. %    \end{macrocode}
  847. %    Then we locally delete any contents the
  848. %    {\sf token} register might have.
  849. %    \begin{macrocode}
  850.    \toks\count@{}}
  851. %    \end{macrocode}
  852. % \end{macro}
  853. % \begin{macro}{\save@decl}
  854. %    During the construction of the preamble the current {\sf token} is
  855. %    always saved in the macro =\@nextchar= (see the definition
  856. %    of =\@mkpream= on page \pageref{@mkpream}). The macro
  857. %    =\save@decl= saves it into the next free
  858. %    {\sf token} register, i.e.\ in =\toks\count@=.
  859. % \changes{v2.0c}{90/08/14}{`relax removed and added elsewhere.}
  860. %    \begin{macrocode}
  861. \def\save@decl{\toks\count@ \expandafter{\@nextchar}}
  862. %    \end{macrocode}
  863. %    The reason for the  use of =\relax= is the following
  864. %    hypothetical situation in the preamble:
  865. %    \quad =..\the\toks1\the\toks2..= \quad \TeX\ expands
  866. %    =\the\toks2= first in order to find out if the digit =1=
  867. %    is followed by other digits. E.g.\ a =5= saved in the
  868. %    {\sf token} register $2$ would lead \TeX\ to insert the contents
  869. %    of {\sf token} register $15$ instead of $1$ later on.
  870. % The example above referred to an older version of =\save@decl= which
  871. % inserted a =\relex= inside the token register. This is now moved to
  872. % the places where the actual token registers are inserted (look for
  873. % =\the@toks=) because the old version would still make =@=
  874. % expressions to moving arguments since after expanding the second
  875. % register while looking for the end of the number the contents of the
  876. % token register is added so that later on the whole register will be
  877. % expanded.  This serious bug was found after nearly two years
  878. % international use of this style option by Johannes Braams.
  879. % \end{macro}
  880. % How does the situation look like, if we want to add another column
  881. % to the preamble, i.e.\ if we have found a {\tt c}, {\tt l}, {\tt r},
  882. % {\tt p}, {\tt m} or {\tt b} in the user preamble~?
  883. % In this case we have the problem of the {\sf token} register from
  884. % =>{..}= and =<{..}= having to be inserted at this moment
  885. % because formating instructions like =\hfil= have to be set
  886. % around them. On the other hand it is not known yet, if any
  887. % =<{..}= instruction will appear in the user preamble at all.
  888. % We solve this problem by adding two {\sf token} registers at a time.
  889. % This explains, why we have freed the {\sf token} registers in
  890. % =\prepnext@tok=.
  891. % \begin{macro}{\insert@column}
  892. % \begin{macro}{\@sharp}
  893. %    We now define the macro =\insert@column= which will do
  894. %    this work for us.
  895. %    \begin{macrocode}
  896. \def\insert@column{%
  897. %    \end{macrocode}
  898. %    Here, we assume that the {\sf count} register
  899. %    =\@tempcnta= has saved the value $=\count@= - 1$.
  900. %    \begin{macrocode}
  901.    \the@toks \the \@tempcnta
  902. %    \end{macrocode}
  903. %    Next follows the =#= sign which specifies the place
  904. %    where the text of the column shall be inserted. To avoid
  905. %    errors during the expansions in
  906. %    =\@addtopreamble= we hide this sign in the command
  907. %    =\@sharp= which is temporarily occupied with
  908. %    =\relax= during the build-up of the preamble.
  909. %    To remove unwanted spaces before and after the column text, we set
  910. %    an =\ignorespaces=  in front and a =\unskip= afterwards.
  911. % \changes{v2.0e}{91/02/07}{Added {} around `@sharp for new ftsel}
  912. % \changes{v2.0h}{92/06/22}{Removed {} again in favour of `d@llarbegin}
  913. %    \begin{macrocode}
  914.    \ignorespaces \@sharp \unskip
  915. %    \end{macrocode}
  916. %    Then the second {\sf token} register follows whose number should
  917. %    be saved in =\count@=.
  918. %    We make sure that there will be no further expansion after reading
  919. %    the number, by finishing with =\relax=. The case above is not
  920. %    critical since it is ended by =\ignorespaces=.
  921. % \changes{v2.0c}{90/08/14}{`relax added to avoid problem 
  922. %                           `the`toks0`the`toks1.}
  923. %    \begin{macrocode}
  924.    \the@toks \the \count@ \relax}
  925. %    \end{macrocode}
  926. % \end{macro}
  927. % \end{macro}
  928. % \subsection{The separation of columns}
  929. % \begin{macro}{\@addamp}
  930. %    In the preamble a =&= has to be inserted between any two
  931. %    columns; before the first column there
  932. %    should not be a =&=. As the user preamble may start with a
  933. %    {\tt |} we have to remember somehow if we have already inserted a
  934. %    =#= (i.e.\ a column). This is done with the boolean variable
  935. %    =\if@firstamp= that we test in =\@addamp=,
  936. %    the macro that inserts the =&=.
  937. %    \begin{macrocode}
  938. %    \newif \@iffirstamp
  939. %    \def\@addamp{\if@firstamp \@firstampfalse
  940. %                 \else \@addtopreamble &\fi}
  941. %    \end{macrocode}
  942. % \end{macro}
  943. % \begin{macro}{\@acol}
  944. % \begin{macro}{\@acolampacol}
  945. % \begin{macro}{\col@sep}
  946. %    We will now define some abbreviations for the extensions,
  947. %    appearing most often in the preamble build-up.
  948. %    Here =\col@sep= is a {\sf dimen} register which is set
  949. %    equivalent to =\arraycolsep= in an {\sf array}--environment,
  950. %    otherwise it is set equivalent to =\tabcolsep=.
  951. %    \begin{macrocode}
  952. \newdimen\col@sep
  953. \def\@acol{\@addtopreamble{\hskip\col@sep}}
  954. %    \def\@acolampacol{\@acol\@addamp\@acol}
  955. %    \end{macrocode}
  956. % \end{macro}
  957. % \end{macro}
  958. % \end{macro}
  959. % \subsection{The macro {\tt \protect\bslash @mkpream}}
  960. % \begin{macro}{\@mkpream}
  961. % \begin{macro}{\the@toks}
  962. %    \label{@mkpream}
  963. %    Now we can define the macro which builds up the preamble for the
  964. %    =\halign=.
  965. %    First we initialize =\@preamble=, =\@lastchclass=
  966. %    and the boolean variable =\if@firstamp=.
  967. %    \begin{macrocode}
  968. \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
  969. %    \end{macrocode}
  970. %    During the build-up of the preamble we cannot directly use the
  971. %    =#= sign; this would lead to an error message in the next
  972. %    =\@addtopreamble= call.
  973. %    Instead, we use the command =\@sharp= at places where later
  974. %    a =#= will be.
  975. %    This command is at first given the meaning =\relax=;
  976. %    therefore it will not be expanded when the preamble
  977. %    is extended.
  978. %    In the macro =\@array=, shortly before the =\halign=
  979. %    is carried out, =\@sharp= is given its final meaning.
  980. %    In a similar way,
  981. %    we deal with the commands =\@startpbox= and
  982. %    =\@endpbox=, although the reason is different here: these
  983. %    macros expand in many {\sf tokens} which would delay the
  984. %    build-up of the preamble.
  985. %    \begin{macrocode}
  986.    \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
  987. %    \end{macrocode}
  988. %    Now we remove possible  $*$-forms in the user preamble with the
  989. %    command =\@xexpast=.  As we already know, this command saves
  990. %    its result in the macro =\@tempa=.
  991. %    \begin{macrocode}
  992.    \@xexpast #1*0x\@@
  993. %    \end{macrocode}
  994. %    Afterwards we initialize all registers and macros, that we need
  995. %    for the build-up of the preamble.
  996. %    Since we want to start with the {\sf token} register $0$,
  997. %    =\count@= has to contain the value $-1$.
  998. %    \begin{macrocode}
  999.    \count@\m@ne
  1000.    \let\the@toks\relax
  1001. %    \end{macrocode}
  1002. %    Then we call up =\prepnext@tok= in order to prepare the
  1003. %    {\sf token} register $0$ for use.
  1004. %    \begin{macrocode}
  1005.    \prepnext@tok
  1006. %    \end{macrocode}
  1007. %    To evaluate the user preamble (without stars) saved in
  1008. %    =\@tempa= we use the \LaTeX--macro =\@tfor=.
  1009. %    The strange appearing construction with =\expandafter= is
  1010. %    based on the fact that we have to put the replacement text of
  1011. %    =\@tempa= and not the macro =\@tempa= to this
  1012. %    \LaTeX--macro.
  1013. %    \begin{macrocode}
  1014.    \expandafter \@tfor \expandafter \@nextchar
  1015.     \expandafter :\expandafter =\@tempa \do
  1016. %    \end{macrocode}
  1017. %    The body of this loop (the group after the =\do=)
  1018. %    is executed for one {\sf token} at a time, whereas
  1019. %    the current {\sf token} is saved in =\@nextchar=.
  1020. %    At first we evaluate the current {\sf token} with the already
  1021. %    defined macro =\@testpach=, i.e.\ we assign to
  1022. %    =\@chclass= the character class and to =\@chnum=
  1023. %    the character number of this {\sf token}.
  1024. % \changes{v2.0f}{92/02/29}{`@testpach now without arg}
  1025. %    \begin{macrocode}
  1026.    {\@testpach
  1027. %    \end{macrocode}
  1028. %    Then we branch out depending on the value of =\@chclass= into
  1029. %    different macros that extend the preamble respectively.
  1030. %    \begin{macrocode}
  1031.    \ifcase \@chclass \@classz \or \@classi \or \@classii
  1032.      \or \save@decl \or \or \@classv \or \@classvi
  1033.      \or \@classvii \or \@classviii  \or \@classix
  1034.      \or \@classx \fi
  1035. %    \end{macrocode}
  1036. %    Two cases deserve our special attention:
  1037. %    Since the current {\sf token} cannot have the character class $4$
  1038. %    (start) we have skipped this possibility. If the character class
  1039. %    is $3$, only the content of =\@nextchar= has to be saved into
  1040. %    the current {\sf token} register; therefore we call up
  1041. %    =\save@decl= directly and save a macro name.
  1042. %    After the preamble has been extended we assign the
  1043. %    value of =\@chclass= to the counter =\@lastchclass= to
  1044. %    assure that this information will be available during the next run
  1045. %    of the loop.
  1046. %    \begin{macrocode}
  1047.    \@lastchclass\@chclass}%
  1048. %    \end{macrocode}
  1049. %    After the loop has been finished space must still be added to
  1050. %    the created preamble, depending on the last {\sf token}.
  1051. %    Depending on the value of =\@lastchclass= we perform
  1052. %    the necessary operations.
  1053. %    \begin{macrocode}
  1054.    \ifcase\@lastchclass
  1055. %    \end{macrocode}
  1056. %    If the last class equals $0$ we add a
  1057. %    =\hskip \col@sep=.
  1058. %    \begin{macrocode}
  1059.    \@acol \or
  1060. %    \end{macrocode}
  1061. %    If it equals $1$ we do not add any additional space so that the
  1062. %    horizontal lines do not exceed the vertical ones.
  1063. %    \begin{macrocode}
  1064.    \or
  1065. %    \end{macrocode}
  1066. %    Class $2$ is treated like class $0$ because a =<{...}=  can
  1067. %    only directly follow after class $0$.
  1068. %    \begin{macrocode}
  1069.    \@acol \or
  1070. %    \end{macrocode}
  1071. %    Most of the other possibilities can only appear if the user
  1072. %    preamble was defective. Class $3$ is not allowed since after
  1073. %    a =>{..}= there must always follow a {\tt c}, {\tt l},
  1074. %    { {\tt r}, {\tt p},\tt m} or  {\tt b}. We report an error
  1075. %    and ignore the declaration given by ={..}=.
  1076. %    \begin{macrocode}
  1077.    \@preamerr \thr@@ \or
  1078. %    \end{macrocode}
  1079. %    If =\@lastchclass= is $4$ the user preamble has been empty.
  1080. %    To continue, we insert a =#= in the preamble.
  1081. %    \begin{macrocode}
  1082.    \@preamerr \tw@ \@addtopreamble\@sharp \or
  1083. %    \end{macrocode}
  1084. %    Class $5$ is allowed again. In this case
  1085. %    (the user preamble ends with =@{..}=) we need not
  1086. %    do anything.
  1087. %    \begin{macrocode}
  1088.    \or
  1089. %    \end{macrocode}
  1090. %    Any other case means that the arguments to
  1091. %    =@=, {\tt !}, {\tt <}, {\tt >}, {\tt p}, {\tt m} or {\tt b}
  1092. %    have been forgotten. So we report an error and ignore the last
  1093. %    {\sf token}.
  1094. %    \begin{macrocode}
  1095.    \else  \@preamerr \@ne \fi
  1096. %    \end{macrocode}
  1097. %    Now that the build-up of the preamble is almost finished we can
  1098. %    insert the {\sf token} registers and therefore redefine
  1099. %    =\the@toks=. The actual insertion, though, is performed
  1100. %    later.
  1101. %    \begin{macrocode}
  1102.    \def\the@toks{\the\toks}}
  1103. %    \end{macrocode}
  1104. % \end{macro}
  1105. % \end{macro}
  1106. %  \section{The macros {\tt \protect
  1107. %       \bslash @classz} to {\tt \protect\bslash @classx}}
  1108. % The preamble is extended by the macros =\@classz= to
  1109. % =\@classx= which are called by =\@mkpream=
  1110. %  depending on =\@lastchclass=
  1111. % (i.e. the character class of the last {\sf token}).
  1112. % \begin{macro}{\@classx}
  1113. %    First we define =\@classx= because of its important r\^ole.
  1114. %    When it is called we find that the current
  1115. %    {\sf token} is {\tt p}, {\tt m} or {\tt b}.
  1116. %    That means that a new column has to start.
  1117. %    \begin{macrocode}
  1118. \def\@classx{%
  1119. %    \end{macrocode}
  1120. %    Depending on the value of =\@lastchclass= different actions
  1121. %    must take place:
  1122. %    \begin{macrocode}
  1123.   \ifcase \@lastchclass
  1124. %    \end{macrocode}
  1125. %    If the last character class was $0$ we separate the columns by
  1126. %    =\hskip\col@sep= followed by =&= and another
  1127. %    =\hskip\col@sep=.
  1128. %    \begin{macrocode}
  1129.   \@acolampacol \or
  1130. %    \end{macrocode}
  1131. %    If the last class was class $1$ --- that means that a vertical
  1132. %    line was
  1133. %    drawn, --- before this line a =\hskip\col@sep= was inserted.
  1134. %    Therefore there has to be only a =&= followed by
  1135. %    =\hskip\col@sep=. But this =&= may be inserted only
  1136. %    if this is not the first column. This process is controlled
  1137. %    by =\if@firstamp= in the macro =\addamp=.
  1138. %    \begin{macrocode}
  1139.   \@addamp \@acol \or
  1140. %    \end{macrocode}
  1141. %    Class $2$ is treated like class $0$ because =<{...}= can only
  1142. %    follow after class $0$.
  1143. %    \begin{macrocode}
  1144.   \@acolampacol \or
  1145. %    \end{macrocode}
  1146. %    Class $3$ requires no actions because all things necessary have
  1147. %    been done by the preamble {\sf token} {\tt >}.
  1148. %    \begin{macrocode}
  1149.   \or
  1150. %    \end{macrocode}
  1151. %    Class $4$ means that we are at the beginning of the preamble.
  1152. %    Therefore we start the preamble with =\hskip\col@sep= and
  1153. %    then call =\@firstampfalse=. This makes sure that a later
  1154. %    =\@addamp= inserts the character
  1155. %    =&= into the preamble.
  1156. %    \begin{macrocode}
  1157.   \@acol \@firstampfalse \or
  1158. %    \end{macrocode}
  1159. %    For class $5$ {\sf tokens} only the character =&= is inserted
  1160. %    as a column separator. Therefore we call =\@addamp=.
  1161. %    \begin{macrocode}
  1162.   \@addamp
  1163. %    \end{macrocode}
  1164. %    Other cases are impossible. For an example
  1165. %    $=\@lastchclass= \string= 6$---as it might appear in a
  1166. %    preamble of the form =...!p...=---{\tt p} would have
  1167. %    been taken as an  argument of {\tt !}\ by =\@testpach=.
  1168. %    \begin{macrocode}
  1169.   \fi}
  1170. %    \end{macrocode}
  1171. % \end{macro}
  1172. % \begin{macro}{\@classz}
  1173. %    If the character class of the last {\sf token} is $0$
  1174. %    we have {\tt c}, {\tt l}, {\tt r} or an argument of {\tt m},
  1175. %    {\tt b} or\ {\tt p}. In the first three cases the preamble must be
  1176. %    extended the same way as if we had class $10$. The remaining two
  1177. %    cases do not require any action because the space needed was
  1178. %    generated by the last {\sf token} (i.e.\ {\tt m}, {\tt b} or
  1179. %    {\tt p}). Since =\@lastchclass= has the value $10$ at
  1180. %    this point nothing happens when =\@classx= is called. So the
  1181. %    macro =\@chlassz= may start like this:
  1182. %    \begin{macrocode}
  1183. \def\@classz{\@classx
  1184. %    \end{macrocode}
  1185. %    According to the definition of =\insert@column= we must store
  1186. %    the number of the {\sf token} register in which a preceding
  1187. %    =>{..}= might have stored its argument into
  1188. %    =\@tempcnta=.
  1189. %    \begin{macrocode}
  1190.    \@tempcnta \count@
  1191. %    \end{macrocode}
  1192. %    To have $=\count@= \string= =\@tmpcnta= + 1$ we prepare
  1193. %    the next {\sf token} register.
  1194. %    \begin{macrocode}
  1195.    \prepnext@tok
  1196. %    \end{macrocode}
  1197. %    Now the preamble must be extended with the column whose format
  1198. %    can be determinated by =\@chnum=.
  1199. %    \begin{macrocode}
  1200.    \@addtopreamble{\ifcase \@chnum
  1201. %    \end{macrocode}
  1202. %    If =\@chnum= has the value $0$ a centered column has to be
  1203. %    generated.
  1204. %    So we begin with stretchable space.
  1205. %    \begin{macrocode}
  1206.       \hfil
  1207. %    \end{macrocode}
  1208. %    The command =\d@llarbegin= follows expanding into =\begingroup=
  1209. %    (in the {\sf tabular}--environment) or into =$=.  Doing this
  1210. %    (provided an appropriate setting of =\d@llarbegin=) we achieve
  1211. %    that the contents of the columns of an {\sf array}--environment
  1212. %    are set in math mode while those of a {\sf tabular}--environment
  1213. %    are set in LR mode.
  1214. %    \begin{macrocode}
  1215.       \d@llarbegin
  1216. %    \end{macrocode}
  1217. %    Now we insert the contents of the two {\sf token} registers
  1218. %    and the symbol
  1219. %    for the column entry (i.e.\ =#= or
  1220. %    more precise =\@sharp=) using =\insert@column=.
  1221. %    \begin{macrocode}
  1222.       \insert@column
  1223. %    \end{macrocode}
  1224. %    We end this case with =\d@llarend= and =\hfil= where =\d@llarend=
  1225. %    again is either =$= or =\endgroup=.
  1226. %    \begin{macrocode}
  1227.       \d@llarend \hfil \or
  1228. %    \end{macrocode}
  1229. %    The templates for {\tt l} and {\tt r} (i.e.\ =\@chnum= $1$
  1230. %    or $2$) are generated the same way. Since one  =\hfil= is
  1231. %    missing the text is moved to the relevant side.
  1232. %    The =\kern\z@= is needed in case of an empty column
  1233. %    entry. Otherwise
  1234. %    the =\unskip= in =\insert@column= removes the
  1235. %    =\hfil=.
  1236. %    \begin{macrocode}
  1237.       \d@llarbegin \insert@column \d@llarend \hfil \or
  1238.       \hfil\kern\z@ \d@llarbegin \insert@column \d@llarend \or
  1239. %    \end{macrocode}
  1240. %    The templates for {\tt p}, {\tt m} and {\tt b} mainly consist
  1241. %    of a {\sf box}. In case of {\tt m} it is generated by
  1242. %    =\vcenter=.
  1243. %    This command is allowed only in math mode. Therefore we start with
  1244. %    a~=$=.
  1245. %    \begin{macrocode}
  1246.    $\vcenter
  1247. %    \end{macrocode}
  1248. %    The part of the templates which is the same in all three cases
  1249. %    ({\tt p}, {\tt m} and {\tt b})
  1250. %    is built by the macros =\@startpbox= and
  1251. %    =\@endpbox=. =\@startpbox= has an argument:
  1252. %    the width of the column which is stored in the current
  1253. %    {\sf token} (i.e.\ =\@nextchar=).
  1254. %    Between these two macros we find the well known
  1255. %    =\insert@column=.
  1256. %    \begin{macrocode}
  1257.    \@startpbox{\@nextchar}\insert@column \@endpbox $\or
  1258. %    \end{macrocode}
  1259. %    The templates for {\tt p} and {\tt b} are generated in the same
  1260. %    way though we do not need the
  1261. %    =$= characters because we use =\vtop=
  1262. %    or =\vbox=.
  1263. %    \begin{macrocode}
  1264.    \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
  1265.    \vbox \@startpbox{\@nextchar}\insert@column \@endpbox
  1266. %    \end{macrocode}
  1267. %    Other values for =\@chnum= are impossible. Therefore we
  1268. %    end the arguments to =\@addtopreamble= and =\ifcase=.
  1269. %    Before we come to the end of =\@classz= we have to
  1270. %    prepare the next {\sf token} register.
  1271. %    \begin{macrocode}
  1272.   \fi}\prepnext@tok}
  1273. %    \end{macrocode}
  1274. % \end{macro}
  1275. % \begin{macro}{\@classix}
  1276. %    In case of class $9$ ({\tt >}--{\sf token}) we first check
  1277. %    if the character class of the last
  1278. %    {\sf token} was $3$. In this case we have a
  1279. %    user preamble of the form =..>{...}>{...}..= which
  1280. %    is not allowed. We only give an error message and continue.
  1281. %    So the declarations defined by the first  =>{...}=
  1282. %    are ignored.
  1283. %    \begin{macrocode}
  1284. \def\@classix{\ifnum \@lastchclass = \thr@@
  1285.        \@preamerr \thr@@ \fi
  1286. %    \end{macrocode}
  1287. %    Furthermore, we call up =\@class10=
  1288. %    because afterwards always a new column is started by
  1289. %    {\tt c}, {\tt l}, {\tt r}, {\tt p}, {\tt m} or {\tt b}.
  1290. %    \begin{macrocode}
  1291.        \@classx}
  1292. %    \end{macrocode}
  1293. % \end{macro}
  1294. % \begin{macro}{\@classviii}
  1295. %    If the current {\sf token} is a {\tt <} the last
  1296. %    character class must be $0$. In this case it is not necessary to
  1297. %    extend the preamble. Otherwise we output an error message, set
  1298. %    =\@chclass= to $6$ and call =\@classvi=.
  1299. %    By doing this we achieve that {\tt <} is treated like {\tt !}.
  1300. %    \begin{macrocode}
  1301. \def\@classviii{\ifnum \@lastchclass >\z@
  1302.       \@preamerr 4\@chclass 6 \@classvi \fi}
  1303. %    \end{macrocode}
  1304. % \end{macro}
  1305. % \begin{macro}{\@arrayrule}
  1306. %    There is only one incompatibility with the original definition:
  1307. %    the definition of =\@arrayrule=. In the original a line
  1308. %    without width\footnote{So the space between {\tt cc} and {\tt c|c}
  1309. %                                  is equal.}
  1310. %    is created by multiple insertions of =\hskip .5\arrayrulewidth=.
  1311. %    We only insert a vertical line into the preamble.
  1312. %    This is done to prevent problems with \TeX's main
  1313. %    memory when generating
  1314. %    tables with many vertical lines in them (especially in the case of
  1315. %    {\sf floats}).
  1316. %    \begin{macrocode}
  1317. \def\@arrayrule{\@addtopreamble \vline}
  1318. %    \end{macrocode}
  1319. % \end{macro}
  1320. % \begin{macro}{\@classvii}
  1321. %    As a consequence it follows that in case of class $7$
  1322. %    (=@= {\sf token})  the preamble need not to be extended.
  1323. %    In the original definition $=\@lastchclass= \string= 1$
  1324. %    is treated by inserting =\hskip .5\arrayrulewidth=.
  1325. %    We only check if the last {\sf token} was of class $3$ which is
  1326. %    forbidden.
  1327. %    \begin{macrocode}
  1328. \def\@classvii{\ifnum \@lastchclass = \thr@@
  1329. %    \end{macrocode}
  1330. %    If this is true we output an error message and
  1331. %    ignore the declarations stored
  1332. %    by the last  =>{...}=, because these are overwritten
  1333. %    by the argument of {\tt @}.
  1334. %    \begin{macrocode}
  1335.    \@preamerr \thr@@ \fi}
  1336. %    \end{macrocode}
  1337. % \end{macro}
  1338. % \begin{macro}{\@classvi}
  1339. %    If the current {\sf token} is a regular {\tt !}\ and the last
  1340. %    class
  1341. %    was $0$ or $2$ we extend the preamble with =\hskip \col@sep=.
  1342. %    If the last {\sf token} was of class $1$ (for instance {\tt |})
  1343. %    we extend with =\hskip \doublerulesep= because the
  1344. %    construction =!{...}= has to be treated like {\tt |}.
  1345. %    \begin{macrocode}
  1346. \def\@classvi{\ifcase \@lastchclass
  1347.       \@acol \or
  1348.       \@addtopreamble{\hskip \doublerulesep}\or
  1349.       \@acol \or
  1350. %    \end{macrocode}
  1351. %    Now =\@preamerr...= should follow because a
  1352. %    user preamble of the form =..>{..}!..= is not allowed.
  1353. %    To save memory we call =\@classvii= instead which also
  1354. %    does what we want.
  1355. %    \begin{macrocode}
  1356.       \@classvii
  1357. %    \end{macrocode}
  1358. %    If =\@lastchclass= is $4$ or $5$ nothing has to be done.
  1359. %    Class $6$ to $10$ are not possible.
  1360. %    So we finish the macro.
  1361. %    \begin{macrocode}
  1362.       \fi}
  1363. %    \end{macrocode}
  1364. % \end{macro}
  1365. % \begin{macro}{\@classii}
  1366. % \begin{macro}{\@classiii}
  1367. %    In the case of character classes $2$ and $3$ (i.e.\ the argument
  1368. %    of {\tt <} or {\tt >}) we only have to store the current
  1369. %    {\sf token} (=\@nextchar=) into the corresponding
  1370. %    {\sf token} register since the preparation and
  1371. %    insertion of these registers
  1372. %    are done by the macro =\@classz=.
  1373. %    This is equivalent to calling =\save@decl= in the case of
  1374. %    class $3$. To save command identifiers we do this call up
  1375. %     in the macro =\@mkpream=.
  1376. %    Class $2$ exhibits a more complicated situation: the
  1377. %    {\sf token} registers have already been inserted by
  1378. %    =\@classz=. So the value of =\count@= is too high
  1379. %    by one. Therefore we decrease =\count@= by $1$.
  1380. %    \begin{macrocode}
  1381. \def\@classii{\advance \count@ \m@ne
  1382. %    \end{macrocode}
  1383. %    Next we store the current {\sf token} into the correct 
  1384. %    {\sf token} register by calling =\save@decl= and then
  1385. %    increase the value of =\count@= again. At this point we
  1386. %    can save memory once more (at the cost of time) if we use the
  1387. %     macro =\prepnext@tok=.
  1388. %    \begin{macrocode}
  1389.    \save@decl\prepnext@tok}
  1390. %    \end{macrocode}
  1391. % \end{macro}
  1392. % \end{macro}
  1393. % \begin{macro}{\@classv}
  1394. %    If the current {\sf token} is of class $5$ then it is an argument
  1395. %    of a {\tt @} {\sf token}. It must be stored into a
  1396. %    {\sf token} register.
  1397. %    \begin{macrocode}
  1398. \def\@classv{\save@decl
  1399. %    \end{macrocode}
  1400. %    We extend the preamble with a command which inserts this
  1401. %    {\sf token} register into the preamble when its construction is
  1402. %    finished. The user expects that this argument is worked out in
  1403. %    math mode if it was used in an {\sf array}--environment. Therefore
  1404. %    we surround it with =\d@llar...='s.
  1405. % \changes{v2.0c}{90/08/14}{`relax added to avoid problem 
  1406. %                           `the`toks0`the`toks1.}
  1407. %    \begin{macrocode}
  1408.    \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
  1409. %    \end{macrocode}
  1410. %    Finally we must prepare the next {\sf token} register.
  1411. %    \begin{macrocode}
  1412.    \prepnext@tok}
  1413. %    \end{macrocode}
  1414. % \end{macro}
  1415. % \begin{macro}{\@classi}
  1416. %    In the case of class $0$ we were able to generate the necessary
  1417. %    space between columns by using the macro =\@classx=.
  1418. %    Analogously the macro =\@classvi= can be used for class $1$.
  1419. %    \begin{macrocode}
  1420. \def\@classi{\@classvi
  1421. %    \end{macrocode}
  1422. %    Depending on =\@chnum= a vertical line
  1423. %    \begin{macrocode}
  1424.    \ifcase \@chnum \@arrayrule \or
  1425. %    \end{macrocode}
  1426. %    or (in case of =!{...}=) the current {\sf token} --- stored
  1427. %    in =\@nextchar= --- has to be inserted into the preamble.
  1428. %    This corresponds to calling =\@classv=.
  1429. %    \begin{macrocode}
  1430.       \@classv \fi}
  1431. %    \end{macrocode}
  1432. % \end{macro}
  1433. % \begin{macro}{\@startpbox}
  1434. %    In =\@classz=  the macro =\@startpbox= is used.
  1435. %    The width of the {\sf parbox} is passed as an argument.
  1436. %    =\vcenter=, =\vtop= or =\vbox= are already in the
  1437. %    preamble. So we start with the braces for the wanted box.
  1438. %    \begin{macrocode}
  1439. \def\@startpbox#1{\bgroup
  1440. %    \end{macrocode}
  1441. %    The argument is the width of the box. This information has to be
  1442. %    assigned to =\hsize=.
  1443. %    Then we assain default values to several parameters used in a
  1444. %    {\sf parbox}.
  1445. %    \begin{macrocode}
  1446.   \hsize #1 \@arrayparboxrestore
  1447. %    \end{macrocode}
  1448. %    Our main problem is to obtain the same distance between succeeding
  1449. %    lines of the {\sf parbox}.
  1450. %    We have to remember that the distance between two {\sf parboxes}
  1451. %    should be defined by =\@arstrut=. That means that it can be
  1452. %    greater than the distance in a {\sf parbox}.
  1453. %    Therefore it is not enough to set a =\@arstrut= at the
  1454. %    beginning and at the end of the {\sf parbox}. This would
  1455. %    dimension the distance
  1456. %    between first and second line and the distance between the two
  1457. %    last lines of the {\sf parbox} wrongly.
  1458. %    To prevent this we set an invisible rule of height
  1459. %    =\@arstrutbox=
  1460. %    at the beginning of the {\sf parbox}. This has no effect on the
  1461. %    depth of the first line. At the end of the {\sf parbox} we set
  1462. %    analogously another invisible rule which only affects the depth
  1463. %    of the last line.
  1464. %    \begin{macrocode}
  1465.    \vrule \@height \ht\@arstrutbox \@width \z@}
  1466. %    \end{macrocode}
  1467. % \end{macro}
  1468. % \begin{macro}{\@endpbox}
  1469. %    If there are any declarations defined by =>{...}=
  1470. %    and =<{...}=
  1471. %    they now follow in the macro =\@classz= --- the contents
  1472. %    of the column in between.
  1473. %    So the macro =\@endpbox= must insert the {\sf specialstrut}
  1474. %    mentioned earlier and then close the group opened by
  1475. %    =\@startpbox=.
  1476. %    \begin{macrocode}
  1477. \def\@endpbox{\vrule \@width \z@ \@depth \dp \@arstrutbox \egroup}
  1478. %    \end{macrocode}
  1479. % \end{macro}
  1480. % \section{Building and calling {\tt \protect\bslash halign}}
  1481. % \begin{macro}{\@array}
  1482. %    After we have discussed the macros needed for the evaluation
  1483. %    of the user preamble we can define the macro =\@array=
  1484. %    which uses these macros to create a =\halign=.
  1485. %    It has two arguments. The first one is a position argument
  1486. %    which can be {\tt t}, {\tt b} or {\tt c}; the
  1487. %    second one describes the wanted preamble,
  1488. %    e.g.\ it has the form =|c|c|c|=.
  1489. %    \begin{macrocode}
  1490. \def\@array[#1]#2{%
  1491. %    \end{macrocode}
  1492. %    First we define a {\sf strut} whose size basically corresponds
  1493. %     to a normal {\sf strut} multiplied by the factor
  1494. %    =\arraystretch=.
  1495. %    This {\sf strut} is then  inserted into every row and enforces
  1496. %     a minimal distance between two rows.
  1497. %    Nevertheless, when using horizontal lines, large letters
  1498. %    (like accented capital letters) still collide with such lines.
  1499. %    Therefore at first we add to the height of a normal {\sf strut}
  1500. %    the value of the parameter =\extrarowheight=.
  1501. %    \begin{macrocode}
  1502.   \@tempdima \ht \strutbox
  1503.   \advance \@tempdima by\extrarowheight
  1504.   \setbox \@arstrutbox \hbox{\vrule
  1505.              \@height \arraystretch \@tempdima
  1506.              \@depth \arraystretch \dp \strutbox
  1507.              \@width \z@}%
  1508. %    \end{macrocode}
  1509. %    Then we open a group, in which the user preamble is evaluated by
  1510. %    the macro =\@mkpream=. As we know this must happen locally.
  1511. %    This macro creates a preamble for a =\halign= and saves
  1512. %    its result globally in the control sequence =\@preamble=.
  1513. %    \begin{macrocode}
  1514.   \begingroup
  1515.   \@mkpream{#2}%
  1516. %    \end{macrocode}
  1517. %    We again redefine =\@preamble= so that a call up of
  1518. %    =\@preamble= now starts the =\halign=. Thus also the
  1519. %    arguments of {\tt >}, {\tt <}, {\tt @} and {\tt !}, saved in the
  1520. %    {\sf token} registers are inserted into the preamble.
  1521. %    The =\tabskip= at the beginning and end of the preamble
  1522. %    is set to {\sf 0pt} (in the beginning by the use of
  1523. %    =\ialign=). Also the command =\@arstrut= is build in,
  1524. %    which inserts the =\@arstrutbox=, defined above. Of course,
  1525. %    the opening brace after =\ialign= has to be implicit as it
  1526. %    will be closed in =\endarray= or another macro.
  1527. %    \begin{macrocode}
  1528.   \xdef\@preamble{\ialign \@halignto
  1529.                   \bgroup \@arstrut \@preamble
  1530.                           \tabskip \z@ \cr}%
  1531. %    \end{macrocode}
  1532. %    What we have not explained yet is the macro =\@halignto=
  1533. %    that was just used. Depending on its replacement text the
  1534. %    =\halign= becomes a =\halign= {\tt to} \meta{dimen}.
  1535. %    Now we close the group again. Thus
  1536. %    =\@startpbox= and =\@endpbox= as well as all
  1537. %    {\sf token} registers get their former meaning back.
  1538. %    \begin{macrocode}
  1539.   \endgroup
  1540. %    \end{macrocode}
  1541. %     To support the {\tt delarray.sty} style option we include a hook
  1542. %     into this part of the code which is a no-op in the main style.
  1543. % \changes{v2.1a}{92/07/03}{Hook for delarray added}
  1544. %    \begin{macrocode}
  1545.   \@arrayleft
  1546. %    \end{macrocode}
  1547. %    Now we decide depending on the position argument in which {\sf
  1548. %    box} the =\halign= is to be put. (=\vcenter= may be used
  1549. %    because we are in math mode.)
  1550. % \changes{v2.1a}{92/07/03}{Wrong spec is now equiv to [t]}
  1551. %    \begin{macrocode}
  1552.   \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
  1553. %    \end{macrocode}
  1554. %    Now another implicit opening brace appears; then definitions
  1555. %    which shall stay local follow. While constructing the
  1556. %    =\@preamble= in =\@mkpream= the =#= sign must be
  1557. %    hidden in the macro =\@sharp= which is =\let= to
  1558. %    =\relax= at that moment (see definition of =\@mkpream=
  1559. %    on page~\pageref{@mkpream}).
  1560. %    All these now get their actual meaning.
  1561. %    \begin{macrocode}
  1562.   \bgroup
  1563.   \let \@sharp ##\let \protect \relax
  1564. %    \end{macrocode}
  1565. %    With the above defined {\sf struts} we fix down the distance
  1566. %    between rows by setting =\lineskip= and =\baselineskip=
  1567. %    to {\sf 0pt}. Since there have to be set =$='s
  1568. %    around every column in the {\sf array}--environment
  1569. %     the parameter =\mathsurround= should
  1570. %    also be set to {\sf 0pt}. This prevents additional space between
  1571. %    the rows. The
  1572. %    \PlainTeX--macro =\m@th= does this.
  1573. %    \begin{macrocode}
  1574.   \lineskip \z@
  1575.   \baselineskip \z@
  1576.   \m@th
  1577. %    \end{macrocode}
  1578. %    Beside, we have to assign a special meaning (which we still have
  1579. %    to specify) to the line separator =\\=. We also have to
  1580. %    redefine the command =\par= in such a way that empty lines in
  1581. %    =\halign= cannot do any damage. We succeed in doing  so
  1582. %    by choosing something that will disappear when expanding.
  1583. %    After that we only have to call up =\@preamble= to
  1584. %    start the wanted =\halign=.
  1585. %    \begin{macrocode}
  1586.   \let\\ \@arraycr  \let\par\@empty \@preamble}
  1587. %    \end{macrocode}
  1588. % \end{macro}
  1589. % \begin{macro}{\extrarowheight}
  1590. %    The {\sf dimen} parameter used above also needs to be allocated.
  1591. %    As a default value we use {\sf 0pt}, to ensure compatibility with
  1592. %    standard \LaTeX.
  1593. %    \begin{macrocode}
  1594. \newdimen \extrarowheight
  1595. \extrarowheight=0pt
  1596. %    \end{macrocode}
  1597. % \end{macro}
  1598. % \begin{macro}{\@arstrut}
  1599. %    Now the insertion of =\@arstrutbox= through =\@arstut=
  1600. %    is easy since we know exactly in which mode \TeX\ is while working
  1601. %    on the =\halign= preamble.
  1602. %    \begin{macrocode}
  1603. \def\@arstrut{\unhcopy\@arstrutbox}
  1604. %    \end{macrocode}
  1605. % \end{macro}
  1606. % \section{The line separator {\tt\protect\bslash\protect\bslash}}
  1607. % \begin{macro}{\@arraycr}
  1608. %    In the macro =\@array= the line separator =\\= is
  1609. %    =\let= to the command =\@arraycr=.
  1610. %    Its definition starts with a special brace which I have directly
  1611. %    copied from the original definition. It is
  1612. %    necessary, because the =\futurlet= in =\@ifnextchar=
  1613. %    might
  1614. %    expand a  following =&= {\sf token} in a construction like
  1615. %    =\\ &=. This would otherwise end the alignment template at a
  1616. %    wrong time. For further information see
  1617. %    \cite[Appendix D]{bk:knuth}.
  1618. %    \begin{macrocode}
  1619. \def\@arraycr{{\ifnum 0=`}\fi
  1620. %    \end{macrocode}
  1621. %    Then we test whether the user is using the star form and ignore
  1622. %    a possible star (I also disagree with this procedure, because a
  1623. %    star does not make any sense here).
  1624. %    \begin{macrocode}
  1625.   \@ifstar \@xarraycr \@xarraycr}
  1626. %    \end{macrocode}
  1627. % \end{macro}
  1628. % \begin{macro}{\@xarraycr}
  1629. %    In the command =\@xarraycr= we test if an optional argument
  1630. %    exists.
  1631. %    \begin{macrocode}
  1632. \def\@xarraycr{\@ifnextchar [%
  1633. %    \end{macrocode}
  1634. %    If it does, we branch out into the macro =\@argarraycr= if
  1635. %    not we close the special brace (mentioned above) and end the row
  1636. %    of the =\halign= with a =\cr=.
  1637. %    \begin{macrocode}
  1638.   \@argarraycr {\ifnum 0=`{\fi}\cr}}
  1639. %    \end{macrocode}
  1640. % \end{macro}
  1641. % \begin{macro}{\@argarraycr}
  1642. %    If additional space is requested by the user this case is treated
  1643. %    in the macro =\@argarraycr=. First we close the special brace
  1644. %    and then we test if the additional space is positive.
  1645. %    \begin{macrocode}
  1646. \def\@argarraycr[#1]{\ifnum0=`{\fi}\ifdim #1>\z@
  1647. %    \end{macrocode}
  1648. %    If this is the case we create an invisible vertical rule with a
  1649. %    depth of $=\dp\@arstutbox=  + \left\langle
  1650. %                                         \it wanted\ space
  1651. %                                       \right\rangle  $.
  1652. %    Thus we achieve that all vertical lines specified
  1653. %    in the user preamble by a {\tt |} are now
  1654. %    generally drawn.
  1655. %    Then the row ends with a =\cr=.
  1656. %    If the space is negative we end the row at once with a =\cr=
  1657. %    and move back up with a =\vskip=.
  1658. %    While testing these macros I found out that the
  1659. %    =\endtemplate=
  1660. %    created by =\cr= and =&= is something like an
  1661. %    =\outer= primitive and therefore it should not appear in
  1662. %    incomplete =\if= statements. Thus the following solution was
  1663. %    chosen which hides the =\cr= in other macros when \TeX\
  1664. %    is skipping conditional text.
  1665. %    \begin{macrocode}
  1666.   \@xargarraycr{#1}\else \@yargarraycr{#1}\fi}
  1667. %    \end{macrocode}
  1668. % \end{macro}
  1669. % \begin{macro}{\@xargarraycr}
  1670. % \begin{macro}{\@yargarraycr}
  1671. %    The following macros were already explained above.
  1672. %    \begin{macrocode}
  1673. \def\@xargarraycr#1{\unskip
  1674.   \@tempdima #1\advance\@tempdima \dp\@arstrutbox
  1675.   \vrule \@depth\@tempdima \@width\z@ \cr}
  1676. \def\@yargarraycr#1{\cr\noalign{\vskip #1}}
  1677. %    \end{macrocode}
  1678. % \end{macro}
  1679. % \end{macro}
  1680. % \section{Spanning several columns}
  1681. % \begin{macro}{\multicolumn}
  1682. %    If several columns should be held together with a special format
  1683. %    the command =\multicolumn= must be used. It has three
  1684. %    arguments: the number of columns to be covered; the format for
  1685. %    the result column and the actual column entry.
  1686. %    \begin{macrocode}
  1687. \def\multicolumn#1#2#3{%
  1688. %    \end{macrocode}
  1689. %    First we combine the given number of columns into a single one;
  1690. %    then we start a new block so that the following definition is kept
  1691. %    local.
  1692. %    \begin{macrocode}
  1693.    \multispan{#1}\begingroup
  1694. %    \end{macrocode}
  1695. %    Since a =\multicolumn= should only describe the format of a
  1696. %    result column, we redefine =\@addamp= in such a way that one
  1697. %    gets an error message if one uses more than one
  1698. %    {\tt c}, {\tt l}, {\tt r}, {\tt p}, {\tt m} or {\tt b} in the
  1699. %    second argument. One should consider that this definition is local
  1700. %    to the build-up of the preamble; an {\sf array}-- or
  1701. %    {\sf tabular}--environment in the third argument of the
  1702. %    =\multicolumn= is therefore worked through correctly as well.
  1703. %    \begin{macrocode}
  1704.    \def\@addamp{\if@firstamp \@firstampfalse \else
  1705.                 \@preamerr 5\fi}%
  1706. %    \end{macrocode}
  1707. %    Then we evaluate the second argument with the help of
  1708. %    =\@mkpream=.
  1709. %    Now we still have to insert the contents of the {\sf token}
  1710. %    register into the =\@preamble=, i.e.\ we have to say
  1711. %    =\xdef\@preamble{\@preamble}=. This is achieved shorter by
  1712. %    writing:
  1713. %    \begin{macrocode}
  1714.    \@mkpream{#2}\@addtopreamble\@empty
  1715. %    \end{macrocode}
  1716. %    After the =\@preamble= is created we forget all local
  1717. %    definitions and occupations of the {\sf token} registers.
  1718. %    \begin{macrocode}
  1719.    \endgroup
  1720. %    \end{macrocode}
  1721. %    In the special situation of  =\multicolumn= =\@preamble=
  1722. %    is not needed as preamble for a =\halign= but it is directly
  1723. %    inserted into our table. Thus instead of =\sharp=
  1724. %    there has to be the column entry (=#3=) wanted by the user.
  1725. %    \begin{macrocode}
  1726.    \def\@sharp{#3}%
  1727. %    \end{macrocode}
  1728. %    Now we can pass the =\@preamble= to \TeX\ . For safety
  1729. %    we start with an =\@arstrut=. This should usually be in the
  1730. %    template for the first column however we do not know if this
  1731. %    template was overwritten by our =\multicolumn=.
  1732. %    \begin{macrocode}
  1733.    \@arstrut \@preamble \ignorespaces}
  1734. %    \end{macrocode}
  1735. % \end{macro}
  1736. %   \section{The Environment Definitions}
  1737. % After these preparations we are able to define the environments. They
  1738. % only differ in the initialisations of =\d@llar...=, =\col@sep=
  1739. %  and =\@halignto=.
  1740. % \begin{macro}{\@halignto}
  1741. % \begin{macro}{\d@llarbegin}
  1742. % \begin{macro}{\d@llarend}
  1743. %    In order to relieve the {\sf save stack} we assign the replacement
  1744. %    texts for =\@halignto= globally. =\d@llar= has to be local
  1745. %    since otherwise nested {\sf tabular} and {\sf array} environments 
  1746. %    (via =\multicolumn=) are impossible.
  1747. % \changes{v2.0g}{92/06/18}{`d@llarbegin defined on toplevel.}
  1748. %    When the new font selection scheme is in force we have to 
  1749. %    we surround all =\halign= entries 
  1750. %    with braces. See remarks in TUGboat 10\#2. Actually we are going
  1751. %    to use =\begingroup= and =\endgroup=. However, this is only
  1752. %    necessary when we are in text mode. In math the surrounding
  1753. %    dollar signs will already serve as the necessary extra grouping
  1754. %    level. Therefore we switch the settings of =\d@llarbegin= and
  1755. %    =\d@llarend= between groups and dollar signs.
  1756. %    \begin{macrocode}
  1757. \let\d@llarbegin\begingroup
  1758. \let\d@llarend\endgroup
  1759. %    \end{macrocode}
  1760. % \end{macro}
  1761. % \end{macro}
  1762. % \end{macro}
  1763. % \begin{macro}{\array}
  1764. %    Our new definition of =\array= then reads:
  1765. % \changes{v2.0d}{90/08/20}{`d@llar local to preamble.}
  1766. %    \begin{macrocode}
  1767. \def\array{\col@sep\arraycolsep
  1768.   \def\d@llarbegin{$}\let\d@llarend\d@llarbegin\gdef\@halignto{}%
  1769. %    \end{macrocode}
  1770. %    Since there might be an optional argument we call another
  1771. %    macro which is also used by the other environments.
  1772. %    \begin{macrocode}
  1773.   \@tabarray}
  1774. %    \end{macrocode}
  1775. % \end{macro}
  1776. % \begin{macro}{\@tabarray}
  1777. %    This macro tests for a optional bracket and then calls up
  1778. %    =\@array= or =\@array[c]= (as default).
  1779. %    \begin{macrocode}
  1780. \def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}}
  1781. %    \end{macrocode}
  1782. % \end{macro}
  1783. % \begin{macro}{\tabular}
  1784. % \begin{macro}{\tabular*}
  1785. %    The environments {\sf tabular} and {\sf tabular$*$} differ
  1786. %    only in the initialisation of =\@halignto=. Therefore
  1787. %    we define
  1788. %    \begin{macrocode}
  1789. \def\tabular{\gdef\@halignto{}\@tabular}
  1790. %    \end{macrocode}
  1791. %     and analoguesly
  1792. %     \begin{macrocode}
  1793. \expandafter\def\csname tabular*\endcsname#1{%
  1794.       \gdef\@halignto{to#1}\@tabular}
  1795. %    \end{macrocode}
  1796. % \end{macro}
  1797. % \end{macro}
  1798. % \begin{macro}{\@tabular}
  1799. %    The rest of the job is carried out by the =\@tabular= macro:
  1800. %    \begin{macrocode}
  1801. \def\@tabular{%
  1802. %    \end{macrocode}
  1803. %    First of all we have to make sure that we start out in {\sf
  1804. %    hmode}.
  1805. %    Otherwise we might find our table dangling by itself on a line.
  1806. %    \begin{macrocode}
  1807.   \leavevmode
  1808. %    \end{macrocode}
  1809. %    It should be taken into consideration that the macro
  1810. %    =\@array=
  1811. %    must be called in math mode. Therefore we open a {\sf box}, insert
  1812. %    a =$= and then assign the correct values to =\col@sep=
  1813. %    and =\d@llar...=.
  1814. % \changes{v2.0d}{90/08/20}{`d@llar local to preamble.}
  1815. %    \begin{macrocode}
  1816.   \hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup
  1817.                                     \let\d@llarend\endgroup
  1818. %    \end{macrocode}
  1819. %    Now everything {\sf tabular} specific is done and we are able to
  1820. %    call the =\@tabarray= macro.
  1821. %    \begin{macrocode}
  1822.   \@tabarray}
  1823. %    \end{macrocode}
  1824. % \end{macro}
  1825. % \begin{macro}{\endarray}
  1826. %    When the processing of {\sf array} is finished we have to
  1827. %    close the =\halign=
  1828. %    and afterwards the surrounding {\sf box} selected by
  1829. %    =\@array=. To save {\sf token} space we then redefine
  1830. %    =\@preamble=
  1831. %    because its replacement text isn't longer needed.
  1832. %    \begin{macrocode}
  1833. \def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
  1834. %    \end{macrocode}
  1835. % \end{macro}
  1836. % \begin{macro}{\endtabular}
  1837. % \begin{macro}{\endtabular*}
  1838. %    To end a {\sf tabular} or {\sf tabular$*$} environment we call up
  1839. %    =\endarray=, close the math mode and then the surrounding
  1840. %    =\hbox=.
  1841. %    \begin{macrocode}
  1842. \def\endtabular{\endarray $\egroup}
  1843. \expandafter\let\csname endtabular*\endcsname=\endtabular
  1844. %    \end{macrocode}
  1845. % \end{macro}
  1846. % \end{macro}
  1847. %   \section{Last minute definitions}
  1848. % If this file is used as a style file we should =\let= all macros
  1849. % to =\relax= that were used in the original but are no longer
  1850. %  necessary.
  1851. %    \begin{macrocode}
  1852. \let\@ampacol=\relax        \let\@expast=\relax
  1853. \let\@arrayclassiv=\relax   \let\@arrayclassz=\relax
  1854. \let\@tabclassiv=\relax     \let\@tabclassz=\relax
  1855. \let\@arrayacol=\relax      \let\@tabacol=\relax
  1856. \let\@tabularcr=\relax      \let\@@endpbox=\relax
  1857. \let\@argtabularcr=\relax   \let\@xtabularcr=\relax
  1858. %    \end{macrocode}
  1859. % \begin{macro}{\@preamerr}
  1860. %    We also have to redefine the error routine =\@preamerr= since
  1861. %    new kind of errors are possible.
  1862. %    The code for this macro is not perfect yet;
  1863. %    it still needs too much memory.
  1864. %    \begin{macrocode}
  1865. \def\@preamerr#1{\def\@tempd{{..} at wrong position: }%
  1866.    \@latexerr{%
  1867.    \ifcase #1 Illegal pream-token (\@nextchar): `c' used\or %0
  1868.     Missing arg: token ignored\or                           %1
  1869.     Empty preamble: `l' used\or                             %2
  1870.     >\@tempd token ignored\or                               %3
  1871.     <\@tempd changed to !{..}\or                            %4
  1872.     Only one column-spec. allowed.\fi}\@ehc}                %5
  1873. %    \end{macrocode}
  1874. % \end{macro}
  1875. % \begin{macro}{\@tfor}
  1876. %    Testing this implementation an error was found in the definition
  1877. %    of the \LaTeX{} macro =\@tfor=. It was not implemented
  1878. %    according to
  1879. %    its specification. The assignment to =\@fortmp= must not take
  1880. %    place
  1881. %    via =\xdef=. A =\def= has to be used because =#2= must
  1882. %    not be expanded. Since this mistake does not show up when
  1883. %    =\@tfor= is used in {\tt latex.tex}, it does not
  1884. %    seem to have been noticed.
  1885. %    \begin{macrocode}
  1886. \def\@tempa#1:=#2\do#3{\def\@fortmp{#2}\ifx\@fortmp\@empty
  1887.       \else\@tforloop#2\@nil\@nil\@@#1{#3}\fi}
  1888. \ifx\@tempa\@tfor
  1889. \else
  1890.   \errhelp{The bug fix for \@tfor was removed from
  1891.            array.sty because it was^^J%
  1892.            corrected in latex.tex <dec91>.^^J^^J%
  1893.            Please update to a newer LaTeX release.}
  1894.   \errmessage{Obsolete LaTeX release (older than Dec.91)}
  1895.   \let\@tfor\@tempa
  1896. \let\@tempa\@empty
  1897. %</style>
  1898. %    \end{macrocode}
  1899. % \end{macro}
  1900. % \section
  1901. %   [Defining your own column specifiers]
  1902. %   {Defining your own column specifiers\footnotemark}
  1903. % \footnotetext{The code and the documentation in this section was
  1904. %   written by David. So far only the code from newarray was plugged
  1905. %   into array so that some parts of the documentation still claim
  1906. %   that this is newarray and even worse, some parts of the code are
  1907. %   unnecessarily doubled. This will go away in a future release. For
  1908. %   the moment we thought it would be more important to bring both
  1909. %   styles together.}
  1910. % \changes{v2.1a}{92/07/03}{Newcolumn stuff added}
  1911. % \DeleteShortVerb{\=}
  1912. % \MakeShortVerb{\"}
  1913. %  \begin{macro}{\newcolumn}
  1914. %    In {\tt newarray.sty} the macro for specifying new columns was
  1915. %    named "\newcolumn". When the functionality was added to {\tt
  1916. %    array.sty} the name changed to "\newcolumntype". To allow
  1917. %    prcessing older sources that made use of {\tt newarray.sty} we
  1918. %    provide a definition for the old name.
  1919. %    \begin{macrocode}
  1920. \def\newcolumn{%
  1921.   \typeout{*** Obsolete command \string\newcolumn!
  1922.                Please use \noexpand\newcolumntype ***}%
  1923.   \newcolumntype
  1924. %    \end{macrocode}
  1925. %  \end{macro}
  1926. % \begin{macro}{\newcolumntype}
  1927. % \changes{v2.1b}{92/06/07}{Macro renamed from `newcolumn} As
  1928. % described above, the "\newcolumntype" macro gives users the chance
  1929. % to define letters, to be used in the same way as the primitive
  1930. % column specifiers, `c' `p' etc.
  1931. %    \begin{macrocode}
  1932. %<*ncols>
  1933. \def\newcolumntype#1{%
  1934. %    \end{macrocode}
  1935. % "\NC@char" was added in V2.01 so that active characters, like "@" in
  1936. % AMS\LaTeX\ may be used. This trick was stolen from {\tt array.sty}
  1937. % 2.0h. Note that we need to use the possibly active token,
  1938. % "#1", in several places, as that is the token that actually
  1939. % appears in the preamble argument.
  1940. %    \begin{macrocode}
  1941.   \edef\NC@char{\string#1}%
  1942. %    \end{macrocode}
  1943. % First we check whether there is already a definition for this column.
  1944. % Unlike "\newcommand" we give a warning rather than an error if it is
  1945. % defined. If it is a new column, add "\NC@do" \meta{column} to
  1946. % the list "\NC@list".
  1947. %    \begin{macrocode}
  1948.   \@ifundefined{NC@find@\NC@char}%
  1949.     {\@tfor\next:=<>clrmbp@!|\do{\if\next\NC@char
  1950.                     \@warning{Redefining primitive column \NC@char}\fi}%
  1951.      \NC@list\expandafter{\the\NC@list\NC@do#1}}%
  1952.     {\@warning{Column \NC@char\space is already defined}}%
  1953. %    \end{macrocode}
  1954. % Now we define a macro with an argument delimited by the new column
  1955. % specifier, this is used to find occurences of this specifier in the
  1956. % user preamble.
  1957. %    \begin{macrocode}
  1958.   \@namedef{NC@find@\NC@char}##1#1{\NC@{##1}}%
  1959. %    \end{macrocode}
  1960. % If an optional argument was not given, give a default argument of 0.
  1961. %    \begin{macrocode}
  1962.   \@ifnextchar[{\newcol@{\NC@char}}{\newcol@{\NC@char}[0]}}
  1963. %    \end{macrocode}
  1964. % \end{macro}
  1965. % \begin{macro}{\newcol@}
  1966. % We can now define the macro which does the rewriting,
  1967. % "\@reargdef" takes the same arguments as "\newcommand", but
  1968. % does not check that the command is new. For a column, say `D' with
  1969. % one argument, define a command "\NC@rewrite@D" with one
  1970. % argument, which recursively calls "\NC@find" on the user preamble
  1971. % after replacing the first token or group with the replacement text
  1972. % specified in the "\newcolumntype" command. "\NC@find" will find the
  1973. % next occurrence of `D' as it will be "\let" equal to
  1974. % "\NC@find@D" by "\NC@do".
  1975. %    \begin{macrocode}
  1976. \def\newcol@#1[#2]#3{\expandafter\@reargdef
  1977.      \csname NC@rewrite@#1\endcsname[#2]{\NC@find#3}}
  1978. %    \end{macrocode}
  1979. % \end{macro}
  1980. % \begin{macro}{\NC@}
  1981. % Having found an occurence of the new column, save the preamble
  1982. % before the column in "\@temptokena", then check to see if we
  1983. % are at the end of the preamble. (A dummy occurrence of the column
  1984. % specifier will be placed at the end of the preamble by "\NC@do".
  1985. %    \begin{macrocode}
  1986. \def\NC@#1{%
  1987.   \@temptokena\expandafter{\the\@temptokena#1}\futurelet\next\NC@ifend}
  1988. %    \end{macrocode}
  1989. % \end{macro}
  1990. % \begin{macro}{\NC@ifend}
  1991. % We can tell that we are at the end as "\NC@do" will place a "\relax"
  1992. % after the dummy column.
  1993. %    \begin{macrocode}
  1994. \def\NC@ifend{%
  1995. %    \end{macrocode}
  1996. % If we are at the end, do nothing. (The whole preamble will now be in
  1997. % "\@temptokena".)
  1998. %    \begin{macrocode}
  1999.   \ifx\next\relax
  2000. %    \end{macrocode}
  2001. % Otherwise set the flag "\if@tempswa", and rewrite the column.
  2002. % "\expandafter" introduced 1n V2.01
  2003. %    \begin{macrocode}
  2004.     \else\@tempswatrue\expandafter\NC@rewrite\fi}
  2005. %    \end{macrocode}
  2006. % \end{macro}
  2007. % \begin{macro}{\NC@do}
  2008. % If the user has specified `C' and `L' as new columns, the list of
  2009. % rewrites (in the token register "\NC@list") will look like
  2010. % "\NC@do *" "\NC@do C" "\NC@do L".
  2011. % So we need to define "\NC@do" as a one argument macro which
  2012. % initialises the rewriting of the specified column. Let us assume that
  2013. % `C' is the argument.
  2014. %    \begin{macrocode}
  2015. \def\NC@do#1{%
  2016. %    \end{macrocode}
  2017. % First we let "\NC@rewrite" and "\NC@find" be
  2018. % "\NC@rewrite@C" and "\NC@find@C" respectively.
  2019. %    \begin{macrocode}
  2020.   \expandafter\let\expandafter\NC@rewrite
  2021.     \csname NC@rewrite@\string#1\endcsname
  2022.   \expandafter\let\expandafter\NC@find
  2023.     \csname NC@find@\string#1\endcsname
  2024. %    \end{macrocode}
  2025. % Clear the token register "\@temptokena" after putting the present
  2026. % contents of the register in front of the token "\NC@find". At the
  2027. % end we place the tokens `"C\relax"' which "\NC@ifend" will use
  2028. % to detect the end of the user preamble.
  2029. %    \begin{macrocode}
  2030.   \expandafter\@temptokena\expandafter{\expandafter}%
  2031.         \expandafter\NC@find\the\@temptokena#1\relax}
  2032. %    \end{macrocode}
  2033. % \end{macro}
  2034. % \begin{macro}{\showcols}
  2035. % This macro is useful for debugging "\newcolumntype" specifications,
  2036. % it is the equivalent of the primitive "\show" command for macro
  2037. % definitions.  All we need to do is locally redefine "\NC@do" to take
  2038. % its argument (say `C') and then "\show" the (slightly modified)
  2039. % definition of "\NC@rewrite@C". Actually as the the list always
  2040. % starts off with "\NC@do *" and we do not want to print the
  2041. % definition of the $*$-form, define "\NC@do" to throw away the first
  2042. % item in the list, and then redefine itsef to print the rest of the
  2043. % definitions.
  2044. %    \begin{macrocode}
  2045. \def\showcols{{\def\NC@do##1{\let\NC@do\NC@show}\the\NC@list}}
  2046. %    \end{macrocode}
  2047. % \end{macro}
  2048. % \begin{macro}{\NC@show}
  2049. % If the column `C' is defined as above, then
  2050. % "\show\NC@rewrite@C" would output\\
  2051. % "\long macro: ->\NC@find >{$}c<{$}".
  2052. % We want to strip the "long macro: ->" and the "\NC@find". So first we
  2053. % use "\meaning" and then apply the macro "\NC@strip" to the tokens so
  2054. % produced and then "\typeout" the required string.
  2055. %    \begin{macrocode}
  2056. \def\NC@show#1{%
  2057.   \typeout{Column #1\expandafter\expandafter\expandafter\NC@strip
  2058.   \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@}}
  2059. %    \end{macrocode}
  2060. % \end{macro}
  2061. % \begin{macro}{\NC@strip}
  2062. % Delimit the arguments to "\NC@strip" with `{\tt:}', `{\tt->}',
  2063. % a space, and "\@@" to pull out the required parts of the output from
  2064. % "\meaning".
  2065. %    \begin{macrocode}
  2066. \def\NC@strip#1:#2->#3 #4\@@{#2 -> #4}
  2067. %    \end{macrocode}
  2068. % \end{macro}
  2069. % \begin{macro}{\NC@list}
  2070. % Allocate the token register used for the rewrite list.
  2071. %    \begin{macrocode}
  2072. \newtoks\NC@list
  2073. %    \end{macrocode}
  2074. % \end{macro}
  2075. % \subsection{The $*$--form}
  2076. % We view the $*$-form as a slight generalisation of the system
  2077. % described in the previous subsection. The idea is to define a $*$
  2078. % column by a command of the form:
  2079. % \begin{verbatim}
  2080. % \newcolumntype{*}[2]{%
  2081. %    \count@=#1\ifnum\count@>0
  2082. %       \advance\count@ by -1 #2*{\count@}{#2}\fi}
  2083. % \end{verbatim}
  2084. % \begin{macro}{\NC@rewrite@*}\label{NC@rewrite@*}
  2085. % This does not work however as "\newcolumntype" takes great care not
  2086. % to expand anything in the preamble, and so the "\if" is never
  2087. % expanded. "\newcolumntype" sets up various other parts of the
  2088. % rewrite correctly though so we can define:
  2089. %    \begin{macrocode}
  2090. \newcolumntype{*}[2]{}
  2091. %    \end{macrocode}
  2092. % Now we must correct the definition of "\NC@rewrite@*". The
  2093. % following is probably more efficient than a direct translation of
  2094. % the idea sketched above, we do not need to put a $*$ in the preamble
  2095. % and call the rewrite recursively, we can just put "#1" copies of
  2096. % "#2" into "\@temptokena". (Nested $*$ forms will be expanded
  2097. % when the whole rewrite list is expanded again, see "\@mkpream")
  2098. %    \begin{macrocode}
  2099. \long\@namedef{NC@rewrite@*}#1#2{%
  2100. %    \end{macrocode}
  2101. % Store the number.
  2102. %    \begin{macrocode}
  2103.   \count@#1
  2104. %    \end{macrocode}
  2105. % Put "#1" copies of "#2" in the token register.
  2106. %    \begin{macrocode}
  2107.   \loop
  2108.   \ifnum\count@>\z@
  2109.   \advance\count@\m@ne
  2110.   \@temptokena\expandafter{\the\@temptokena#2}%
  2111.   \repeat
  2112. %    \end{macrocode}
  2113. % "\NC@do" will ensure that "\NC@find" is "\let" equal
  2114. % to "\NC@find@*".
  2115. %    \begin{macrocode}
  2116.   \NC@find}
  2117. %    \end{macrocode}
  2118. % \end{macro}
  2119. % \subsection{Modifications to internal macros of {\tt array.sty}}
  2120. % \begin{macro}{\@xexpast}
  2121. % \begin{macro}{\@xexnoop}
  2122. % These macros are used to expand $*$-forms in {\tt array.sty}. "\let"
  2123. % them to "\relax" to save space.
  2124. %    \begin{macrocode}
  2125. \let\@xexpast\relax
  2126. \let\@xexnoop\relax
  2127. %    \end{macrocode}
  2128. % \end{macro}
  2129. % \end{macro}
  2130. % \begin{macro}{\save@decl}
  2131. % We do not assume that the token register is free, we add the new
  2132. % declarations to the front of the register. This is to allow user
  2133. % preambles of the form, ">{foo}>{bar}..". Users are not encouraged to
  2134. % enter such expressions directly, but they may result from the
  2135. % rewriting of "\newcolumntype"'s.
  2136. %    \begin{macrocode}
  2137. \def\save@decl{\toks \count@ = \expandafter\expandafter\expandafter
  2138.                   {\expandafter\@nextchar\the\toks\count@}}
  2139. %    \end{macrocode}
  2140. % \end{macro}
  2141. % \begin{macro}{\@mkpream}
  2142. %    The main modification to "\@mkpream" is to replace the call to
  2143. %    "\@xexpast" (which expanded $*$-forms) by a loop which expands
  2144. %    all "\newcolumntype" specifiers.
  2145. %    \begin{macrocode}
  2146. \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
  2147.    \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
  2148. %    \end{macrocode}
  2149. %    Now we remove possible  $*$-forms and user-defined column
  2150. %    specifiers in the user preamble by repeatedly executing the list
  2151. %    "\NC@list" until the re-writes have no more effect. The
  2152. %    expanded preamble will then be in the token register
  2153. %    "\@temptokena". Actually we need to know at this point that
  2154. %    this is not "\toks0".
  2155. %    \begin{macrocode}
  2156.    \@temptokena{#1}\@tempswatrue
  2157.    \@whilesw\if@tempswa\fi{\@tempswafalse\the\NC@list}%
  2158. %    \end{macrocode}
  2159. %    Afterwards we initialize all registers and macros, that we need
  2160. %    for the build-up of the preamble.
  2161. %    \begin{macrocode}
  2162.    \count@\m@ne
  2163.    \let\the@toks\relax
  2164.    \prepnext@tok
  2165. %    \end{macrocode}
  2166. % Having expanded all tokens defined using "\newcolumntype" (including
  2167. % "*"), we evaluate the remaining tokens, which are saved in
  2168. % "\@temptokena".  We use the \LaTeX--macro "\@tfor" to inspect each
  2169. % token in turn.
  2170. %    \begin{macrocode}
  2171.    \expandafter \@tfor \expandafter \@nextchar
  2172.     \expandafter :\expandafter =\the\@temptokena \do
  2173. %    \end{macrocode}
  2174. % "\@testpatch" does not take an argument since {\tt array.sty} 2.0h.
  2175. %    \begin{macrocode}
  2176.    {\@testpach
  2177.    \ifcase \@chclass \@classz \or \@classi \or \@classii
  2178.      \or \save@decl \or \or \@classv \or \@classvi
  2179.      \or \@classvii \or \@classviii
  2180. %    \end{macrocode}
  2181. %    In {\tt newarray.sty} class 9 is equivalent to class 10.
  2182. %    \begin{macrocode}
  2183.      \or \@classx
  2184.      \or \@classx \fi
  2185.    \@lastchclass\@chclass}%
  2186.    \ifcase\@lastchclass
  2187.    \@acol \or
  2188.    \or
  2189.    \@acol \or
  2190.    \@preamerr \thr@@ \or
  2191.    \@preamerr \tw@ \@addtopreamble\@sharp \or
  2192.    \or
  2193.    \else  \@preamerr \@ne \fi
  2194.    \def\the@toks{\the\toks}}
  2195. %    \end{macrocode}
  2196. % \end{macro}
  2197. % \begin{macro}{\@classix}
  2198. %    {\tt array.sty} does not allow repeated {\tt>} declarations for the
  2199. %    same column. This is allowed in {\tt newarray.sty} as documented in
  2200. %    the introduction. Removing the test for this case makes class 9
  2201. %    equivalent to class 10, and so this macro is redundant. It is
  2202. %    "\let" to "\relax" to save space.
  2203. %    \begin{macrocode}
  2204. \let\@classix\relax
  2205. %    \end{macrocode}
  2206. % \end{macro}
  2207. % \begin{macro}{\@classviii}
  2208. %    In {\tt newarray.sty} explicitly allow class 2, as repeated {\tt<}
  2209. %    expressions are accepted by this style.
  2210. %    \begin{macrocode}
  2211. \def\@classviii{\ifnum \@lastchclass >\z@\ifnum\@lastchclass=\tw@\else
  2212.       \@preamerr 4\@chclass 6 \@classvi \fi\fi}
  2213. %    \end{macrocode}
  2214. % \end{macro}
  2215. % \begin{macro}{\@classv}
  2216. % Class 5 is {\tt@}-expressions (and is also called by class 1)
  2217. % This macro was incorrect in Version~1. Now we do not expand the
  2218. % "@"-expression, but instead explicitly replace an
  2219. % "\extracolsep" command by an assignment to "\tabskip" by a
  2220. % method similar to the "\newcolumntype" system described above.
  2221. % "\d@llarbegin" "\d@llarend" were introduced in V2.01 to match
  2222. % {\tt array.sty} 2.0h.
  2223. %    \begin{macrocode}
  2224. \def\@classv{\save@decl
  2225.    \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@
  2226.    \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
  2227.    \prepnext@tok}
  2228. %    \end{macrocode}
  2229. % \end{macro}
  2230. % \begin{macro}{\NC@ecs}
  2231. % Rewrite the first occurrence of "\extracolsep{1in}" to
  2232. % "\tabskip1in\relax". As a side effect discard any tokens after a
  2233. % second "\extracolsep", there is no point in the user entering two of
  2234. % these commands anyway, so this is not really a restriction.
  2235. %    \begin{macrocode}
  2236. \def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}%
  2237.   \ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi}
  2238. %</ncols>
  2239. %    \end{macrocode}
  2240. % \end{macro}
  2241. % \subsection{Support for the {\tt delarray.sty}}
  2242. % The {\tt delarray.sty} style option extends the array syntax by
  2243. % supporting the notation of delimiters. To this end we extend the
  2244. % array parsing mechanism to include a hook which can be used by this
  2245. % (or another) option to do some additional parsing.
  2246. % \begin{macro}{\@tabarray}
  2247. %    This macro tests for an optional bracket and then calls up
  2248. %    "\@@array" or "\@@array[c]" (as default).
  2249. %    \begin{macrocode}
  2250. %<*style>
  2251. \def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}}
  2252. %    \end{macrocode}
  2253. % \end{macro}
  2254. % \begin{macro}{\@@array}
  2255. %    This macro tests could then test an optional delimiter before the
  2256. %    left brace of the main preamble argument. Here in the main style
  2257. %    it simply is let to be "\@array".
  2258. %    \begin{macrocode}
  2259. \let\@@array\@array
  2260. %    \end{macrocode}
  2261. % \end{macro}
  2262. % \begin{macro}{\endarray}
  2263. % \begin{macro}{\@arrayright}
  2264. %    We have to declare the hook we put into "\@array" above.
  2265. %    A similar hook `"\@arrayright"' will be inserted into the
  2266. %    "\endarray" to gain control. Both defaults to empty.
  2267. %    \begin{macrocode}
  2268. \def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
  2269. \let\@arrayleft\@empty
  2270. \let\@arrayright\@empty
  2271. %</style>
  2272. %    \end{macrocode}
  2273. % \end{macro}
  2274. % \end{macro}
  2275. % \section{The documentation driver file}
  2276. % The next bit of code contains the documentation driver file for
  2277. % \TeX{}, i.e., the file that will produce the documentation you are
  2278. % currently reading. It will be extracted from this file by the {\tt
  2279. % docstrip} program.
  2280. %    \begin{macrocode}
  2281. %<+driver>\documentstyle[array,doc]{article}
  2282. %<+driver>
  2283. %<+driver>% dimensions from ltugboat.sty:
  2284. %<+driver>
  2285. %<+driver>\setlength\textwidth{31pc} \setlength\textheight{54pc}
  2286. %<+driver>\setlength{\parindent}{0pt}
  2287. %<+driver>\setlength{\parskip}{2pt plus 1pt minus 1pt}
  2288. %<+driver>\setlength{\oddsidemargin}{8pc}
  2289. %<+driver>\setlength{\marginparwidth}{8pc}
  2290. %<+driver>\setlength{\topmargin}{-2.5pc} \setlength{\headsep}{20pt}
  2291. %<+driver>\setlength{\columnsep}{1.5pc} 
  2292. %<+driver>\setlength{\columnwidth}{18.75pc}
  2293. %<+driver>
  2294. %<+driver>% Allow large table at bottom
  2295. %<+driver>\renewcommand{\bottomfraction}{0.7} 
  2296. %<+driver>
  2297. %<+driver>\EnableCrossrefs         
  2298. %<+driver>%\DisableCrossrefs   % Say \DisableCrossrefs if index is ready
  2299. %<+driver>
  2300. %<+driver>\RecordChanges                  % Gather update information
  2301. %<+driver>
  2302. %<+driver>\CodelineIndex                  % Index code by line number
  2303. %<+driver>
  2304. %<+driver>%\OnlyDescription    % comment out for implementation details
  2305. %<+driver>%\OldMakeindex       % use if your MakeIndex is pre-v2.9
  2306. %<+driver>\begin{document}
  2307. %<+driver>   \DocInput{array.doc}
  2308. %<+driver>\end{document}
  2309. %    \end{macrocode}
  2310. % \PrintIndex
  2311. % \PrintChanges
  2312. % \Finale
  2313. \endinput
  2314.