home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / inputs / distribs / array / array.doc < prev    next >
Encoding:
Text File  |  1992-10-12  |  97.1 KB  |  2,532 lines

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