chiark / gitweb /
mdwtab.dtx: Add a sneaky kern after `\multicolumn'.
[mdwtools] / mdwtab.dtx
1 % \begin{meta-comment} <general public licence>
2 %%
3 %% mdwtab package -- another rewrite of the tabular environment, etc.
4 %% Copyright (c) 1996, 2002, 2003, 2007, 2016, 2020 Mark Wooding
5 %%
6 %% This file is part of the `mdwtools' LaTeX package collection.
7 %%
8 %% `mdwtools' is free software: you can redistribute it and/or modify it
9 %% under the terms of the GNU General Public License as published by the
10 %% Free Software Foundation; either version 2 of the License, or (at your
11 %% option) any later version.
12 %%
13 %% `mdwtools' is distributed in the hope that it will be useful, but
14 %% WITHOUT ANY WARRANTY; without even the implied warranty of
15 %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 %% General Public License for more details.
17 %%
18 %% You should have received a copy of the GNU General Public License
19 %% along with `mdwtools'.  If not, write to the Free Software Foundation,
20 %% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 %%
22 % \end{meta-comment}
23 %
24 % \begin{meta-comment} <Package preambles>
25 %<+mdwtab>\NeedsTeXFormat{LaTeX2e}
26 %<+mdwtab>\ProvidesPackage{mdwtab}
27 %<+mdwtab>                [2020/09/06 1.14.0 Table typesetting with style]
28 %<+mathenv>\NeedsTeXFormat{LaTeX2e}
29 %<+mathenv>\ProvidesPackage{mathenv}
30 %<+mathenv>                [2020/09/06 1.14.0 Various maths environments]
31 %<+colour>\NeedsTeXFormat{LaTeX2e}
32 %<+colour>\ProvidesPackage{mtcolour}
33 %<+colour>                [2020/09/06 1.14.0 Colour support for mdwtab]
34 %<+color>\NeedsTeXFormat{LaTeX2e}
35 %<+color>\ProvidesPackage{mtcolor}
36 %<+color>                [2020/09/06 1.14.0 Fix for people who can't spell]
37 % \end{meta-comment}
38 %
39 % \CheckSum{3426}
40 %% \CharacterTable
41 %%  {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
42 %%   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
43 %%   Digits        \0\1\2\3\4\5\6\7\8\9
44 %%   Exclamation   \!     Double quote  \"     Hash (number) \#
45 %%   Dollar        \$     Percent       \%     Ampersand     \&
46 %%   Acute accent  \'     Left paren    \(     Right paren   \)
47 %%   Asterisk      \*     Plus          \+     Comma         \,
48 %%   Minus         \-     Point         \.     Solidus       \/
49 %%   Colon         \:     Semicolon     \;     Less than     \<
50 %%   Equals        \=     Greater than  \>     Question mark \?
51 %%   Commercial at \@     Left bracket  \[     Backslash     \\
52 %%   Right bracket \]     Circumflex    \^     Underscore    \_
53 %%   Grave accent  \`     Left brace    \{     Vertical bar  \|
54 %%   Right brace   \}     Tilde         \~}
55 %%
56 %
57 % \begin{meta-comment}
58 %
59 %<*driver>
60 \input{mdwtools}
61 \describespackage{mdwtab}
62 \describespackage{mtcolour}
63 \describespackage{mathenv}
64 \addcontents{lot}{\listoftables}
65 \mdwdoc
66 %</driver>
67 %
68 % \end{meta-comment}
69 %
70 %^^A-------------------------------------------------------------------------
71 % \renewcommand{\tabstyle}{\small}
72 %
73 % \section{User guide}
74 %
75 %
76 % The \package{mdwtab} package contains a reimplementation of the standard
77 % \LaTeX\ \env{tabular} and \env{array} environments.  This is not just an
78 % upgraded version: it's a complete rewrite.  It has several advantages over
79 % the official \package{array} package (not raw \LaTeX's, which is even less
80 % nice), and it's more-or-less compatible.  Most of these are rather
81 % technical, I'll admit.
82 %
83 % \begin{itemize}
84 %
85 % \item The newcolumn system is properly and perfectly integrated into the
86 %       system.  There are now \emph{no} `primitive' column types -- all the
87 %       standard types are created as user-defined columns.
88 %
89 % \item You can define entirely different table-like environments using the
90 %       equipment here.  It's still hard work, although less so than before.
91 %       I'll do an example of this some time.
92 %
93 % \item Construction of the preamble is generally much tidier.  I've used
94 %       token registers rather than |\edef|, and it's all done very nicely.
95 %
96 % \item Fine spacing before and after rules (described by DEK as `a mark of
97 %       quality') is now utterly trivial, since the preamble-generator will
98 %       store the appropriate information.
99 %
100 % \item You can use \env{array} in LR and paragraph modes without having
101 %       to surround it with `|$|' signs.
102 %
103 % \item Usually you don't want tables in the middle of paragraphs.  For these
104 %       cases, I've provided a simpler way to position the table
105 %       horizontally.
106 %
107 % \item Footnotes work properly inside \env{tabular} environments (hoorah!).
108 %       You can `catch' footnotes using the \env{minipage} environment if
109 %       you like.  (It uses an internal version of the \package{footnote}
110 %       package to handle footnotes, which doesn't provide extra goodies like
111 %       the \env{footnote} environment; you'll need to load the full package
112 %       explicitly to get them.)
113 %
114 % \item Standard \LaTeX\ tabular environments have a problem with lining up
115 %       ruled tables.  The |\firsthline| command given in the \textit{\LaTeX\
116 %       Companion} helps a bit, but it's not really good enough, and besides,
117 %       it doesn't \emph{actually} line the text up right after all.  The
118 %       \package{mdwtab} package does the job properly to begin with, so you
119 %       don't need to worry.
120 %
121 % \end{itemize}
122 %
123 % I've tested the following packages with \package{mdwtab}, and they all
124 % work.  Some of the contortions required to make them work weren't pleasant,
125 % but you don't need to know about them.  By a strange coincidence, all the
126 % packages were written by David Carlisle.  Anyway, here's the list:
127 % \begin{itemize}
128 % \item The quite nice \package{dcolumn} package.
129 % \item The more useful \package{delarray} package.
130 % \item The rather spiffy \package{hhline} package.
131 % \item The truly wonderful \package{tabularx} package.
132 % \item The utterly magnificent \package{longtable} package.
133 % \end{itemize}
134 %
135 % Note that I've looked at \package{supertabular} as well: it won't work, so
136 % use \package{longtable} instead, 'cos it's much better.
137 %
138 %
139 % \subsection{The downside}
140 %
141 % There's no such thing as a free lunch.  The \package{mdwtab} environment
142 % is not 100\% compatible with the \env{tabular} environment found in
143 % \LaTeXe\ or the \package{array} package.
144 %
145 % The differences between \package{mdwtab} and \LaTeXe's \env{tabular}
146 % environment are as follows:
147 %
148 % \begin{itemize} \synshorts \let\`=\lq
149 %
150 % \item The vertical spacing in \env{array} environments is different to
151 %       that in \env{tabular} environments.  This produces more attractive
152 %       results in most mathematical uses of \env{array}s, in the author's
153 %       opinion.  The spacing can be modified by playing with length
154 %       parameters.
155 %
156 % \item The presence of horizontal and vertical rules will alter the spacing
157 %       of the table (so a pair of columns separated by a `|' is wider than
158 %       a pair with no separation by "\\arrayrulewidth".  This does mean that
159 %       horizontal and vertical rules match up properly -- the usual \LaTeX\
160 %       environment makes the horizontal rules stop just short of the edge
161 %       of the table, making an ugly mess (check out the \textit{\LaTeX\
162 %       book} if you don't believe me -- page~62 provides a good example).
163 %       The \package{array} package handles rules in the same way as
164 %       \package{mdwtab}.
165 %
166 % \setbox0=\hbox{\footnotesize`\\def\\xcs{\\tabskip=\\fill}'}
167 % \setbox2=\hbox{\footnotesize`...@{\\span\\xcs}...'}
168 % \item In common with the \package{array} package, there are some
169 %       restrictions on the use of the "\\extracolsep" command in preambles:
170 %       you may use at most one "\\extracolsep" command in each `@' or `!'
171 %       expression.  Also, you can't say
172 %       \begin{listing}
173 %\newcommand{\xcs}{\extracolsep{\fill}}
174 %       \end{listing}
175 %       and then expect something like `...@{\\xcs}...' to actually work --
176 %       the "\\extracolsep" mustn't be hidden inside any other
177 %       commands.  Because things like `@' expressions aren't expanded at
178 %       the time, "\\extracolsep" has to be searched and processed
179 %       \`by hand'.\footnote{^^A
180 %         All \cs{extracolsep} does is modify the \cs{tabskip} glue, so
181 %         if you were an evil \TeX\ hacker like me, you could just say
182 %         \unhbox0\ and put \unhbox2\ in your preamble.  That'd work nicely.
183 %         It also works with the \package{array} package.}
184 %
185 % \item Control sequences (commands) in a table's preamble aren't expanded
186 %       before the preamble is read.  In fact, commands in the preamble are
187 %       considered to be column types, and their names are entirely
188 %       independent of normal \LaTeX\ commands.  No column types of this
189 %       nature have yet been defined\footnote{^^A
190 %         There used to be an internal \cs{@magic} type used by
191 %         \env{eqnarray}, but you're not supposed to know about that.
192 %         Besides, it's not there any more.}
193 %       but the possibility's always there.  Use the "\\newcolumntype" or
194 %       "\\coldef" commands to define new column types.
195 %
196 % \item The preamble parsing works in a completely different way.  There is
197 %       a certain amount of compatibility provided, although it's heavily
198 %       geared towards keeping \package{longtable} happy and probably won't
199 %       work with other packages.
200 %
201 % \item Obscure constructs which were allowed by the old preamble parser but
202 %       violate the syntax shown in the next section (e.g., `|@{}|' to
203 %       suppress the "\\doublerulesep" space between two vertical rules,
204 %       described in \textit{The \LaTeX\ Companion} as \`a misuse of the
205 %       `@{...}' qualifier') are now properly outlawed.  You will be given
206 %       an error message if you attempt to use such a construction.
207 %
208 % \item The `*' forms (which repeat column types) are now expanded at a
209 %       different time.  Previously, preambles like `c@*{4}{{:}@}{--}c'
210 %       were considered valid (the example would expand to
211 %       `c@{:}@{:}@{:}@{:}@{--}c'), because `*'s were expanded before the
212 %       preamble was actually parsed.  In the new system, `*' is treated
213 %       just like any other preamble character (it just has a rather odd
214 %       action), and preambles like this will result in an error (and
215 %       probably a rather confusing one).
216 %
217 % \item David Carlisle's \package{colortbl} package entirely fails to work
218 %       with \package{mdwtab}.  However, we now have colour support of our
219 %       own which is at times similar in style.
220 %
221 % \end{itemize}
222 %
223 % There are also several incompatibilities between \package{mdwtab} and
224 % \package{array}:
225 %
226 % \begin{itemize} \synshorts \let\`=\lq
227 %
228 % \item Because of the way "\\newcolumntype" works in the \package{array}
229 %       package, a horrid construction like
230 %       \begin{listing}
231 %\newcolumntype{x}{{:}}
232 %\begin{tabular}{|c!xc|}
233 %       \end{listing}
234 %       is considered to be valid, and is interpreted as `|c!{:}c|'.  My
235 %       reading of pages~54 and~55 of the \textit{\LaTeX\ book} tells me
236 %       that this sort of thing is forbidden in normal \LaTeX\ commands.
237 %       The \package{mdwtab} preamble parser now treats column type letters
238 %       much more like commands with the result that the hacking above won't
239 %       work any more.  The construction above would actually be interpreted
240 %       as `|c!{x}c|' (i.e., the `x' column type wouldn't be expanded to
241 %       `{:}' because the parser noticed that it was the argument to the
242 %       `!' modifier\footnote{^^A
243 %         This is a direct result of the way \TeX\ treats undelimited
244 %         arguments.  See chapters~5 and~20 of \textit{The \TeX book} for
245 %         more information about how grouping affects argument reading.}).
246 %
247 % \item Most of the points above, particularly those relating to the
248 %       handling of the preamble, also apply to the \package{array} package.
249 %       it's not such an advance over the \LaTeXe\ version as everyone said
250 %       it was.
251 %
252 % \end{itemize}
253 %
254 %
255 % \subsection{Syntax}
256 %
257 % \DescribeEnv{tabular}
258 % \DescribeEnv{tabular*}
259 % \DescribeEnv{array}
260 % So that everyone knows where I stand, here's a complete syntax for my
261 % version of the \env{tabular} environment, and friends
262 %
263 % \begin{grammar}
264 %
265 % <tabular-env> ::= \[[
266 %   "\\begin"
267 %   \begin{stack}
268 %     "{tabular}" \\ "{tabular*}" "{" <length> "}" \\
269 %     "{array}" \\ "{smarray}"
270 %   \end{stack}
271 %   \[ "[" <position-arg> "]" \]
272 %   "{" <preamble> "}" <text>
273 %   "\\end"
274 %   \( "{tabular}" \\ "{tabular*}" \\ "{array}" \\ "{smarray}" \)
275 % \]]
276 %
277 % <position-arg> ::= (see below)
278 %
279 % <preamble>    ::= \[[
280 %   <first-column>
281 %   \[ \< <column> \> \]
282 % \]]
283 %
284 % <first-column> ::= \[[ \[ <rule> \] <column> \]]
285 %
286 % <column>      ::= \[[
287 %   \[ <spacing> \] \[ \< <user-pre-text> \> \] <column-type>
288 %   \[ \< <user-post-text> \> \] \[ <spacing> \] \[ <rule> \]
289 % \]]
290 %
291 % <spacing>     ::= \[[ "@" "{" <text> "}" \]]
292 %
293 % <user-pre-text> ::= \[[ \[ "?" \] ">" "{" <text> "}" \]]
294 %
295 % <column-type> ::= \[[
296 %   \begin{stack}
297 %     \[ "T" \\ "M" \] \( "l" \\ "c" \\ "r" \) \\
298 %     \( "p" \\ "m" \\ "b" \) "{" <length> "}" \\
299 %     "#" "{" <raw-pre-text> "}" "{" <raw-post-text> "}"
300 %   \end{stack}
301 % \]]
302 %
303 % <user-post-text> ::= \[[ \[ "?" \] "<" "{" <text> "}" \]]
304 %
305 % <rule>        ::= \[[ \( "|" \\ "!" "{" <text> "}" \) \]]
306 %
307 % \end{grammar}
308 %
309 % If you examine the above very carefully, you'll notice a slight deviation
310 % from the original -- an |@|-expression \emph{following} a rule is
311 % considered to be part of the \emph{next} column, not the current one.  This
312 % is, I think, an almost insignificant change, and essential for some of the
313 % new features.  You'll also notice the new |#| column type form, which
314 % allows you to define new real column types instead of just modifying
315 % existing ones.  It's not intended for direct use in preambles -- it's
316 % there mainly for the benefit of people who know what they're doing and
317 % insist on using |\newcolumntype| anyway.
318 %%
319 % The actual column types are shown in table~\ref{tbl:columns}.
320 %
321 % \begin{table}
322 % \begin{tabular}[C]{| >{\synshorts} c | m{3in} |}         \hlx{hv[1]}
323 %
324 % \multicolumn{2}{|c|}{\bf Column types}                \\ \hlx{v[1]hv}
325 % \bf Name      & \bf Meaning                           \\ \hlx{vhv.}
326 % "l"           & Left aligned text (\env{tabular}) or
327 %                 equation (\env{array}).               \\ \hlx{.}
328 % "c"           & Centred text (\env{tabular}) or
329 %                 equation (\env{array}).               \\ \hlx{.}
330 % "r"           & Right aligned text (\env{tabular}) or
331 %                 equation (\env{array}).               \\ \hlx{vhv.}
332 % "Ml", "Mc" and "Mr" & Left, centre and right aligned
333 %                 equations.*                           \\ \hlx{.}
334 % "Tl", "Tc" and "Tr" & Left, centre and right aligned
335 %                 text.*                                \\ \hlx{vhv.}
336 % "p{"<width>"}" & Top aligned paragraph with the given
337 %                 width.                                \\ \hlx{.}
338 % "m{"<width>"}" & Vertically centred paragraph with
339 %                 the given width.                      \\ \hlx{.}
340 % "b{"<width>"}" & Bottom aligned paragraph with the
341 %                 given width.                          \\ \hlx{vhv.}
342 % "#{"<pre>"}{"<post>"}" & User defined column type:
343 %                 \<pre> is inserted before the
344 %                 cell entry, \<post> is inserted
345 %                 afterwards.*                          \\ \hlx{vhhv[1]}
346 %
347 % \multicolumn{2}{|c|}{\bf Other modifier characters}   \\ \hlx{v[1]hv}
348 % \bf Name      & \bf Meaning                           \\ \hlx{vhv.}
349 % "|"           & Inserts a vertical rule between
350 %                 columns.                              \\ \hlx{.}
351 % "$*["<params>"]" & Inserts a vertical rule of given
352 %                 width between columns; "*" selects
353 %                 "\arraythickrulewidth".*              \\ \hlx{.}
354 % "!{"<text>"}" & Inserts \<text> between columns,
355 %                 treating it as a vertical rule.       \\ \hlx{vhv.}
356 % "@{"<text>"}" & Inserts \<text> instead of the
357 %                 usual intercolumn space.              \\ \hlx{vhv.}
358 % ">{"<text>"}" & Inserts \<text> just before the
359 %                 actual column entry.                  \\ \hlx{.}
360 % "<{"<text>"}" & Inserts \<text> just after the
361 %                 actual column entry.                  \\ \hlx{.}
362 % "?>{"<text>"}" & Inserts \<text> before the column
363 %                 entry \emph{and} the rules list.*     \\ \hlx{.}
364 % "?<{"<text>"}" & Inserts \<text> after the column
365 %                 entry \emph{and} the rules list.*     \\ \hlx{.}
366 % "'{"<text>"}" & Inserts \<text> into the rules list
367 %                 only.*                                \\ \hlx{vhv.}
368 % "*{"<count>"}{"<chars>"}" & Inserts \<count>
369 %                 copies of the \<chars> into the
370 %                 preamble.                             \\ \hlx{vhs}
371 %
372 % \multicolumn{2}{@{}l}{* This column type is a new feature}
373 % \end{tabular}
374 %
375 % \caption{\package{array} and \package{tabular} column types and modifiers}
376 % \label{tbl:columns}
377 % \end{table}
378 %
379 % Now that's sorted everything out, there shouldn't be any arguments at all
380 % about what a column means.
381 %
382 % The lowercase \<position-arg>s \lit{t}, \lit{c} and \lit{b} do exactly
383 % what they did before: control the vertical positioning of the table.  The
384 % uppercase ones control the \emph{horizontal} positioning -- this is how you
385 % create \emph{unboxed} tables.  You can only create unboxed tables in
386 % paragraph mode.
387 %
388 % Note that unboxed tables still can't be broken across pages.  Use
389 % the \package{longtable} package for this, because it already does an
390 % excellent job.
391 %
392 % \DescribeMacro{\tabpause}
393 % One thing you can to with unboxed tables, however, is to `interrupt' them,
394 % do some normal typesetting, and then continue.  This is achieved by the
395 % |\tabpause| command: its argument is written out in paragraph mode, and
396 % the table is continued after the argument finishes.
397 % Note that it isn't a real argument as far as commands like |\verb| are
398 % concerned -- they'll work inside |\tabpause| without any problems.
399 %
400 % \DescribeMacro{\vline}
401 % The |\vline| command draws a vertical rule the height of the current table
402 % cell (unless the current cell is being typeset in paragraph mode -- it
403 % only works in the simple LR-mode table cells, or in \lit{@} or \lit{!}
404 % modifiers).  It's now been given an optional argument which describes
405 % parameters for the line.  See section~\ref{sec:ruleparams}.
406 %
407 % { \let\tabstyle=\relax
408 % \begin{demo}{An example of \cmd\vline}
409 %\large
410 %\begin{tabular}
411 %  {| c !{\vline[5pt]} c | c |}
412 %  \hlx{hv}
413 %  \bf A & \it B & \sf C \\
414 %  \hlx[2pt]{vhv}
415 %  \bf D & \it E & \sf F \\
416 %  \hlx{vh}
417 %\end{tabular}
418 % \end{demo}
419 % }
420 %
421 % \DescribeMacro{smarray}
422 % You've probably noticed that there's an unfamiliar environment mentioned
423 % in the syntax shown above.  The \env{smarray} environment produces a
424 % `small' array, with script size cells rather than the normal full text
425 % size cells.  I've seen examples of this sort of construction\footnote{^^A
426 %   There's a nasty use of \env{smallmatrix} in the |testmath.tex| file which
427 %   comes with the \package{amslatex} distribution.  It's actually there to
428 %   simulate a `smallcases' environment, which the \package{mathenv} package
429 %   includes, based around \env{smarray}.} ^^A
430 % being implemented by totally unsuitable commands.  Someone may find it
431 % handy.
432 %
433 %
434 % \subsection{An updated \cs{cline} command}
435 %
436 % \DescribeMacro{\cline}
437 % \DescribeMacro{\hline}
438 % The standard \LaTeX\ |\cline| command has been updated.  As well as just
439 % passing a range of columns to draw lines through, you can now pass a comma
440 % separated list of column numbers and ranges:
441 %
442 % \begin{grammar}
443 % <cline-cmd>   ::= \[[
444 %   "\\cline"
445 %   \[ "*" \] \\ \[ "[" <rule-params> "]" \]
446 %   "{" \< <number> \[ "-" <number> \] \\ "," \> "}"
447 % \]]
448 % \end{grammar}
449 %
450 % The rules printed by |\cline| and |\hline| can be modified by rule
451 % parameters: see section~\ref{sec:ruleparams}.
452 %
453 % Note that |\cline| rules are rather bodgy.  Other rules now have
454 % \emph{thickness}, but |\cline|s don't.  Instead, they backspace over
455 % previous stuff.  If you don't like that, insert an appropriate gap, using
456 % |\vgap|.  The \lit{z} rune in |\hlx| is perfect for this kind of thing --
457 % precede your \lit{c} lines by \lit{z} lines for best results.
458 %
459 % {\let\tabstyle\relax
460 % \begin{demo}[w]{A \cs{cline} example}
461 %\newcommand{\mc}{\multicolumn{1}}
462 %\begin{tabular}[C]{|c|c|c|c|}           \cline{2,4}
463 %  \mc{c|}{one} & two & three & four   \\ \hline
464 %  five & six & seven & \mc{c}{eight}  \\ \cline{1,3}
465 %\end{tabular}
466 % \end{demo}
467 % }
468 %
469 % \subsection{Other stuff}
470 %
471 % \DescribeMacro\nextrow
472 % The \env{tabular} and \env{array} environments maintain a counter
473 % \textsf{tabrow}.  The counter is reset to zero at the start of each table.
474 % It is stepped by one by default; you can provide an optional argument which
475 % is the amount to add.
476 %
477 %
478 % \subsection{Spacing control}
479 %
480 % One of the most irritating things about \LaTeX's tables is that there isn't
481 % enough space around horizontal rules.  Donald Knuth, in \textit{The
482 % \TeX book}, describes addition of some extra vertical space here as `a mark
483 % of quality', and since \TeX\ was designed to produce `beautiful documents'
484 % it seems a shame that \LaTeX\ doesn't allow this to be done nicely.  Well,
485 % it does now.
486 %
487 % \DescribeMacro{\vgap}
488 % The extra vertical space is added using a command |\vgap|, with the
489 % following syntax:
490 %
491 % \begin{grammar}
492 %
493 % <vgap-cmd>    ::= \[[
494 %   "\\vgap" \[ "[" <which-cols> "]" \] "{" <length> "}"
495 % \]]
496 %
497 % <which-cols>  ::= \[[ \< <number> \[ "-" <number> \] \\ "," \> \]]
498 %
499 % \end{grammar}
500 %
501 % This command must appear either immediately after the beginning of the
502 % table or immediately after the |\\| which ends a row.  (Actually, there are
503 % other commands which also have this requirement -- you can specify a
504 % collection of them wherever you're allowed to give any one.)  It adds some
505 % vertical space (the amount is given by the \<length>) to the table,
506 % making sure that the vertical rules of the table are extended correctly.
507 %
508 % The |\vgap| command relies on information stored while your table preamble
509 % is being examined.  However, it's possible that you might not want some
510 % of the rules drawn (e.g., if you've used |\multicolumn|).  The optional
511 % \<which-cols> argument allows you to specify which rules are \emph{not}
512 % to be drawn.  You can specify either single column numbers or ranges.  The
513 % rule at the very left hand side is given the number~0; the rules at the
514 % end of column~$n$ are numbered~$n$.  It's easy really.
515 %
516 % \DescribeMacro{\hlx}
517 % Using |\vgap| is all very well, but it's a bit cumbersome, and takes up a
518 % lot of typing, especially when combined with |\hline| commands.  The |\hlx|
519 % command tries to tidy things.
520 %
521 % The syntax is simple:
522 % \begin{grammar}
523 %
524 % <hlx-cmd>     ::= \[[
525 %   "\\hlx"
526 %   \[ "*" \] \[ "[" <rule-params> "]" \]
527 %   "{"
528 %   \begin{rep}
529 %     \begin{stack}
530 %       "h" \\
531 %       \tok{"v["<which-cols>"]["<length>"]"} \\
532 %       \tok{"z["<which-cols>"]["<length>"]"} \\
533 %       \tok{"s["<length>"]"} \\
534 %       \tok{"c{"<which-cols>"}"} \\
535 %       "b" \\
536 %       \tok{"/["<number>"]"} \\
537 %       \tok{"!{"<rule-params>"}"} \\
538 %       \tok{"?{"<stuff>"}"} \\
539 %       \tok{"+["<step>"]"} \\
540 %       "."
541 %     \end{stack}
542 %   \end{rep}
543 %   "}"
544 % \]]
545 %
546 % \end{grammar}
547 % The |*| or optional \<rule-params> give rule-drawing parameters for the |h|
548 % and |c| subcommands.  (Note that you can't pass a |*| or an optional
549 % parameters argument to the |h| or |c| subcommands directly.)  See
550 % section~\ref{sec:ruleparams}.
551 %
552 % The argument works a bit like a table preamble, really.  Each letter is a
553 % command.  The following are supported:
554 %
555 % \begin{description}
556 %
557 % \item [\lit*{h}] Works just like |\hline|.  If you put two adjacent to each
558 %       other, a gap will be put between them.
559 %
560 % \item [\lit*{v[}\<which-cols>\lit*{][}\<length>\lit*{]}]  Works
561 %       like \syntax{"\\vgap["<which-cols>"]{"<length>"}"}.  If the
562 %       \<length> is omitted, the value of |\doublerulesep| is used.
563 %       This usually looks right.
564 %
565 % \item [\lit*{z[}\<which-cols>\lit*{][}\<length>\lit*{]}]  Like \lit{v},
566 %       except that the default gap is the current rule width (set by the
567 %       \<rule-params>) rather than |\doublerulesep|.  This is a good thing
568 %       to insert before a |\cline| row.
569 %
570 % \item [\lit*{s[}\<length>\lit*{]}]  Leaves a vertical gap with the
571 %       given size.  If you omit the \<length> then |\doublerulesep| is
572 %       used.  This is usually right.
573 %
574 % \item [\lit*{c\char`\{}\<which-cols>\lit*{\char`\}}]  Works just like
575 %       |\cline|.
576 %
577 % \item [\lit*{b}] Inserts a backspace the width of a rule.  This is useful
578 %       when doing \package{longtable}s.
579 %
580 % \item [\lit*{/[}\<number>\lit*{]}]  Allows a page break in a table.  Don't
581 %       use this except in a \env{longtable} environment.  The \<number>
582 %       works exactly the same as it does in the |\pagebreak| command,
583 %       except that the default is 0, which just permits a break without
584 %       forcing it.
585 %
586 % \item [\lit*{!\char`\{}\<rule-params>\lit*{\char`\}}]  Change the rule
587 %       parameters to be used for subsequent subcommands.
588 %
589 % \item [\lit*{?\char`\{}\<stuff>\lit*{\char`\}}]  Do \<stuff>, which can be
590 %       any commands which \emph{don't} typeset anything.
591 %
592 % \item [\lit*{+[\<step>]}]  Add \<step> (default is 1) to the value of the
593 %       \textsf{tabrow} counter.
594 %
595 % \item [\lit*{.}]  (That's a dot)  Starts the next row of the table.  No
596 %       more characters may follow the dot, and no |\hline|, |\hlx|, |\vgap|
597 %       or |\multicolumn| commands may be used after it.  You don't have to
598 %       include it, and most of the time it's totally useless.  It can be
599 %       handy for some macros, though.  I used it in (and in fact added it
600 %       especially for) the table of column types.
601 %
602 % \end{description}
603 %
604 % An example of the use of |\hlx| is given, so you can see what's going on.
605 %
606 % \begin{figure}
607 % \let\tabstyle\relax
608 % \begin{demo}[w]{Beautiful table example}
609 %\newcommand{\zerowidth}[1]{\hbox to 0pt{\hss#1\hss}}
610 %\setlength{\tabcolsep}{1.5em}
611 %\begin{tabular}[C]{| r | c | r |}                  \hlx{hv[1,2]}
612 %  \multicolumn{3}{|c|}{\bf AT\&T Common Stock}  \\ \hlx{v[1,2]hv}
613 %  \multicolumn{1}{|c|}{\zerowidth{\bf Year}} &
614 %  \multicolumn{1}{c|}{\zerowidth{\bf Price}} &
615 %  \multicolumn{1}{c|}{\zerowidth{\bf Dividend}} \\ \hlx{vhv}
616 %  1971 & 41--54 & \$2.60                        \\
617 %     2 & 41--54 &   2.70                        \\
618 %     3 & 46--55 &   2.87                        \\
619 %     4 & 40--53 &   3.24                        \\
620 %     5 & 45--52 &   3.40                        \\
621 %     6 & 51--59 &    .95\rlap{*}                \\ \hlx{vhs}
622 %  \multicolumn{3}{@{}l}{* (first quarter only)}
623 %\end{tabular}
624 % \end{demo}
625 % \end{figure}
626 %
627 %
628 % \subsection{Creating beautiful long tables}
629 %
630 % You can use the |\vgap| and |\hlx| commands with David Carlisle's
631 % stunning \package{longtable} package.  However, there are some things you
632 % should be away of to ensure that your tables always come out looking
633 % lovely.
634 %
635 % The \package{longtable} package will break a table at an |\hline| command,
636 % leaving a rule at the bottom of the page and another at the top of the
637 % next page.  This means that a constructions like |\hlx{vhv}| will be
638 % broken into something like |\hlx{vh}| at the bottom of the page and
639 % |\hlx{hv}| at the top of the next.  You need to design the table headers
640 % and footers with this in mind.
641 %
642 % However, there appears to be a slight problem:\footnote
643 %   {You might very well call it a bug.  I couldn't possibly comment.}
644 % if the footer starts with an |\hline|, and a page is broken at an |\hline|,
645 % then you get an extra thick rule at the bottom of the page.  This is a bit
646 % of a problem, because if the rule isn't there in the footer and you get
647 % a break between two rows \emph{without} a rule between them, then the page
648 % looks very odd.
649 %
650 % If you want to do ruled longtables, I'd recommend that you proceed as
651 % follows:
652 % \begin{itemize}
653 % \item End header sections with an |\hlx{vh}|.
654 % \item Begin footer sections with an |\hlx{bh}|.
655 % \item Begin the main table with |\hlx{v}|.
656 % \item Insert |\hlx{vhv}| commands in the main table body as usual.
657 % \end{itemize}
658 % If \package{longtable} gets modified appropriately, the use of the \lit{b}
659 % command won't be necessary.
660 %
661 % Here's an example of the sort of thing you'd type.
662 %
663 % \begin{listinglist} \listingsize
664 % \verb"\begin{longtable}[c]{|c|l|}           \hlx{hv}" \\
665 % \verb"\bf Heading & \bf Also heading     \\ \hlx{vh}" \\
666 % \verb"\endhead" \\
667 % \verb"\hlx{bh}" \\
668 % \verb"\endfoot" \\
669 % \verb"\hlx{v}" \\
670 % \verb"First main & table line            \\ \hlx{vhv}" \\
671 % \verb"Lots of text & like this           \\ \hlx{vhv}" \\
672 % \null\quad\vdots \\
673 % \verb"Lots of text & like this           \\ \hlx{vhv}" \\
674 % \verb"Last main & table line             \\ \hlx{vh}" \\
675 % \verb"\end{longtable}"
676 % \end{listinglist}
677 %
678 %
679 % \subsection{Rules and vertical positioning}
680 %
681 % In the \LaTeXe\ and \package{array.sty} versions of \env{tabular}, you run
682 % into problems if you try to use ruled tables together with the \lit{[t]} or
683 % \lit{[b]} position specifiers -- the top or bottom rule ends up being
684 % nicely lined up with the text baseline, giving you an effect which is
685 % nothing like the one you expected.  The \textit{\LaTeX\ Companion} gives
686 % two commands |\firsthline| and |\lasthline| which are supposed to help with
687 % this problem.  (These commands have since migrated into the \package{array}
688 % package.)  Unfortunately, |\firsthline| doesn't do its job properly --
689 % it gets the text position wrong by exactly the width of the table rules.
690 %
691 % The \package{mdwtab} package makes all of this automatic.  It gets the
692 % baseline positions exactly right, whether or not you use rules.  Earlier
693 % versions of this package required that you play with a length parameter
694 % called |\rulefudge|; this is no longer necessary (or even possible -- the
695 % length parameter no longer exists).  The package now correctly compensates
696 % for all sorts of rules and |\vgap|s at the top and bottom of a table and
697 % it gets the positioning right all by itself.  You've never had it so good.
698 %
699 %
700 % \subsection{Rule parameters}
701 % \label{sec:ruleparams}
702 %
703 % The rule-drawing commands |\hline|, |\vline|, |\cline| and |\hlx|, and the
704 % |$| column type (which is otherwise a synonym for "|") accept \emph{rule
705 % parameters}.  If the command is followed by a |*|, then the rules are a bit
706 % thicker than usual -- they use |\arraythickrulewidth| rather than
707 % |\arrayrulewidth|.  However, there's an optional argument which can contain
708 % one of:
709 %
710 % \begin{description} \setdescriptionlabel{\ttfamily#1}
711 % \item[thin] Use |\arrayrulewidth| as the line width.  This is the default.
712 % \item[thick] Use |\arraythickrulewidth| as the line width.  This is the
713 %   same as giving a |*| after the command.
714 % \item[width=\<length>] Make the rules exactly \<length> wide.
715 % \item[\<length>] The same as \texttt{width=\<length>}, for compatibility.
716 % \end{description}
717 %
718 % More of these keywords will be added later if past experience is anything
719 % to go by.  Note that the individual |\hlx| subcommands \emph{don't} take
720 % rule parameters, but see the |!| subcommand for updating the current
721 % parameters.
722 %
723 % \DescribeMacro\tabsetruleparams
724 % If you say \syntax{"\\tabsetruleparams{"<rule-params>"}"} then the
725 % \<rule-params> will be prepended to any parameters provided to specific
726 % rule-drawing commands (including the \lit{\char`\|} preamble command).  For
727 % example, |\tabsetruleparams{thick}| makes all rules thick.  This is a local
728 % declaration.
729 %
730 %
731 % \subsection{User serviceable parts}
732 %
733 % There are a lot of parameters which you can modify in order to make arrays
734 % and tables look nicer.  They are all listed in table~\ref{tbl:config}.
735 %
736 % \begin{table}
737 % \begin{tabular}[C]{| l | m{3in} |}                               \hlx{hv}
738 % \bf Parameter         & \bf Meaning                           \\ \hlx{vhv}
739 % |\tabstyle|           & A command executed at the beginning of
740 %                         a \env{tabular} or \env{tabular$*$}
741 %                         environment.  By default does nothing.
742 %                         Change using |\renewcommand|.         \\ \hlx{vhv}
743 % |\extrarowheight|     & A length added to the height of every
744 %                         row, used to stop table rules
745 %                         overprinting ascenders.  Default 0\,pt.
746 %                         Usage is deprecated now: use |\hlx|
747 %                         instead.                              \\ \hlx{vhv}
748 % |\tabextrasep|        & Extra space added between rows in a
749 %                         \env{tabular} or \env{tabular$*$}
750 %                         environment (added \emph{before} any
751 %                         following |\hline|).  Default 0\,pt.  \\
752 % |\arrayextrasep|      & Analogous to |\tabextrasep|, but for
753 %                         \env{array} environments.  Default
754 %                         1\,jot (3\,pt).                       \\
755 % |\smarrayextrasep|    & Analogous to |\tabextrasep|, but for
756 %                         \env{smarray} environments.  Default
757 %                         1\,pt.                                \\ \hlx{vhv}
758 % |\tabcolsep|          & Space added by default on each side of
759 %                         a table cell (unless suppressed by an
760 %                         \lit{@}-expression) in \env{tabular}
761 %                         environments.  Default is defined by
762 %                         your document class.                  \\
763 % |\arraycolsep|        & Analogous to |\tabcolsep|, but for
764 %                         \env{array} environments.  Default is
765 %                         defined by your document class.       \\
766 % |\smarraycolsep|      & Analogous to |\tabcolsep|, but for
767 %                         \env{smarray} environments.  Default
768 %                         is 3\,pt.                             \\ \hlx{vhv}
769 % |\arrayrulewidth|     & The width of horizontal and vertical
770 %                         rules in tables.                      \\
771 % |\arraythickrulewidth|& The width of starred rules in tables. \\
772 % |\doublerulesep|      & Space added between two adjacent
773 %                         vertical or horizontal rules.  Also
774 %                         used by |\hlx{v}|.                    \\ \hlx{vhv}
775 % |\arraystretch|       & Command containing a factor to
776 %                         multiply the default row height.
777 %                         Default is defined by your document
778 %                         class (usually 1).                    \\ \hlx{vh}
779 % \end{tabular}
780 %
781 % \caption{Parameters for configuring table environments}
782 % \label{tbl:config}
783 %
784 % \end{table}
785 %
786 %
787 % \subsection{Defining column types}
788 %
789 % \DescribeMacro{\newcolumntype}
790 % The easy way to define new column types is using |\newcolumntype|.  It
791 % works in more or less the same way as |\newcommand|:
792 %
793 % \begin{grammar}
794 %
795 % <new-col-type-cmd> ::= \[[
796 %   "\\newcolumntype"
797 %   "{" <column-name> "}"
798 %   \[ "[" <num-args> "]" \]
799 %   \[ "[" <default-arg> "]" \]
800 %   "{" <first-column> \[ \< <column> \> \] "}"
801 % \]]
802 %
803 % \end{grammar}
804 %
805 % (The \env{array.sty} implementation doesn't accept the \<default-arg>
806 % argument.  I've no idea why not, 'cos it was very easy to implement.)
807 %
808 % \DescribeMacro{\colset}
809 % This implementation allows you to define lots of different sets of columns.
810 % You can change the current set using the |\colset| declaration:
811 % \begin{grammar}
812 % <colset-cmd>  ::= \[[ "\\colset" "{" <set-name> "}" \]]
813 % \end{grammar}
814 % This leaves a problem, though: at any particular moment, the current
815 % column set could be anything, since other macros and packages can change
816 % it.
817 %
818 % \DescribeMacro{\colpush}
819 % \DescribeMacro{\colpop}
820 % What actually happens is that a stack of column sets is maintained.  The
821 % |\colset| command just replaces the item at the top of the stack.  The
822 % command |\colpush| pushes its argument onto the top of the stack, making
823 % it the new current set.  The corresponding |\colpop| macro (which doesn't
824 % take any arguments) removes the top item from the stack, reinstating the
825 % previous current column set.
826 %
827 % \begin{grammar}
828 % <colpush-cmd> ::= \[[ "\\colpush" "{" <set-name> "}" \]]
829 % <colpop-cmd>  ::= \[[ "\\colpop" \]]
830 % \end{grammar}
831 %
832 % The macros which manipulate the column set stack work \emph{locally}.
833 % The contents of the stack are saved when you open a new group.
834 %
835 % To make sure everyone behaves themselves properly, these are the rules for
836 % using the column set stack:
837 %
838 % \begin{itemize}
839 %
840 % \item Packages defining column types must ensure that they preserve the
841 %       current column set.  Either they must push their own column type
842 %       and pop it off when they're finished defining columns, or they must
843 %       avoid changing the stack at all, and use the optional arguments to
844 %       |\coldef| and |\collet|.
845 %
846 % \item Packages must not assume that any particular column set is current
847 %       unless they have made sure of it themselves.
848 %
849 % \item Packages must ensure that they pop exactly as much as they push.
850 %       There isn't much policing of this (perhaps there should be more),
851 %       so authors are encouraged to behave responsibly.
852 %
853 % \item Packages must change the current column set (using |\colset|) when
854 %       they start up their table environment.  This will be restored when
855 %       the environment closes.
856 %
857 % \end{itemize}
858 %
859 % \DescribeMacro{\coldef}
860 % |\newcolumntype| is probably enough for most purposes.  However, Real
861 % \TeX nicians, and people writing new table-generating environments, require
862 % something lower-level.
863 %
864 % \begin{grammar}
865 % <coldef-cmd>  ::= \[[
866 %   "\\coldef"
867 %     \[ "[" <set-name> "]" \]
868 %     <col-name> <arg-template> "{" <replacement-text> "}"
869 % \]]
870 % \end{grammar}
871 %
872 % Note that this defines a column type in the current colset.  It works
873 % almost exactly the same way as \TeX's primitive |\def|.  There is a
874 % potential gotcha here: a |\tab@mkpream| token is inserted at the end of
875 % your replacement text.  If you need to read an optional argument or
876 % something, you'll need to gobble this token before you carry on.  The
877 % |\@firstoftwo| macro could be handy here:
878 % \begin{listing}
879 %\coldef x{\@firstoftwo{\@ifnextchar[\@xcolumn@i\@xcolumn@ii}}}
880 % \end{listing}
881 % This isn't a terribly pretty state of affairs, and I ought to do something
882 % about it.  I've not seen any use for an optional argument yet, though.
883 % Note that if you do gobble the |\tab@mkpream|, it's your responsibility to
884 % insert another one at the very end of your macro's expansion (so that
885 % further preamble characters can be read).
886 %
887 % The replacement text is inserted directly.  It's normal to insert preamble
888 % elements here.  There are several to choose from:
889 %
890 % \begin{description}
891 %
892 % \item [Column items] provide the main `meat' of a column.  You insert a
893 %       column element by saying
894 %       \syntax{"\\tabcoltype{"<pre-text>"}{"<post-text>"}"}.
895 %       The user's text gets inserted between these two.  (So do user pre-
896 %       and post-texts.  Bear this in mind.)
897 %
898 % \item [User pre-text items] work like the \lit{>} preamble command.  You
899 %       use the \syntax{"\\tabuserpretype{"<text>"}"} command to insert it.
900 %       User pre-texts are written in \emph{reverse} order between the
901 %       pre-text of the column item and the text from the table cell.
902 %
903 % \item [User post-text items] work like the \lit{<} preamble command.  You
904 %       use the \syntax{"\\tabuserposttype{"<text>"}"} command to insert it.
905 %       Like user pre-texts, user post-texts are written in reverse order,
906 %       between the table cell text and the column item post-text.
907 %
908 % \item [Space items] work like the \lit{@} preamble command.  They're
909 %       inserted with the \syntax{"\\tabspctype{"<text>"}"} command.
910 %
911 % \item [Rule items] work like the `\verb"|"' and \lit{!} commands.  You
912 %       insert them with the \syntax{"\\tabruletype{"<text>"}"} command.
913 %       Note that the text is inserted by |\vgap| too, so it should contain
914 %       things which adjust their vertical size nicely.  If you really need
915 %       to, you can test |\iftab@vgap| to see if you're in a |\vgap|.
916 %
917 % \end{description}
918 %
919 % \DescribeMacro{\collet}
920 % As well as defining columns, you can copy definitions (rather like |\let|
921 % allows you to copy macros).  The syntax is like this:
922 %
923 % \begin{grammar}
924 %
925 % <collet-cmd>  ::= \[[
926 %   \[ "[" <set-name> "]" \] <col-name> \[ "=" \] \[ "[" <set-name> "]" \]
927 %   <col-name>
928 % \]]
929 %
930 % \end{grammar}
931 %
932 % (In other words, you can copy definitions from other column sets.)
933 %
934 %
935 % \subsection{Defining new table-generating environments}
936 %
937 % Quite a few routines are provided specifically to help you to define new
938 % environments which do alignment in a nice way.
939 %
940 % \subsubsection{Reading preambles}
941 %
942 % The main tricky bit in doing table-like environments is parsing preambles.
943 % No longer.
944 %
945 % \DescribeMacro{\tab@readpreamble}
946 % \DescribeMacro{\tab@doreadpream}
947 % The main parser routine is called |\tab@doreadpream|.  Given a user
948 % preamble string as an argument, it will build an |\halign| preamble to
949 % return to you.  However, the preamble produced won't be complete.  This is
950 % because you can actually make multiple calls to |\tab@doreadpream| with
951 % bits of user preambles.  The |\newcolumntype| system uses this mechanism,
952 % as does the \lit{*} (repeating) modifier.  When there really is no more
953 % preamble to read, you need to \emph{commit} the heldover tokens to the
954 % output.  The |\tab@readpreamble| routine will do this for you -- given a
955 % user preamble, it builds a complete output from it.
956 %
957 % A token register |\tab@preamble| is used to store the generated preamble.
958 % Before starting, you must initialise this token list to whatever you want.
959 % There's another token register, |\tab@shortline|, which is used to store
960 % tokens used by |\vgap|.  For each column in the table, the list contains
961 % an |\omit| (to override the standard preamble) and an |\hfil| space taking
962 % up most of the column.  Finally, for each rule item in the user preamble,
963 % the shortline list contains an entry of the form:
964 % \begin{quote} \synshorts
965 %   "\\tab@ckr{"<column-number>"}{"<rule-text>"}"
966 % \end{quote}
967 % This is used to decide whether to print the rule or an empty thing of the
968 % same width.  You probably ought to know that the very first column does
969 % \emph{not} have a leading |\omit| -- this is supplied by |\vgap| so that
970 % it can then look for optional arguments.
971 %
972 % \DescribeMacro{\tab@initread}
973 % As well as initialising |\tab@preamble| and emptying |\tab@shortline|,
974 % there are several other operations required to initialise a preamble read.
975 % These are all performed by the |\tab@initread| macro, although you may want
976 % to change some of the values for your specific application.  For reference,
977 % the actions performed are:
978 % \begin{itemize}
979 % \item initialising the parser state by setting $|\tab@state| =
980 %       |\tab@startstate|$;
981 % \item clearing the token lists |\tab@preamble| and |\tab@shortlist|;
982 % \item initialising the macros |\tab@tabtext|, |\tab@midtext|, and
983 %       |\tab@multicol| to their default values of `|&|',
984 %       `|\ignorespaces#\unskip|' and the empty token list respectively.^^A
985 %       \footnote{^^A
986 %         These are macros rather than token lists to avoid hogging all
987 %         the token list registers.  Actually, the package only allocates
988 %         two, although it does use almost all of the temporary registers as
989 %         well.  Also, there's a lie: \cs{unskip} is too hamfisted to remove
990 %         trailing spaces properly;  I really use a macro called
991 %         \cs{@maybe@unskip}}
992 % \item clearing the internal token list registers |\tab@pretext|,
993 %       |tab@userpretext| and |\tab@posttext|;
994 % \item clearing the column counter |\tab@columns| to zero;
995 % \item clearing the action performed when a new column is started (by making
996 %       the |\tab@looped| macro equal to |\relax|; this is used to make
997 %       |\multicolumn| macro raise an error if you try to do more than one
998 %       column); and
999 % \item setting up some other switches used by the parser (|\iftab@rule|,
1000 %       |\iftab@initrule| and |\iftab@firstcol|, all of which are set to be
1001 %       |true|).
1002 % \end{itemize}
1003 %
1004 % The macro |\tab@multicol| is used by the |\multicolumn| command to insert
1005 % any necessary items (e.g., struts) before the actual column text.  If you
1006 % set this to something non-empty, you should probably consider adding a
1007 % call to the macro to the beginning of |\tab@preamble|.
1008 %
1009 % When parsing is finally done, the count register |\tab@columns| contains
1010 % the number of columns in the alignment.  Don't corrupt this value, because
1011 % it's used for handling |\hline| commands.
1012 %
1013 % \subsubsection{Starting new lines}
1014 %
1015 % The other messy bit required by table environments is the newline command
1016 % |\\|.  There are nasty complications involved with starting new lines, some
1017 % of which can be handled by this package, and some on which I can only give
1018 % advice.
1019 %
1020 % \DescribeMacro{\tab@cr}
1021 % The optional arguments and star-forms etc. can be read fairly painlessly
1022 % using the |\tab@cr| command:
1023 %
1024 % \begin{grammar}
1025 % <tabcr-cmd>   ::= \[[
1026 %   "\\tab@cr" <command> "{" <non-star-text> "}" "{" <star-text> "}"
1027 % \]]
1028 % \end{grammar}
1029 %
1030 % This will call your \<command> with two arguments.  The first is the
1031 % contents of the optional argument, or `|\z@|' if there wasn't one.  The
1032 % second is either \<star-text> or \<non-star-text> depending on
1033 % whether the user wrote the $*$-form or not.
1034 %
1035 % Somewhere in your \<command>, you'll have to use the |\cr| primitive to
1036 % end the table row.  After you've done this, you \emph{must} ensure that you
1037 % don't do anything that gets past \TeX's mouth without protecting it --
1038 % otherwise |\hline| and co.\ won't work.  I usually wrap things up in a
1039 % |\noalign| to protect them, although there are other methods.  Maybe.
1040 %
1041 % You might like to have a look at the \env{eqnarray} implementation provided
1042 % to see how all this gets put into practice.
1043 %
1044 %
1045 % \subsection{Colour support}
1046 %
1047 % I've now added colour support to \package{mdwtab}.  That is, you can play
1048 % with the colours of table cell backgrounds, rules and text.  The support
1049 % isn't there by default: you have to either give the \textsf{colour} option
1050 % when you load \package{mdwtab}, or include the \package{mtcolour} package
1051 % yourself.  It's very new, and might break.  It's probably not as good as
1052 % \package{colortbl}.  I prefer English spellings for the commands and
1053 % declarations: to reduce confusion, I've provided synonyms with fewer `u's.
1054 % If only American package authors were so thoughtful.  The examples in this
1055 % part of the documentation may not display correctly in some DVI viewers:
1056 % for best results, run |dvips| and view the PostScript using (say)
1057 % GhostScript.
1058 %
1059 % \subsubsection{New commands and features}
1060 %
1061 % \DescribeMacro\cellcolour
1062 % The |\cellcolour| command changes the background colour for the current
1063 % cell.  You can use it directly in a table cell, or in the table preamble.
1064 % It doesn't matter whereabouts in the table cell it goes.  Note that
1065 % unlike the \package{colortbl}, the |\cellcolour| command works on the
1066 % \emph{entire} contents of the cell, including the |\tabcolsep| space and
1067 % the rules, if any.  That means that it's robust even if there are |@{...}|
1068 % preamble commands present.
1069 %
1070 % The actual syntax is like this:
1071 %
1072 % \begin{grammar}
1073 % <cell-colour-cmd> ::= \[[
1074 %   \( "\\cellcolour" \\ "\\cellcolor" \)
1075 %   \[ "*" \]
1076 %   \[ "[" <colour-model> "]" \]
1077 %   "{" <colour> "}"
1078 %   \[ "[" <left-overhang> "]"
1079 %      \[ "[" <right-overhang> "]" \] \]
1080 % \]]
1081 % \end{grammar}
1082 %
1083 % The \lit{*} makes |\cellcolour| override an extant |\rowcolour| command
1084 % (see below).  The \<colour-model> and \<colour> are as for the |\color|
1085 % command.  The \<left-overhang> is how much the colour band should stick out
1086 % to the left of the cell; and similarly for the \<right-overhang>.  If you
1087 % don't give a \<right-overhang> then the same value is used for both; if you
1088 % give neither then there's no overhang.  The reason you might want overhang
1089 % is to deal with |\extracolsep| glue.  I shouldn't worry about it if I were
1090 % you.
1091 %
1092 % It's very useful to use |\cellcolour| in a preamble, in particular, in the
1093 % |?>| preamble command (which was added specifically).  (If you use only |>|
1094 % then |\vgap| leaves very odd-looking gaps in the table.)
1095 %
1096 % { \let\tabstyle=\relax
1097 % \begin{demo}{A coloured table}
1098 %\newcolumntype{\c}[2]{%
1099 %  >{\color{#1}}%
1100 %  ?>{\cellcolour{#2}}%
1101 %}
1102 %\begin{tabular}
1103 %   {|\c{cyan}{red}c|
1104 %     \c{magenta}{green}c|
1105 %     \c{yellow}{blue}c|}
1106 %                       \hlx{hv}
1107 %  One  &Two  &Three \\ \hlx{vhv}
1108 %  Four &Five &Six   \\ \hlx{vhv}
1109 %  Seven&Eight&Nine  \\ \hlx{vh}
1110 %\end{tabular}
1111 % \end{demo}
1112 % }
1113 %
1114 % Obviously, judicious use of |\newcolumntype| would abbreviate the above
1115 % considerably.
1116 %
1117 % \DescribeMacro\rowcolour
1118 % \DescribeMacro\rowcolouroff
1119 % The |\rowcolour| command changes the background colour in the same way as
1120 % |\cellcolour|; however, its effect takes precedence over |\cellcolour| (but
1121 % not |\cellcolour*|) if both are active, and isn't automatically turned off
1122 % at the start of the next cell.  To actually turn it off again, say
1123 % |\rowcolouroff|.
1124 %
1125 % \begin{grammar}
1126 % <row-colour-cmd> ::= \[[
1127 %   \( "\\rowcolour" \\ "\\rowcolor" \)
1128 %   \[ "[" <colour-model> "]" \]
1129 %   "{" <colour> "}"
1130 % \]]
1131 % \end{grammar}
1132 %
1133 % Note that you don't get to specify overhang parameters here.  The ones from
1134 % the |\cellcolour| declaration are used, unless there isn't one in which
1135 % case there aren't any.
1136 %
1137 % \DescribeMacro\ifmod
1138 % A common thing to do is colour alternate rows of the table differently.
1139 % This is a bit tricker for \package{mdwtab} than it would be for, say,
1140 % \package{array}, since it's hard to spot where the `rows' actually change.
1141 % The solution is to use the \textsf{tabrow} counter, and |\ifmod|.  Saying
1142 % say \syntax{"\\ifmod{"$x$"}{"$m$"}{"$y$"}{"<yes>"}{"<no>"}"} is the same as
1143 % saying \<yes> if $x \bmod m = y$, and \<no> otherwise.  This is typically
1144 % used as follows.
1145 %
1146 % % { \let\tabstyle=\relax
1147 % \begin{demo}{Alternating row colours}
1148 %\begin{tabular}
1149 %  {|?>{\ifmod
1150 %    {\value{tabrow}}{2}{1}
1151 %    {\rowcolour{white}}
1152 %    {\rowcolour[gray]{0.9}}}
1153 %     c|c|}
1154 %  \hlx{h+v}
1155 %  One   & Two   \\ \hlx{vh+v}
1156 %  Three & Four  \\ \hlx{vh+v}
1157 %  Five  & Six   \\ \hlx{vh+v}
1158 %  Seven & Eight \\ \hlx{vh+v}
1159 %  Nine  & Ten   \\ \hlx{vh+}
1160 %\end{tabular}
1161 % \end{demo}
1162 % }
1163 %
1164 % There are new rule parameters for colours.  You get a colourful rule if you
1165 % say \syntax{"colour" "=" <colour>}.  You can also say \syntax{"colourmodel"
1166 % "=" <colour-model>} to choose unnamed colours.
1167 %
1168 % When I've thought of what other things need doing, I'll do some of them.
1169 % The kit I've provided \emph{can} do most interesting things, but it might
1170 % require a certain level of hacking.  Ask me if you want something and it's
1171 % not obvious how to do it.
1172 %
1173 % \subsubsection{Dirty tricks}
1174 %
1175 % The colour support interacts with |\vgap| very badly.  The preamble rune
1176 % |?>{\cellcolour{...}}| works well if you want to colour a column, and
1177 % |\rowcolour| works either in the preamble or as
1178 % |\hlx{?{\rowcolour{...}}}|.  But what if you want to just colour one table
1179 % cell?  You can, as suggested above, just say |\cellcolour{...}| in the
1180 % table text, but that leaves really nasty-looking gaps above and below if
1181 % there are adjacent |\vgap| rows.
1182 %
1183 % This is what |\hlx{?{...}}| was invented for.  Here's a demo.
1184 %
1185 % \begin{demo}[w]{Colouring just one cell}
1186 %\let\hack=\relax
1187 %\begin{tabular}[C]{|c|?>{\hack}c|}          \hlx{hv}
1188 %Uncoloured & cells here                  \\ \hlx{vhv}
1189 %And some & more                          \\
1190 %        \hlx{vh?{\gdef\hack{\cellcolour{red}}}v}
1191 %Yet more & This one's red!               \\
1192 %        \hlx{vh?{\global\let\hack=\relax}v}
1193 %And more & uncoloured cells              \\ \hlx{vh}
1194 %\end{tabular}
1195 % \end{demo}
1196 %
1197 %
1198 % \subsection{The \package{mathenv} package alignment environments}
1199 %
1200 % The \package{mathenv} package provides several environments for aligning
1201 % equations in various ways.  They're mainly provided as a demonstration of
1202 % the table handling macros in \package{mdwtab}, so don't expect great
1203 % things.  If you want truly beautiful mathematics, use
1204 % \package{amsmath}.\footnote{^^A
1205 %   Particularly since nice commands like \cmd\over\ are being reactivated
1206 %   in a later release of \package{amsmath}.}
1207 % However, the various environments do nest in an approximately useful way.
1208 % I also think that the \env{matrix} and \env{script} environments provided
1209 % here give better results than their \package{amsmath} equivalents, and
1210 % they are certainly more versatile.
1211 %
1212 % \subsubsection{The new \env{eqnarray} environment}
1213 %
1214 % \DescribeEnv{eqnarray}
1215 % \DescribeEnv{eqnarray*}
1216 % As an example of the new column defining features, and because the original
1217 % isn't terribly good, I've included a rewritten version of the
1218 % \env{eqnarray} environment.  The new implementation closes the gap between
1219 % \env{eqnarray} and \AmSTeX\ alignment features.  It's in a separate,
1220 % package called \package{mathenv}, to avoid wasting your memory.
1221 %
1222 % \begin{grammar}
1223 %
1224 % <eqnarray-env> ::= \[[
1225 %   <begin-eqnarray> \< <row> \\ "\\\\" \> <end-eqnarray>
1226 % \]]
1227 %
1228 % <begin-eqnarray> ::= \[[
1229 %   "\\begin" \( "{eqnarray}" \\ "{eqnarray*}" \)
1230 %   \[ "[" \< <eqa-column> \> "]" \]
1231 % \]]
1232 %
1233 % <eqa-column>  ::= \[[
1234 %   \[ "q" \\ ":" \]
1235 %   \[ \< ">" "{" <pre-text> "}" \> \]
1236 %   \begin{stack}
1237 %     \[ "T" \] \( "r" \\ "c" \\ "l" \) \\
1238 %     "L" \\
1239 %     "x"
1240 %   \end{stack}
1241 %   \[ \< "<" "{" <post-text> "}" \> \]
1242 % \]]
1243 %
1244 % <end-eqnarray> ::= \[[
1245 %   "\\end" \begin{stack} "{eqnarray}" \\ "{eqnarray*}" \end{stack}
1246 % \]]
1247 %
1248 % \end{grammar}
1249 %
1250 % Descriptions of the various column types are given in
1251 % table~\ref{tbl:eqnarray}.
1252 %
1253 % \begin{table}
1254 % \begin{tabular}[C]{| >{\synshorts} c | m{3in} |}         \hlx{hv[1]}
1255 %
1256 % \multicolumn{2}{|c|}{\bf Column types}                \\ \hlx{v[1]hv}
1257 % \bf Name      & \bf Meaning                           \\ \hlx{vhv.}
1258 % "l"           & Left aligned piece of equation.       \\ \hlx{.}
1259 % "c"           & Centred piece of equation.            \\ \hlx{.}
1260 % "x"           & Centred or flush-left whole equation
1261 %                 (depending on \textsf{fleqn} option). \\ \hlx{.}
1262 % "r"           & Right aligned piece of equation.      \\ \hlx{vhv.}
1263 % "L"           & Left aligned piece of equation whose
1264 %                 width is considered to be 2\,em.      \\ \hlx{vhv.}
1265 % "Tl", "Tc" and "Tr" & Left, centre and right aligned
1266 %                 text.                                 \\ \hlx{vhhv[1]}
1267 %
1268 % \multicolumn{2}{|c|}{\bf Other modifier characters}   \\ \hlx{v[1]hv}
1269 % \bf Name      & \bf Meaning                           \\ \hlx{vhv.}
1270 % ":"           & Leaves a big gap between equations.
1271 %                 By default, the `chunks' separated by
1272 %                 \lit{:}s are equally spaced on the
1273 %                 line.                                 \\ \hlx{.}
1274 % "q"           & Inserts 1\,em of space                \\ \hlx{vhv.}
1275 % ">{"<text>"}" & Inserts \<text> just before the
1276 %                 actual column entry.                  \\ \hlx{.}
1277 % "<{"<text>"}" & Inserts \<text> just after the
1278 %                 actual column entry.                  \\ \hlx{vhv.}
1279 % "*{"<count>"}{"<chars>"}" & Inserts \<count>
1280 %                 copies of the \<chars> into the
1281 %                 preamble.                             \\ \hlx{vh}
1282 % \end{tabular}
1283 %
1284 % \caption{\package{eqnarray} column types and modifiers}
1285 % \label{tbl:eqnarray}
1286 % \end{table}
1287 %
1288 % The default preamble, if you don't supply one of your own, is \lit{rcl}.
1289 % Most of the time, \lit{rl} is sufficient, although compatibility is more
1290 % important to me.
1291 %
1292 % By default, there is no space between columns, which makes formul\ae\ in an
1293 % \env{eqnarray} environment look just like formul\ae\ typeset on their own,
1294 % except that things get aligned in columns.  This is where the default
1295 % \env{eqnarray} falls down: it leaves |\arraycolsep| space between each
1296 % column making the thing look horrible.
1297 %
1298 % An example would be good here, I think.  This one's from exercise 22.9 of
1299 % the \textit{\TeX book}.
1300 %
1301 % \begin{demo}[w]{Simultaneous equations}
1302 %\begin{eqnarray}[*3{rc}rl]
1303 %  10w & + &  3x & + & 3y & + & 18z & = 1 \\
1304 %   6w & - & 17x &   &    & - &  5z & = 2
1305 %\end{eqnarray}
1306 % \end{demo}
1307 %
1308 % Choosing a more up-to-date example, here's some examples from  the
1309 % \textit{\LaTeX\ Companion}.
1310 %
1311 % \begin{demo}[w]{Lots of equations}
1312 %\begin{eqnarray}[rl:rl:lq]
1313 % V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
1314 %       U_i = u_i, \qquad \mbox{for $i \ne j$}  \\
1315 % V_j &= v_j,           & X_j &= x_j            &
1316 %       U_j u_j + \sum_{i \ne j} q_i u_i. \label{eq:A}
1317 %\end{eqnarray}
1318 % \end{demo}
1319 %
1320 % \begin{figure}
1321 % \begin{demo}[w]{Plain text column and \cs{tabpause}}
1322 %\begin{eqnarray}[rlqqTl]
1323 %     x  &= y           & by (\ref{eq:A}) \\
1324 %     x' &= y'          & by definition \\
1325 %\tabpause{and}
1326 % x + x' &= y + y'      & by Axiom~1
1327 %\end{eqnarray}
1328 % \end{demo}
1329 % \end{figure}
1330 %
1331 % The new features also mean that you don't need to mess about with
1332 % |\lefteqn| any more.  This is handled by the \lit{L} column type:
1333 %
1334 % \begin{demo}{Splitting example}
1335 %\begin{eqnarray*}[Ll]
1336 %   w+x+y+z = \\
1337 %    & a+b+c+d+e+{} \\
1338 %    & f+g+h+i+j
1339 %\end{eqnarray*}
1340 % \end{demo}
1341 %
1342 % Finally, just to prove that the spacing's right at last, here's another one
1343 % from the \textit{Companion}.
1344 %
1345 % \begin{demo}{Spacing demonstration}
1346 %\begin{equation}
1347 %  x^2 + y^2 = z^2
1348 %\end{equation}
1349 %\begin{eqnarray}[rl]
1350 %  x^2 + y^2 &= z^2 \\
1351 %        y^2 &< z^2
1352 %\end{eqnarray}
1353 % \end{demo}
1354 %
1355 % Well, that was easy enough.  Now on to numbering.  As you've noticed, the
1356 % equations above are numbered.  You can use the \env{eqnarray$*$}
1357 % environment to turn off the numbering in the whole environment, or say
1358 % |\nonumber| on a line to suppress numbering of that one in particular.
1359 %
1360 % \DescribeMacro{\eqnumber}
1361 % More excitingly, you can say |\eqnumber| to enable numbering for a
1362 % particular equation, or \syntax{"\\eqnumber["<text>"]"} to choose what to
1363 % show instead of the line number.  This works for both starred and unstarred
1364 % versions of the environment.  Now |\nonumber| becomes merely a synonym for
1365 % `|\eqnumber[]|'.
1366 %
1367 % A note for cheats: you can use the sparkly new \env{eqnarray} for simple
1368 % equations by specifying \lit{x} as the column description.  Who needs
1369 % \AmSTeX?\ |;-)|
1370 %
1371 % \DescribeEnv{eqlines}
1372 % \DescribeEnv{eqlines*}
1373 % In fact, there's a separate environment \env{eqlines}, which is equivalent
1374 % to \env{eqnarray} with a single \lit{x} column; the result is that you can
1375 % insert a collection of displayed equations separated by |\\| commands.  If
1376 % you don't like numbering, use \env{eqlines$*$} instead.
1377 %
1378 % \subsubsection{The \env{eqnalign} environment}
1379 %
1380 % \DescribeEnv{eqnalign}
1381 % There's a new environment, \env{eqnalign}, which does almost the same
1382 % thing as \env{eqnarray} but not quite.  It doesn't do equation numbers,
1383 % and it wraps its contents up in a box.  The result of this is that:
1384 %
1385 % \begin{itemize}
1386 %
1387 % \item You can use \env{eqnalign} for just a part of a formula.
1388 %       The \env{eqnarray} environment must take up the whole display.
1389 %
1390 % \item You can use \env{eqnalign} within \env{eqnarray} for extra fine
1391 %       alignment of subsidiary bits.
1392 %
1393 % \item You can break off from doing an \env{eqnarray} using the |\tabpause|
1394 %       command.  You can't use |\tabpause| inside
1395 %       \env{eqnalign}.\footnote{^^A
1396 %         Well, technically speaking there's nothing to stop you.  However,
1397 %         the results won't be pretty.}
1398 %
1399 % \end{itemize}
1400 %
1401 % The \env{eqnalign} environment works like this:
1402 %
1403 % \begin{grammar}
1404 %
1405 % <eqnalign-env> ::= \[[
1406 %   <begin-eqnalign> <contents> <end-eqnalign>
1407 % \]]
1408 %
1409 % <begin-eqnalign> ::= \[[
1410 %   "\\begin" "{eqnalign}"
1411 %   \[ "[" \< <eqa-column> \> "]" \]
1412 %   \[ "[" \( "t" \\ "c" \\ "b" \) "]" \]
1413 % \]]
1414 %
1415 % <end-eqnalign> ::= \[[ "\\end" "{eqnalign}" \]]
1416 %
1417 % \end{grammar}
1418 %
1419 % As the syntax suggests, the preamble for the \env{eqnalign} environment
1420 % works exactly the same way as for \env{eqnarray}.  Example time: another
1421 % one from the \textit{\TeX book}.
1422 %
1423 % \begin{figure}
1424 % \begin{demo}[w]{Example of \env{eqnalign}}
1425 %\[
1426 %  \left\{ \begin{eqnalign}[rl]
1427 %    \alpha &= f(z) \\ \beta  &= f(z^2) \\
1428 %    \gamma &= f(z^3)
1429 %  \end{eqnalign} \right\}
1430 %  \qquad
1431 %  \left\{ \begin{eqnalign}[rl]
1432 %    x &= \alpha^2 - \beta \\ y &= 2\gamma
1433 %  \end{eqnalign} \right\}.
1434 %\]
1435 % \end{demo}
1436 % \end{figure}
1437 %
1438 % \DescribeMacro{\multicolumn}
1439 % The |\multicolumn| command works correctly in both the \env{eqnarray} and
1440 % \env{eqnalign} environments, although you should bear in mind that you
1441 % should give \env{eqnarray} column types, not \env{array} ones.
1442 %
1443 % \subsubsection{A note on spacing in alignment environments}
1444 %
1445 % Most of the time, equations in \env{eqnarray} and \env{eqnalign}
1446 % environments will be beautiful.  However, there are some things you should
1447 % bear in mind when you produce beautiful equations.
1448 %
1449 % The main problem with spacing is making sure that binary relations and
1450 % binary operators have the correct amount of space on each side of them.
1451 % The alignment environments insert `hidden' objects at the ends of table
1452 % cells to assist with the spacing: \lit{l} column types have a hidden object
1453 % on the left, \lit{r} types have a hidden object on the right, and \lit{c}
1454 % types have a hidden object on \emph{both} ends.  These hidden objects add
1455 % the correct space when there's a binary operator or relation next to them.
1456 % If some other sort of object is lurking there, no space is added.  So far,
1457 % so good.
1458 %
1459 % The only problem comes when you have something like this:
1460 %
1461 % \begin{demo}{How not to do an \env{eqnarray}}
1462 %\begin{eqnarray*}[rcl]
1463 %  x +  y & = & 12 \\
1464 % 2x - 5y & = & -6
1465 %\end{eqnarray*}
1466 % \end{demo}
1467 %
1468 % The `$-$' sign in the second equation has been treated as a binary operator
1469 % when really it should be a unary prefix operator, but \TeX\ isn't clever
1470 % enough to know the difference.  (Can you see the difference in the spacing
1471 % between $-6$~and~${}-6$?)  There are two possible solutions to the
1472 % problem.  You could wrap the `|-6|' up in a group (`|{-6}|'), or just the
1473 % $-$ sign (`|{-}6|').  A better plan, though, is to get rid of the middle
1474 % column altogether:
1475 %
1476 % \begin{demo}{How to do an \env{eqnarray}}
1477 %\begin{eqnarray*}[rl]
1478 %  x +  y & = 12 \\
1479 % 2x - 5y & = -6
1480 %\end{eqnarray*}
1481 % \end{demo}
1482 %
1483 % Since the things in the middle column were the same width, it's not
1484 % actually doing any good.  Also, now that \TeX\ can see that the thing on
1485 % the left of the `$-$' sign is a relation (the `$=$' sign), it will space
1486 % the formula correctly.
1487 %
1488 % In this case, it might be even better to add some extra columns, and line
1489 % up the $x$ and $y$ terms in the left hand side:
1490 %
1491 % \begin{demo}{Extra beautiful \env{eqnarray}}
1492 %\begin{eqnarray*}[rrl]
1493 %  x + &  y & = 12 \\
1494 % 2x - & 5y & = -6
1495 %\end{eqnarray*}
1496 % \end{demo}
1497 %
1498 % ^^A Some hacking now to display box sizes.
1499 %
1500 % {
1501 % \catcode`p=12 \catcode`t=12
1502 % \gdef\magni#1pt{#1}
1503 % }
1504 %
1505 % \newcommand{\widthof}[1]{^^A
1506 %   \settowidth{\dimen0 }{#1}^^A
1507 %   \expandafter\magni\the\dimen0\,pt^^A
1508 % }
1509 %
1510 % ^^A The text below makes an assumption which looks correct to me (I asked
1511 % ^^A TeX, and it agreed with me), although in case anything changes, I want
1512 % ^^A to be informed.
1513 %
1514 % \sbox0{$+$} \sbox2{$-$} \ifdim\wd0=\wd2\else%
1515 %   \errmessage{Assertion failed: `+' and `-' are different widths!}
1516 % \fi
1517 %
1518 % There's no need to put the `$+$' and `$-$' operators in their own column
1519 % here, because they're both \widthof{$+$} wide, even though they don't
1520 % look it.
1521 %
1522 % \subsubsection{Configuring the alignment environments}
1523 %
1524 % There are a collection of parameters you can use to make the equation
1525 % alignment environments (\env{eqnarray} and \env{eqnalign}) look the way
1526 % you like them.  These are all shown in table~\ref{tbl:eqnparms}.
1527 %
1528 % \begin{table}
1529 % \begin{tabular}[C]{| l | p{3in} |}                               \hlx{hv}
1530 % \bf Parameter         & \bf Use                               \\ \hlx{vhv}
1531 % |\eqaopenskip|        & Length put on the left of an
1532 %                         \env{eqnarray} environment.  By
1533 %                         default, this is |\@centering| (to
1534 %                         centre the alignment) or |\mathindent|
1535 %                         (to left align) depending on whether
1536 %                         you're using the \textsf{fleqn}
1537 %                         document class option.                \\
1538 % |\eqacloseskip|       & Length put on the right of an
1539 %                         \env{eqnarray} environment.  By
1540 %                         default, this is |\@centering|, to
1541 %                         align the environment correctly.      \\ \hlx{vhv}
1542 % |\eqacolskip|         & Space added by the \lit{:} column
1543 %                         modifier.  This should be a rubber
1544 %                         length, although it only stretches in
1545 %                         \env{eqnarray}, not in \env{eqnalign}.
1546 %                         The default value is 1\smallf1/2\,em
1547 %                         with 1000\,pt of stretch.             \\
1548 % |\eqainskip|          & Space added at each side of a normal
1549 %                         column.  By default this is 0\,pt.    \\ \hlx{vhv}
1550 % |\eqastyle|           & The maths style used in the alignment.
1551 %                         By default, this is |\textstyle|,
1552 %                         and you probably won't want to change
1553 %                         it.                                   \\ \hlx{vh}
1554 % \end{tabular}
1555 %
1556 % \caption{Parameters for the \env{eqnarray} and \env{eqnalign} environments}
1557 % \label{tbl:eqnparms}
1558 % \end{table}
1559 %
1560 %
1561 % \subsection{Other multiline equations}
1562 %
1563 % Sometimes there's no sensible alignment point for splitting equations.  The
1564 % normal thing to do under these circumstances is to put the first line way
1565 % over to the left of the page, and the last line over to the right.  (If
1566 % there are more lines, I imagine we put them in the middle.)
1567 %
1568 % \DescribeEnv{spliteqn}
1569 % \DescribeEnv{spliteqn*}
1570 % The \env{spliteqn} environment allows you to do such splitting of
1571 % equations.  Rather than tediously describe it, I'll just give an example,
1572 % because it's really easy.  The $*$-version works the same, except it
1573 % doesn't put an equation number in.
1574 %
1575 % \begin{figure}
1576 % \begin{demo}[w]{A split equation}
1577 %\begin{spliteqn}
1578 %  \sum_{1\le j\le n}
1579 %  \frac {1} { (x_j - x_1) \ldots (x_j - x_{j-1})
1580 %              (x - x_j) (x_j - x_{j+1}) \ldots (x_j - x_n) }
1581 %  \\
1582 %  = \frac {1} { (x - x_1) \ldots (x - x_n) }.
1583 %\end{spliteqn}
1584 % \end{demo}
1585 % \end{figure}
1586 %
1587 % \DescribeEnv{subsplit}
1588 % If you have a very badly behaved equation, you might want to split a part
1589 % of it (say, a bit of a fraction), particularly if you're doing things in
1590 % narrow columns.
1591 %
1592 % \begin{figure}
1593 % \begin{demo}[w]{A \env{subsplit} environment}
1594 %\begin{equation}
1595 %  \frac{
1596 %    \begin{subsplit}
1597 %      q^{\frac{1}{2} n(n+1)}(ea; q^2)_\infty (eq/a; q^2)_\infty \\
1598 %                 (caq/e; q^2)_\infty (cq^2/ae; q^2)_\infty
1599 %    \end{subsplit}
1600 %  }{
1601 %    (e; q)_\infty (cq/e; q)_\infty
1602 %  }
1603 %\end{equation}
1604 % \end{demo}
1605 % \end{figure}
1606 %
1607 % \subsection{Matrices}
1608 %
1609 % Also included in the \package{mathenv} package is a collection of things
1610 % for typesetting matrices.  The standard \env{array} doesn't (in my opinion)
1611 % provide the right sort of spacing for matrices.  \PlainTeX\ provides some
1612 % quite nice matrix handling macros, but they don't work in the appropriate
1613 % \LaTeX\ way.
1614 %
1615 % \textbf{Warning:} These definitions will make old versions of
1616 % \package{plain.sty} unhappy; newer versions correctly restore the
1617 % Plain~\TeX\ macros |\matrix| and |\pmatrix|.
1618 %
1619 % \DescribeEnv{matrix}
1620 % The simple way to do matrices is with the \env{matrix} environment.
1621 %
1622 % \begin{grammar}
1623 %
1624 % <matrix-env>  ::= \[[ <begin-matrix> <contents> <end-matrix> \]]
1625 %
1626 % <begin-matrix> ::= \[[ "\\begin{matrix}" \[ "[" <matrix-cols> "]" \] \]]
1627 %
1628 % <matrix-cols> ::= \[[
1629 %   \< \[ "[" \] \[ "T" \] \( "l" \\ "c" \\ "r" \) \>
1630 % \]]
1631 %
1632 % <end-matrix>  ::= \[[ "\\end{stack}" \]]
1633 %
1634 % \end{grammar}
1635 %
1636 % The \lit{l}, \lit{c} and \lit{r} columns are fairly obvious -- they align
1637 % their contents in the appropriate way.  The \lit{[} character is more
1638 % complicated.  It means `repeat the remaining column types forever', so a
1639 % preamble of \lit{cc[lr} means `two centred columns, then alternating left-
1640 % and right-aligned columns for as often as needed'.  The default preamble,
1641 % if you don't specify one, is \lit{[c} -- `any number of centred columns'.
1642 %
1643 % \DescribeMacro{\multicolumn}
1644 % The |\multicolumn| command works correctly in matrices, although you should
1645 % bear in mind that you should give \env{matrix} column types, not
1646 % \env{array} ones.
1647 %
1648 % \DescribeEnv{pmatrix}
1649 % The standard \env{matrix} environment doesn't put any delimiters around the
1650 % matrix.  You can use the standard |\left| and |\right| commands, although
1651 % this is a bit nasty.  The \env{pmatrix} environment will put parentheses
1652 % around the matrix it creates; it's otherwise exactly the same as
1653 % \env{matrix}.
1654 %
1655 % \DescribeEnv{dmatrix}
1656 % A \env{dmatrix} environment is also provided.  It takes two extra
1657 % arguments: the left and right delimiter characters (without |\left| or
1658 % |\right|).
1659 %
1660 % \begin{figure}
1661 % \begin{demo}[w]{Various \env{matrix} environments}
1662 %\[ \begin{matrix} 1 & 0 \\ 0 & -1 \end{matrix} \quad
1663 %   \begin{pmatrix}
1664 %     \cos\theta & \sin\theta \\
1665 %    -\sin\theta & \cos\theta
1666 %   \end{pmatrix} \quad
1667 %   \begin{dmatrix}[] 0 & -i \\ i & 0 \end{dmatrix}
1668 %\]
1669 % \end{demo}
1670 % \end{figure}
1671 %
1672 % \DescribeEnv{smatrix}
1673 % Normal matrices always come out the same size; they don't change size
1674 % according to the surrounding context (unfortunately).  However, it can be
1675 % occasionally useful to put matrices in running text, so you can talk about
1676 % $A$ being $\bigl( \begin{smatrix} a & b \\ b & c \end{smatrix} \bigr)$
1677 % being its own transpose (i.e., $A = A^T$).  This is accomplished using the
1678 % \env{smatrix} (the `s' stands for `small' -- I thought that `smallmatrix'
1679 % was too big to type inline).  As well as inline text, the \env{smatrix}
1680 % can be useful in displays, if the matrix is deep in a subformula.  I can't
1681 % think of any examples offhand, though.
1682 %
1683 % \DescribeEnv{spmatrix}
1684 % \DescribeEnv{sdmatrix}
1685 % The \env{smatrix} environment doesn't supply any delimiters, like
1686 % \env{matrix}.  There are \env{spmatrix} and \env{sdmatrix} environments
1687 % which do, though.  Note that delimiters have a tendency to get too big and
1688 % mess up the line spacing -- I had to use explicitly |\big| delimiters
1689 % in the above example.
1690 %
1691 % \DescribeEnv{pmatrix*}
1692 % \DescribeEnv{spmatrix*}
1693 % \DescribeEnv{sdmatrix*}
1694 % All the small matrix environments have starred versions, which are more
1695 % suitable for use in displays, since they have more space between the rows.
1696 % They're intended for typesetting really big matrices in displays.
1697 %
1698 % \DescribeMacro{\ddots}
1699 % \DescribeMacro{\vdots}
1700 % The standard |\vdots| and |\ddots| commands don't produce anything at all
1701 % nice in small matrices, so this package redefines them so that they scale
1702 % properly to smaller sizes.
1703 %
1704 % \DescribeEnv{genmatrix}
1705 % Actually, all these environments are special cases of one: \env{genmatrix}.
1706 % This takes oodles of arguments:
1707 % \begin{quote} \synshorts
1708 % "\\begin{genmatrix}{"<matrix-style>"}{"<outer-style>"}" \\
1709 % \null \qquad "{"<spacing>"}{"<left-delim>"}{"<right-delim>"}" \\
1710 % \null \quad\vdots \\
1711 % "\\end{genmatrix}"
1712 % \end{quote}
1713 % The two `style' arguments should be things like |\textstyle| or
1714 % |\scriptstyle|; the first, \<matrix-style>, is the style to use for the
1715 % matrix elements, and the second, \<outer-style>, is the style to assume
1716 % for the surrounding text (this affects the spacing within the matrix; it
1717 % should usually be the same as \<matrix-style>).  The \<spacing> is inserted
1718 % between the matrix and the delimiters, on each side of the matrix.  It's
1719 % usually `|\,|' in full-size matrices, and blank for small ones.  The
1720 % delimiters are inserted around the matrices, and sized appropriately.
1721 %
1722 % \DescribeEnv{newmatrix}
1723 % You can create your own matrix environments if you like, using the
1724 % |\newmatrix| command.  It takes two arguments, although they're a bit
1725 % odd.  The first is the name of the environment, and the second contains
1726 % the arguments to pass to \env{genmatrix}.  For example, the \env{pmatrix}
1727 % environment was defined by saying
1728 %
1729 % \begin{listing}
1730 %\newmatrix{pmatrix}{{\textstyle}{\textstyle}{\,}{(}{)}}
1731 % \end{listing}
1732 %
1733 % If you don't pass all three arguments, then you end up requiring the
1734 % user to specify the remaining ones.  This is how \env{dmatrix} works.
1735 %
1736 % \DescribeEnv{script}
1737 % Finally, although it's not really a matrix, stacked super- and subscripts
1738 % follow much the same sorts of spacing rules.  The \env{script} environment
1739 % allows you to do this sort of thing very easily.  It essentially provides
1740 % a `matrix' with the right sort of spacing.  The default preamble string is
1741 % \lit{c}, giving you centred scripts, although you can say
1742 % |\begin{script}[l]| for left-aligned scripts, which is better if the
1743 % script is being placed to the right of its operator.  If you're really
1744 % odd, you can have more than one column.
1745 %
1746 % \begin{demo}{Example of \env{script}}
1747 %\[ \mathop{{\sum}'}_{x \in A}
1748 %   f(x)
1749 %   \stackrel{\mathrm{def}}{=}
1750 %   \sum_{\begin{script}
1751 %     x \in A \\ x \ne 0
1752 %   \end{script}} f(x)
1753 %\]
1754 % \end{demo}
1755 %
1756 %
1757 % \subsection{Other \package{mathenv} environments}
1758 %
1759 % The \package{mathenv} package contains some other environments which may
1760 % be useful, based on the enhanced \env{tabular} and \env{array}
1761 % environments.
1762 %
1763 % \DescribeEnv{cases}
1764 % The \env{cases} environment lets you say things like the following:
1765 %
1766 % \begin{demo}[w]{Example of \env{cases}}
1767 %\[ P_{r-j} = \begin{cases}
1768 %               0 & if $r-j$ is odd \\
1769 %               r!\,(-1)^{(r-j)/2} & if $r-j$ is even
1770 %             \end{cases}
1771 %\]
1772 % \end{demo}
1773 %
1774 % The spacing required for this is a bit messy, so providing an environment
1775 % for it is quite handy.
1776 %
1777 % \DescribeEnv{smcases}
1778 % The \env{smcases} environment works the same way as \env{cases}, but with
1779 % scriptsize lettering.
1780 %
1781 % \implementation
1782 %
1783 %
1784 %^^A-------------------------------------------------------------------------
1785 % \section{Implementation of table handling}
1786 %
1787 %
1788 % Here we go.  It starts horrid and gets worse.  However, it does stay nicer
1789 % than the original, IMHO.
1790 %
1791 %    \begin{macrocode}
1792 %<*mdwtab>
1793 %    \end{macrocode}
1794 %
1795 %
1796 % \subsection{Registers, switches and things}
1797 %
1798 % We need lots of these.  It's great fun.
1799 %
1800 % The two count registers are simple enough:
1801 %
1802 % \begin{description}
1803 % \item [\cs{tab@state}] contains the current parser state.  Since we
1804 %       probably won't be parsing preambles recursively, this is a global
1805 %       variable.
1806 % \item [\cs{tab@columns}] contains the number of the current column.
1807 % \item [\cs{tab@hlstate}] contains the state required for hline management.
1808 % \item [\textsf{tabrow}] contains the row number in the table.  It's a
1809 %       proper \LaTeX\ counter.
1810 % \end{description}
1811 %
1812 %    \begin{macrocode}
1813 \newcount\tab@state
1814 \newcount\tab@columns
1815 \newcounter{tabrow}
1816 %    \end{macrocode}
1817 %
1818 % We need \emph{lots} of token registers.  Fortunately, most of them are only
1819 % used during parsing.  We'll use \PlainTeX's scratch tokens for this.  Note
1820 % that |\toks\tw@| isn't used here.  It, and |\toks@|, are free for use by
1821 % column commands.
1822 %
1823 %    \begin{macrocode}
1824 \newtoks\tab@preamble
1825 \newtoks\tab@shortline
1826 \toksdef\tab@pretext 4
1827 \toksdef\tab@posttext 6
1828 \toksdef\tab@userpretext 8
1829 %    \end{macrocode}
1830 %
1831 % The dimens are fairly straightforward.  The inclusion of |\col@sep| is a
1832 % sacrifice to compatibility -- judicious use of |\let| in \package{array}
1833 % would have saved a register.
1834 %
1835 %    \begin{macrocode}
1836 \newdimen\extrarowheight
1837 \newdimen\tabextrasep
1838 \newdimen\arrayextrasep
1839 \newdimen\smarraycolsep
1840 \newdimen\smarrayextrasep
1841 \newdimen\tab@width
1842 \newdimen\col@sep
1843 \newdimen\tab@endheight
1844 \newdimen\arraythickrulewidth
1845 \newdimen\tab@rulewidth
1846 %    \end{macrocode}
1847 %
1848 % Some skip registers too.  Phew.
1849 %
1850 %    \begin{macrocode}
1851 \newskip\tab@leftskip
1852 \newskip\tab@rightskip
1853 %    \end{macrocode}
1854 %
1855 % And some switches.  The first three are for the parser.
1856 %
1857 %    \begin{macrocode}
1858 \newif\iftab@firstcol
1859 \newif\iftab@initrule
1860 \newif\iftab@rule
1861 \newif\iftab@vgap
1862 \newif\iftab@colour
1863 %    \end{macrocode}
1864 %
1865 % Now assign some default values to new dimen parameters.  These definitions
1866 % are essentially the equivalent of an |\openup 1\jot| in \env{array}, but
1867 % not in \env{tabular}.  This looks nice, I think.
1868 %
1869 %    \begin{macrocode}
1870 \tabextrasep\z@
1871 \arrayextrasep\jot
1872 \smarraycolsep\thr@@\p@
1873 \smarrayextrasep\z@
1874 \arraythickrulewidth\p@
1875 %    \end{macrocode}
1876 %
1877 % Set some things up for alien table environments.
1878 %
1879 %    \begin{macrocode}
1880 \let\tab@extrasep\tabextrasep
1881 \let\tab@penalty\relax
1882 %    \end{macrocode}
1883 %
1884 %
1885 % \subsection{Options processing}
1886 %
1887 % Notice options, load package.
1888 %
1889 %    \begin{macrocode}
1890 \DeclareOption{colour}{\tab@colourtrue}
1891 \DeclareOption{color}{\tab@colourtrue}
1892 \ProcessOptions
1893 \RequirePackage{mdwkey}
1894 %    \end{macrocode}
1895 %
1896 % \subsection{Some little details}
1897 %
1898 % \begin{macro}{\@maybe@unskip}
1899 %
1900 % This macro solves a little problem.  In an alignment (and in other places)
1901 % it's desirable to suppress trailing space.  The usual method, to say
1902 % |\unskip|, is a little hamfisted, because it removes perfectly reasonable
1903 % aligning spaces like |\hfil|s.  While as a package writer I can deal with
1904 % this sort of thing by saying |\kern\z@| in appropriate places, it can
1905 % annoy users who are trying to use |\hfill| to override alignment in funny
1906 % places.
1907 %
1908 % My current solution seems to be acceptable.  I'll remove the natural width
1909 % of the last glue item, so that it can still stretch and shrink if
1910 % necessary.  The implementation makes use of the fact that multiplying
1911 % a \<skip> by a \<number> kills off the stretch.  (Bug fix: don't do this
1912 % when we're in vertical mode.)
1913 %
1914 %    \begin{macrocode}
1915 \def\@maybe@unskip{\ifhmode\hskip\m@ne\lastskip\relax\fi}
1916 %    \end{macrocode}
1917 %
1918 % \end{macro}
1919 %
1920 % \begin{macro}{\q@delim}
1921 %
1922 % Finally, for the sake of niceness, here's a delimiter token I can use
1923 % for various things.  It's a `quark', for what it's worth (i.e., it expands
1924 % to itself) although I'm not really sure why this is a good thing.  As far
1925 % as I'm concerned, it's important that it has a unique meaning (i.e., that
1926 % it won't be |\ifx|-equal to other things, or something undefined) and that
1927 % it won't be used where I don't expect it to be used.  \TeX\ will loop
1928 % horridly if it tries to expand this, so I don't think that quarks are
1929 % wonderfully clever thing to use.  (Maybe it should really expand to
1930 % something like `\syntax{<quark>"."}', which will rapidly fill \TeX's memory
1931 % if it gets accidentally expanded.  Still, I'll leave it as it is until
1932 % such time as I understand the idea more.)
1933 %
1934 %    \begin{macrocode}
1935 \def\q@delim{\q@delim}
1936 %    \end{macrocode}
1937 %
1938 % \end{macro}
1939 %
1940 %
1941 % \subsection{Parser states}
1942 %
1943 % Now we start on the parser.  It's really simple, deep down.  We progress
1944 % from state to state, extracting tokens from the preamble and building
1945 % command names from them.  Each command calls one of the element-building
1946 % routines, which works out which state it should be in.  We go through each
1947 % of the states in between (see later) doing default things for the ones we
1948 % missed out.
1949 %
1950 % Anyway, here's some symbolic names for the states.  It makes my life
1951 % easier.
1952 %
1953 %    \begin{macrocode}
1954 \chardef\tab@startstate 0
1955 \chardef\tab@loopstate 1
1956 \chardef\tab@rulestate 1
1957 \chardef\tab@prespcstate 2
1958 \chardef\tab@prestate 3
1959 \chardef\tab@colstate 4
1960 \chardef\tab@poststate 5
1961 \chardef\tab@postspcstate 6
1962 \chardef\tab@limitstate 7
1963 %    \end{macrocode}
1964 %
1965 %
1966 % \subsection{Adding things to token lists}
1967 %
1968 % Define some macros for adding stuff to the beginning and end of token
1969 % lists.  This is really easy, actually.  Here we go.
1970 %
1971 %    \begin{macrocode}
1972 \def\tab@append#1#2{#1\expandafter{\the#1#2}}
1973 \def\tab@prepend#1#2{%
1974   \toks@{#2}#1\expandafter{\the\expandafter\toks@\the#1}%
1975 }
1976 %    \end{macrocode}%
1977 %
1978 %
1979 % \subsection{Committing a column to the preamble}
1980 %
1981 % Each time we pass the `rule' state, we `commit' the tokens we've gathered
1982 % so far to the main preamble token list.  This is how we do it.  Note the
1983 % icky use of |\expandafter|.
1984 %
1985 %    \begin{macrocode}
1986 \def\tab@commit{%
1987 %    \end{macrocode}
1988 %
1989 % If this isn't the first column, then we need to put in a column separator.
1990 %
1991 %    \begin{macrocode}
1992   \iftab@firstcol\else%
1993     \expandafter\tab@append\expandafter\tab@preamble%
1994       \expandafter{\tab@tabtext}%
1995   \fi%
1996 %    \end{macrocode}
1997 %
1998 % Now dump in the |\tab@lefttext| material.
1999 %
2000 %    \begin{macrocode}
2001   \expandafter\tab@append\expandafter\tab@preamble%
2002     \expandafter{\tab@lefttext}%
2003 %    \end{macrocode}
2004 %
2005 % Now we spill the token registers into the main list in a funny order (which
2006 % is why we're doing it in this strange way in the first place.
2007 %
2008 %    \begin{macrocode}
2009   \toks@\expandafter{\tab@midtext}%
2010   \tab@preamble\expandafter{%
2011     \the\expandafter\tab@preamble%
2012     \the\expandafter\tab@pretext%
2013     \the\expandafter\tab@userpretext%
2014     \the\expandafter\toks@%
2015     \the\expandafter\tab@posttext%
2016     \tab@righttext%
2017   }%
2018 %    \end{macrocode}
2019 %
2020 % Now reset token lists and things for the next go round.
2021 %
2022 %    \begin{macrocode}
2023   \tab@firstcolfalse%
2024   \tab@pretext{}%
2025   \tab@userpretext{}%
2026   \tab@posttext{}%
2027 }
2028 %    \end{macrocode}
2029 %
2030 %
2031 % \subsection{Playing with parser states}
2032 %
2033 % \begin{macro}{\tab@setstate}
2034 %
2035 % This is how we set new states.  The algorithm is fairly simple, really.
2036 %
2037 % ^^A Let's see how good my TeX really is... ;-)
2038 % ^^A Actually, it doesn't seem to have worked out too badly.  Maybe I should
2039 % ^^A write a package to do this automatically.  It's rather tricky, though.
2040 %
2041 % \def\qq{\mbox{\quad}}
2042 % \sbox{0}{\itshape\textunderscore}\def\_{\usebox{0}}
2043 %
2044 % \begin{quote}
2045 % {\bf while} $\it tab\_state \ne s$ {\bf do} \\
2046 % \qq $\mathit{tab\_state = tab\_state}+1$; \\
2047 % \qq {\bf if} $\it tab\_state = tab\_limitState$ {\bf then}
2048 %                               $\it tab\_state=tab\_loopState$; \\
2049 % \qq {\bf if} $\it tab\_state = tab\_preSpcState$ {\bf then} \\
2050 % \qq \qq {\bf if} $\it tab\_initRule$ {\bf then} \\
2051 % \qq \qq \qq $\it tab\_initRule = {\bf false}$; \\
2052 % \qq \qq {\bf else} \\
2053 % \qq \qq \qq {\bf if} $\it tab\_inMultiCol$ {\bf then moan}; \\
2054 % \qq \qq \qq $\it commit$; \\
2055 % \qq \qq \qq $\it append(tab\_shortLine,\hbox{`|&\omit|')}$; \\
2056 % \qq \qq {\bf end\,if}; \\
2057 % \qq {\bf end\,if}; \\
2058 % \qq {\bf if} $\it tab\_state \ne s$ {\bf then}
2059 %                               $\it do\_default(tab\_state)$; \\
2060 % {\bf end\,while};
2061 % \end{quote}
2062 %
2063 % First we decide if there's anything to do.  If so, we call another macro to
2064 % do it for us.
2065 %
2066 %    \begin{macrocode}
2067 \def\tab@setstate#1{%
2068   \ifnum#1=\tab@state\else%
2069     \def\@tempa{\tab@setstate@i{#1}}%
2070     \@tempa%
2071   \fi%
2072 }
2073 %    \end{macrocode}
2074 %
2075 % This is where the fun is.  First we bump the state by one, and loop back
2076 % if we fall off the end.
2077 %
2078 %    \begin{macrocode}
2079 \def\tab@setstate@i#1{%
2080   \global\advance\tab@state\@ne%
2081   \ifnum\tab@state>\tab@limitstate%
2082     \global\tab@state\tab@loopstate%
2083   \fi%
2084 %    \end{macrocode}
2085 %
2086 % Now, if we've just passed the ruleoff state, we commit the current text
2087 % \emph{unless} this was the strange initial rule at the very beginning.  We
2088 % provide a little hook here so that |\multicolumn| can moan if you try and
2089 % give more than one column there.  We also add another tab/omit pair to the
2090 % list we use for |\vgap|.
2091 %
2092 %    \begin{macrocode}
2093   \ifnum\tab@state=\tab@prespcstate%
2094     \iftab@initrule%
2095       \tab@initrulefalse%
2096     \else%
2097       \tab@looped%
2098       \tab@commit%
2099       \expandafter\tab@append\expandafter\tab@shortline%
2100         \expandafter{\tab@rightruletext}%
2101       \tab@append\tab@shortline{&\omit}%
2102       \expandafter\tab@append\expandafter\tab@shortline%
2103         \expandafter{\tab@leftruletext}%
2104     \fi%
2105   \fi%
2106 %    \end{macrocode}
2107 %
2108 % Now we decide whether to go round again.  If not, we do the default thing
2109 % for this state.  This is mainly here so that we can put the |\tabcolsep| or
2110 % whatever in if the user didn't give an \lit{@} expression.
2111 %
2112 %    \begin{macrocode}
2113   \ifnum#1=\tab@state%
2114     \let\@tempa\relax%
2115   \else%
2116     \csname tab@default@\number\tab@state\endcsname%
2117   \fi%
2118   \@tempa%
2119 }
2120 %    \end{macrocode}
2121 %
2122 % \end{macro}
2123 %
2124 % Now we set up the default actions for the various states.
2125 %
2126 % In state~2 (pre-space) we add in the default gap if either we didn't have
2127 % an \lit{@} expression in the post-space state or there was an explicit
2128 % intervening rule.
2129 %
2130 %    \begin{macrocode}
2131 \@namedef{tab@default@2}{%
2132   \iftab@rule%
2133     \tab@append\tab@pretext{\hskip\col@sep}%
2134   \fi%
2135 }
2136 %    \end{macrocode}
2137 %
2138 % If the user omits the column type, we insert an `l'-type column and moan
2139 % a lot.
2140 %
2141 %    \begin{macrocode}
2142 \@namedef{tab@default@4}{%
2143   \tab@err@misscol%
2144   \tab@append\tab@pretext{\tab@bgroup\relax}%
2145   \tab@append\tab@posttext{\relax\tab@egroup\hfil}%
2146   \tab@append\tab@shortline{\hfil}%
2147   \advance\tab@columns\@ne%
2148 }
2149 %    \end{macrocode}
2150 %
2151 % Finally we deal with the post-space state.  We set a marker so that we
2152 % put in the default space in the pre-space state later too.
2153 %
2154 %    \begin{macrocode}
2155 \@namedef{tab@default@6}{%
2156   \tab@append\tab@posttext{\hskip\col@sep}%
2157   \tab@ruletrue%
2158 }
2159 %    \end{macrocode}
2160 %
2161 %
2162 % \subsection{Declaring token types}
2163 %
2164 % \begin{macro}{\tab@extracol}
2165 %
2166 % Before we start, we need to handle |\extracolsep|.  This is a right pain,
2167 % because the original version of \env{tabular} worked on total expansion,
2168 % which is a Bad Thing.  On the other hand, turning |\extracolsep| into a
2169 % |\tabskip| is also a major pain.
2170 %
2171 %    \begin{macrocode}
2172 \def\tab@extracol#1#2{\tab@extracol@i#1#2\extracolsep{}\extracolsep\end}
2173 \def\tab@extracol@i#1#2\extracolsep#3#4\extracolsep#5\end{%
2174   \ifx @#3@%
2175     \def\@tempa{#1{#2}}%
2176   \else%
2177     \def\@tempa{#1{#2\tabskip#3\relax#4}}%
2178   \fi%
2179   \@tempa%
2180 }
2181 %    \end{macrocode}
2182 %
2183 % \end{macro}
2184 %
2185 % This is where we do the work for inserting preamble elements.
2186 %
2187 % \begin{macro}{\tabruletype}
2188 %
2189 % Inserting rules is interesting, because we have to decide where to put
2190 % them.  If this is the funny initial rule, it goes in the pre-text list,
2191 % otherwise it goes in the post-text list.  We work out what to do first
2192 % thing:
2193 %
2194 %    \begin{macrocode}
2195 \def\tabruletype#1{\tab@extracol\tabruletype@i{#1}}%
2196 \def\tabruletype@i#1{%
2197   \iftab@initrule%
2198     \let\tab@tok\tab@pretext%
2199   \else%
2200     \let\tab@tok\tab@posttext%
2201   \fi%
2202 %    \end{macrocode}
2203 %
2204 % Now if we're already in the rule state, we must have just done a rule.
2205 % This means we must put in the |\doublerulesep| space, both here and in the
2206 % shortline list.  Otherwise we just stick the rule in.
2207 %
2208 % This is complicated, because |\vgap| needs to be able to remove some bits
2209 % of rule.  We pass each one to a macro |\tab@ckr|, together with the column
2210 % number, which is carefully bumped at the right times, and this macro will
2211 % vet the rules and output the appropriate ones.  There's lots of extreme
2212 % |\expandafter| nastiness as a result.  Amazingly, this actually works.
2213 %
2214 %    \begin{macrocode}
2215   \ifnum\tab@state=\tab@rulestate%
2216     \tab@append\tab@tok{\hskip\doublerulesep\begingroup#1\endgroup}%
2217     \expandafter\tab@append\expandafter\tab@shortline\expandafter{%
2218       \expandafter\hskip\expandafter\doublerulesep%
2219       \expandafter\tab@ckr\expandafter{\the\tab@columns}%
2220         {\begingroup#1\endgroup}%
2221     }%
2222   \else%
2223     \tab@setstate\tab@rulestate%
2224     \tab@append\tab@tok{\begingroup#1\endgroup}%
2225     \expandafter\tab@append\expandafter\tab@shortline\expandafter{%
2226       \expandafter\tab@ckr\expandafter{\the\tab@columns}%
2227         {\begingroup#1\endgroup}%
2228     }%
2229   \fi%
2230 %    \end{macrocode}
2231 %
2232 % Finally, we say there was a rule here, so that default space gets put in
2233 % after this.  Otherwise we lose lots of generality.
2234 %
2235 %    \begin{macrocode}
2236   \tab@ruletrue%
2237 }
2238 %    \end{macrocode}
2239 %
2240 % \end{macro}
2241 %
2242 % \begin{macro}{\tabspctype}
2243 %
2244 % We need to work out which space-state we should be in.  Then we just put
2245 % the text in.  Easy, really.
2246 %
2247 %    \begin{macrocode}
2248 \def\tabspctype#1{\tab@extracol\tabspctype@i{#1}}%
2249 \def\tabspctype@i#1{%
2250   \tab@rulefalse%
2251   \ifnum\tab@state>\tab@prespcstate%
2252     \tab@setstate\tab@postspcstate%
2253     \let\tab@tok\tab@posttext%
2254   \else%
2255     \tab@setstate\tab@prespcstate%
2256     \let\tab@tok\tab@pretext%
2257   \fi%
2258   \tab@append\tab@tok{\begingroup#1\endgroup}%
2259 }
2260 %    \end{macrocode}
2261 %
2262 % \end{macro}
2263 %
2264 % \begin{macro}{\tabcoltype}
2265 %
2266 % If we're already in the column state, we bump the state and loop round
2267 % again, to get all the appropriate default behaviour.  We bump the column
2268 % counter, and add the bits of text we were given to appropriate token lists.
2269 % We also add the |\hfil| glue to the shortline list, to space out the rules
2270 % properly.
2271 %
2272 %    \begin{macrocode}
2273 \def\tabcoltype#1#2{%
2274   \ifnum\tab@state=\tab@colstate%
2275     \global\advance\tab@state\@ne%
2276   \fi%
2277   \advance\tab@columns\@ne%
2278   \tab@setstate\tab@colstate%
2279   \tab@append\tab@pretext{#1}%
2280   \tab@append\tab@posttext{#2}%
2281   \tab@append\tab@shortline{\hfil}%
2282 }
2283 %    \end{macrocode}
2284 %
2285 % \end{macro}
2286 %
2287 % \begin{macro}{\tabuserpretype}
2288 % \begin{macro}{\tabuserposttype}
2289 %
2290 % These are both utterly trivial.
2291 %
2292 %    \begin{macrocode}
2293 \def\tabuserpretype#1{%
2294   \tab@setstate\tab@prestate%
2295   \tab@prepend\tab@userpretext{#1}%
2296 }
2297 %    \end{macrocode}
2298 %
2299 %    \begin{macrocode}
2300 \def\tabuserposttype#1{%
2301   \tab@setstate\tab@poststate%
2302   \tab@prepend\tab@posttext{#1}%
2303 }
2304 %    \end{macrocode}
2305 %
2306 % \end{macro}
2307 % \end{macro}
2308 %
2309 %
2310 % \subsection{The colset stack}
2311 %
2312 % Let's start with something fairly easy.  We'll keep a stack of column sets
2313 % so that users don't get confused by package authors changing the current
2314 % column set.  This is fairly easy, really.
2315 %
2316 % \begin{macro}{\tab@push}
2317 % \begin{macro}{\tab@pop}
2318 % \begin{macro}{\tab@head}
2319 %
2320 % These are the stack management routines.  The only important thing to note
2321 % is that |\tab@head| must take place \emph{only} in \TeX's mouth, so we can
2322 % use it in |\csname|\dots|\endcsname| constructions.
2323 %
2324 %    \begin{macrocode}
2325 \def\tab@push#1#2{%
2326   \toks@{{#2}}%
2327   \expandafter\def\expandafter#1\expandafter{\the\expandafter\toks@#1}%
2328 }
2329 \def\tab@pop#1{\edef#1{\expandafter\@gobble#1}}
2330 \def\tab@head#1{\expandafter\tab@head@i#1\relax}
2331 \def\tab@head@i#1#2\relax{#1}
2332 %    \end{macrocode}
2333 %
2334 % \end{macro}
2335 % \end{macro}
2336 % \end{macro}
2337 %
2338 % \begin{macro}{\colset}
2339 % \begin{macro}{\colpush}
2340 % \begin{macro}{\colpop}
2341 %
2342 % Now we can define the user macros.
2343 %
2344 %    \begin{macrocode}
2345 \def\tab@colstack{{tabular}}
2346 \def\colset{\colpop\colpush}
2347 \def\colpush{\tab@push\tab@colstack}
2348 \def\colpop{\tab@pop\tab@colstack}
2349 %    \end{macrocode}
2350 %
2351 % \end{macro}
2352 % \end{macro}
2353 % \end{macro}
2354 %
2355 % \begin{macro}{\tab@colset}
2356 %
2357 % Now we define a shortcut for reading the top item off the stack.
2358 %
2359 %    \begin{macrocode}
2360 \def\tab@colset{\tab@head\tab@colstack}
2361 %    \end{macrocode}
2362 %
2363 % \end{macro}
2364 %
2365 %
2366 % \subsection{The main parser routine}
2367 %
2368 % \begin{macro}{\tab@initread}
2369 %
2370 % This macro sets up lots of variables to their normal states prior to
2371 % parsing a preamble.  Some things may need changing, but not many.  This
2372 % version just sets the major hooks, and then does a subread.  The midtext
2373 % macro contains what to put in the very middle of each template --
2374 % |\multicolumn| will insert its argument here.
2375 %
2376 %    \begin{macrocode}
2377 \def\tab@initread{%
2378   \def\tab@lefttext{}%
2379   \def\tab@leftruletext{}%
2380   \def\tab@righttext{}%
2381   \def\tab@rightruletext{}%
2382   \def\tab@tabtext{&}%
2383   \def\tab@midtext{\ignorespaces####\@maybe@unskip}%
2384   \tab@initsubread%
2385 }
2386 %    \end{macrocode}
2387 %
2388 % \end{macro}
2389 %
2390 % \begin{macro}{\tab@initsubread}
2391 %
2392 % This is where most of the activity is.  We don't replace the left and right
2393 % texts, so that we effectively inherit them rfrom the enclosing
2394 % environment.
2395 %
2396 %    \begin{macrocode}
2397 \def\tab@initsubread{%
2398 %    \end{macrocode}
2399 %
2400 % First, reset the parser state to the start state.
2401 %
2402 %    \begin{macrocode}
2403   \global\tab@state\tab@startstate%
2404 %    \end{macrocode}
2405 %
2406 % We clear the token lists to sensible values, mostly.
2407 %
2408 %    \begin{macrocode}
2409   \tab@preamble{}%
2410   \tab@shortline{}%
2411   \tab@pretext{}%
2412   \tab@userpretext{}%
2413   \tab@posttext{}%
2414   \let\tab@multicol\@empty%
2415   \def\tab@startpause{\penalty\postdisplaypenalty\medskip}%
2416   \def\tab@endpause{\penalty\predisplaypenalty\medskip}%
2417 %    \end{macrocode}
2418 %
2419 % Finally, reset the column counter, don't raise errors when we loop, and set
2420 % some parser flags to their appropriate values.
2421 %
2422 %    \begin{macrocode}
2423   \tab@columns\z@%
2424   \let\tab@looped\relax%
2425   \tab@ruletrue%
2426   \tab@initruletrue%
2427   \tab@firstcoltrue%
2428 }
2429
2430 %    \end{macrocode}
2431 %
2432 % \end{macro}
2433 %
2434 % \begin{macro}{\tab@readpreamble}
2435 %
2436 % This is the main macro for preamble handling.  Actually, all it does is
2437 % gobble its argument's leading brace and call another macro, but it does it
2438 % with style.
2439 %
2440 %    \begin{macrocode}
2441 \def\tab@readpreamble#1{%
2442   \expandafter\tab@append\expandafter\tab@shortline%
2443     \expandafter{\tab@leftruletext}%
2444   \tab@doreadpream{#1}%
2445   \iftab@initrule\global\tab@state\tab@prespcstate\fi%
2446   \tab@setstate\tab@rulestate%
2447   \expandafter\tab@append\expandafter\tab@shortline%
2448     \expandafter{\tab@rightruletext}%
2449   \tab@commit%
2450 }
2451 %    \end{macrocode}
2452 %
2453 % \end{macro}
2454 %
2455 % \begin{macro}{\tab@doreadpream}
2456 %
2457 % The preamble is in an argument.  Previous versions used a nasty trick using
2458 % |\let| and |\afterassignment|.  Now we use an explicit end token, to allow
2459 % dodgy column type handlers to scoop up the remaining preamble tokens
2460 % and process them.  Not that anyone would want to do that, oh no (see
2461 % the \lit{[} type in the \env{eqnarray} environment |;-)|).
2462 %
2463 %    \begin{macrocode}
2464 \def\tab@doreadpream#1{\tab@mkpreamble#1\q@delim}
2465 %    \end{macrocode}
2466 %
2467 % \end{macro}
2468 %
2469 % \begin{macro}{\tab@mkpreamble}
2470 %
2471 % This is the main parser routine.  It takes each token in turn, scrutinises
2472 % it carefully, and does the appropriate thing with it.
2473 %
2474 % The preamble was given as an argument to |\tab@doreadpream|, and that has
2475 % helpfully stripped off the initial |{| character.  We need to pick off the
2476 % next token (whatever it is) so we can examine it.  We'll use |\futurelet|
2477 % so we can detect groups and things in funny places.
2478 %
2479 %    \begin{macrocode}
2480 \def\tab@mkpreamble{\futurelet\@let@token\tab@mkpreamble@i}
2481 %    \end{macrocode}
2482 %
2483 % If we find a space token, we'll go off and do something a bit special,
2484 % since spaces are sort of hard to handle.  Otherwise we'll do it in the old
2485 % fashioned way.
2486 %
2487 %    \begin{macrocode}
2488 \def\tab@mkpreamble@i{%
2489   \ifx\@let@token\@sptoken%
2490     \expandafter\tab@mkpreamble@spc%
2491   \else%
2492     \expandafter\tab@mkpreamble@ii%
2493   \fi%
2494 }
2495 %    \end{macrocode}
2496 %
2497 % If we find a |\@@endpreamble| token, that's it and we're finished.  We just
2498 % gobble it and return.  Otherwise, if it's an open group character, we'll
2499 % complain because someone's probably tried to put an argument in the wrong
2500 % place.  Finally, if none of the other things apply, we'll deal with the
2501 % character below.
2502 %
2503 %    \begin{macrocode}
2504 \def\tab@mkpreamble@ii{%
2505   \ifx\@let@token\q@delim%
2506     \def\@tempa{\let\@let@token}%
2507   \else%
2508     \ifcat\bgroup\noexpand\@let@token%
2509       \tab@err@oddgroup%
2510       \def\@tempa##1{\tab@mkpreamble}%
2511     \else%
2512       \let\@tempa\tab@mkpreamble@iii%
2513     \fi%
2514   \fi%
2515   \@tempa%
2516 }
2517 %    \end{macrocode}
2518 %
2519 % Handle a character.  This involves checking to see if it's actually
2520 % defined, and then doing it.  Doing things this way means we won't get
2521 % stranded in mid-preamble unless a package author has blown it.
2522 %
2523 %    \begin{macrocode}
2524 \def\tab@mkpreamble@iii#1{%
2525   \@ifundefined{\tab@colset!col.\string#1}{%
2526     \tab@err@undef{#1}\tab@mkpreamble%
2527   }{%
2528     \@nameuse{\tab@colset!col.\string#1}%
2529   }%
2530 }
2531 %    \end{macrocode}
2532 %
2533 % If we get given a space character, we'll look up the command name as
2534 % before.  If no-one's defined the column type we'll just skip it silently,
2535 % which lets users do pretty formatting if they like.
2536 %
2537 %    \begin{macrocode}
2538 \@namedef{tab@mkpreamble@spc} {%
2539   \@ifundefined{\tab@colset!col. }{%
2540     \tab@mkpreamble%
2541   }{%
2542     \@nameuse{\tab@colset!col. }%
2543   }%
2544 }
2545 %    \end{macrocode}
2546 %
2547 % \end{macro}
2548 %
2549 % \begin{macro}{\coldef}
2550 %
2551 % Here's how to define column types the nice way.  Some dexterity is required
2552 % to make everything work right, but it's simple really.
2553 %
2554 %    \begin{macrocode}
2555 \def\coldef{\@testopt\coldef@i\tab@colset}
2556 \def\coldef@i[#1]#2#3#{\coldef@ii[#1]{#2}{#3}}
2557 \def\coldef@ii[#1]#2#3#4{%
2558   \expandafter\def\csname#1!col.\string#2\endcsname#3{%
2559     #4\tab@mkpreamble%
2560   }%
2561 }
2562 %    \end{macrocode}
2563 %
2564 % \end{macro}
2565 %
2566 % \begin{macro}{\collet}
2567 %
2568 % We'd like to let people copy column types from other places.  This is how
2569 % to do it.
2570 %
2571 %    \begin{macrocode}
2572 \def\collet{\@testopt\collet@i\tab@colset}
2573 \def\collet@i[#1]#2{%
2574   \@ifnextchar=%
2575     {\collet@ii[#1]{#2}}%
2576     {\collet@ii[#1]{#2}=}%
2577 }
2578 \def\collet@ii[#1]#2={\@testopt{\collet@iii[#1]{#2}}\tab@colset}
2579 \def\collet@iii[#1]#2[#3]#4{%
2580   \expandafter\let\csname#1!col.\string#2\expandafter\endcsname%
2581                   \csname#3!col.\string#4\endcsname%
2582 }
2583 %    \end{macrocode}
2584 %
2585 % \end{macro}
2586 %
2587 % \begin{macro}{\newcolumntype}
2588 %
2589 % We just bundle the text off to |\newcommand| and expect it to cope.  It
2590 % ought to.  The column type code inserts the user's tokens directly, rather
2591 % than calling |\tab@doreadpream| recursively.  The magic control sequence
2592 % is the one looked up by the parser.
2593 %
2594 % There's some additional magic here for compatibility with the obscure way
2595 % that \package{array} works.
2596 %
2597 %    \begin{macrocode}
2598 \def\newcolumntype#1{\@testopt{\nct@i{#1}}0}
2599 \def\nct@i#1[#2]{\@ifnextchar[{\nct@ii{#1}[#2]}{\nct@iii{#1}{[#2]}}}
2600 \def\nct@ii#1[#2][#3]{\nct@iii{#1}{[#2][#3]}}
2601 \def\nct@iii#1#2#3{%
2602   \expandafter\let\csname\tab@colset!col.\string#1\endcsname\relax%
2603   \expandafter\newcommand\csname\tab@colset!col.\string#1\endcsname#2{%
2604     \tab@deepmagic{#1}%
2605     \tab@mkpreamble%
2606     #3%
2607   }%
2608 }
2609 %    \end{macrocode}
2610 %
2611 % Now for some hacking for compatibility with \package{tabularx}.
2612 %
2613 %    \begin{macrocode}
2614 \def\newcol@#1[#2]{\nct@iii{#1}{[#2]}}
2615 %    \end{macrocode}
2616 %
2617 % And now some more.  This is seriously deep magic.  Hence the name.
2618 %
2619 %    \begin{macrocode}
2620 \def\tab@deepmagic#1{%
2621   \csname NC@rewrite@\string#1\endcsname\NC@find\tab@@magic@@%
2622 }
2623 \def\NC@find#1\tab@@magic@@{}
2624 %    \end{macrocode}
2625 %
2626 % \end{macro}
2627 %
2628 %
2629 % \subsection{Standard column types}
2630 %
2631 % First, make sure we're setting up the right columns.  This also sets the
2632 % default for the user.  Other packages must not use the |\colset| command
2633 % for defining columns -- they should use the stack operations defined above.
2634 % For colour support, we ensure that the total stretch in a table cell is
2635 % 1\,fil.
2636 %
2637 %    \begin{macrocode}
2638 \def\tab@halfhfil{\hskip\z@\@plus.5fil\relax}
2639 %    \end{macrocode}
2640 %
2641 % And now on with the show.
2642 %
2643 %    \begin{macrocode}
2644 \colset{tabular}
2645 %    \end{macrocode}
2646 %
2647 % Now do the simple alignment types.  These are fairly simple.  The
2648 % mysterious kern in the \lit{l} type is to stop the |\col@sep| glue from
2649 % vanishing due to the |\unskip| inserted by the standard |\tab@midtext| if
2650 % the column contains no text.  (Thanks for spotting this bug go to that
2651 % nice Mr~Carlisle.)
2652 %
2653 %    \begin{macrocode}
2654 \coldef l{\tabcoltype{\kern\z@\tab@bgroup}{\tab@egroup\hfil}}
2655 \coldef c{\tabcoltype{\tab@halfhfil\tab@bgroup}{\tab@egroup\tab@halfhfil}}
2656 \coldef r{\tabcoltype{\hfil\tab@bgroup}{\tab@egroup}}
2657 %    \end{macrocode}
2658 %
2659 % Some extensions now.  These are explicitly textual or mathematical
2660 % columns.  Can be useful if you're providing column types for other people.
2661 % I've inserted a kern here for exactly the same reason as for the \lit{l}
2662 % column type above.
2663 %
2664 %    \begin{macrocode}
2665 \coldef T#1{\tab@aligncol{#1}{\tab@btext}{\tab@etext}}
2666 \coldef M#1{\tab@aligncol{#1}{\tab@bmaths}{\tab@emaths}}
2667 \def\tab@aligncol#1#2#3{%
2668   \if#1l\tabcoltype{\kern\z@#2}{#3\hfil}\fi%
2669   \if#1c\tabcoltype{\tab@halfhfil#2}{#3\tab@halfhfil}\fi%
2670   \if#1r\tabcoltype{\hfil#2}{#3}\fi%
2671 }
2672 %    \end{macrocode}
2673 %
2674 % Now for the default rules.
2675 %
2676 %    \begin{macrocode}
2677 \coldef ${\@firstoftwo{\tab@withrp\tab@vrule}}
2678 \coldef |{\@firstoftwo{\tab@withrp\tab@vrule[]}}
2679 \def\tab@vrule#1{\tabruletype{#1\vrule\@width\dimen@}\tab@mkpreamble}
2680 \coldef !#1{\tabruletype{#1}}
2681 %    \end{macrocode}
2682 %
2683 % Deal with \lit{@} expressions.
2684 %
2685 %    \begin{macrocode}
2686 \coldef @#1{\tabspctype{#1}}
2687 %    \end{macrocode}
2688 %
2689 % And the paragraph types.  I've added things to handle footnotes here.
2690 %
2691 %    \begin{macrocode}
2692 \coldef p#1{\tabcoltype%
2693              {\savenotes\vtop\tab@bpar{#1}}%
2694              {\tab@epar\spewnotes\hfil}}
2695 \coldef m#1{\tabcoltype%
2696              {\savenotes$\vcenter\tab@bpar{#1}}%
2697              {\tab@epar$\spewnotes\hfil}}
2698 \coldef b#1{\tabcoltype%
2699              {\savenotes\vbox\tab@bpar{#1}}%
2700              {\tab@epar\spewnotes\hfil}}
2701 %    \end{macrocode}
2702 %
2703 % Phew.  Only a few more left now.  The user text ones.
2704 %
2705 %    \begin{macrocode}
2706 \coldef >#1{\tabuserpretype{#1}}
2707 \coldef <#1{\tabuserposttype{#1}}
2708 \coldef ?#1#2{%
2709   \ifx>#1\expandafter\tabuserpretype%
2710   \else\expandafter\tabuserposttype\fi%
2711   {#2}%
2712   \tab@append\tab@shortline{#2}%
2713 }
2714 \coldef '#1{%
2715   \tab@append\tab@shortline{#1}%
2716 }
2717 %    \end{macrocode}
2718 %
2719 % The strange column type.
2720 %
2721 %    \begin{macrocode}
2722 \coldef ##1#2{\tabcoltype{#1}{#2}}
2723 %    \end{macrocode}
2724 %
2725 % And \lit{*}, which repeats a preamble spec.  The tricky part is ensuring
2726 % that nested \lit{*} specs work correctly: we must save the loop counter, in
2727 % |\count 0|, obviously, but \emph{also} the |\iterate| macro built which
2728 % |\loop| modifies internally.  Usually you'd use grouping to fix this, but
2729 % if we introduce a group level then we won't update the preamble registers
2730 % correctly.  Instead, queue up tokens to restore the values in \TeX's input
2731 % list.
2732 %
2733 %    \begin{macrocode}
2734 \coldef *#1#2{%
2735   \toks\tw@\expandafter{\iterate}%
2736   \toks@{%
2737     \count@#1%
2738     \loop\ifnum\count@>0\relax%
2739       \tab@doreadpream{#2}%
2740       \advance\count@\m@ne%
2741     \repeat%
2742   }%
2743   \edef\@tempa{%
2744     \the\toks@%
2745     \def\noexpand\iterate{\the\toks\tw@}%
2746     \count@\the\count@%
2747   }%
2748   \@tempa%
2749 }
2750 %    \end{macrocode}
2751 %
2752 %
2753 % \subsection{Paragraph handling}
2754 %
2755 % First of all, starting new paragraphs: the vbox token is already there, and
2756 % we have the width as an argument.
2757 %
2758 % \begin{macro}{\tab@bpar}
2759 %
2760 % There are some gymnastics to do here to support lists which form the
2761 % complete text of the parbox.  One of the odd things I'll do here is to
2762 % not insert a strut on the first line: instead, I'll put the text into a
2763 % box register so that I can inspect it later.  So that I have access to
2764 % the height of the first line, I'll use a |\vtop| -- I can get at the
2765 % final depth by using |\prevdepth|, so this seems to be the most general
2766 % solution.
2767 %
2768 %    \begin{macrocode}
2769 \def\tab@bpar#1{%
2770   \bgroup%
2771   \setlength\hsize{#1}%
2772   \@arrayparboxrestore%
2773   \setbox\z@\vtop\bgroup%
2774   \global\@minipagetrue%
2775   \global\@noskipsecfalse%
2776   \everypar\expandafter{\the\everypar%
2777     \global\@minipagefalse%
2778     \everypar{}%
2779   }%
2780 }
2781 %    \end{macrocode}
2782 %
2783 % \end{macro}
2784 %
2785 % \begin{macro}{\tab@epar}
2786 %
2787 % To end the paragraph, close the box.  That sounds easy, doesn't it?
2788 % I need to space out the top and bottom of the box so that it looks as if
2789 % struts have been applied.
2790 %
2791 %    \begin{macrocode}
2792 \def\tab@epar{%
2793 %    \end{macrocode}
2794 %
2795 % Anyway, I should end the current paragraph if I'm still in horizontal
2796 % mode.  A simple |\par| will do this nicely.  I'll also remove any trailing
2797 % vertical glue (which may be left there by a list environment), because
2798 % things will look very strange otherwise.
2799 %
2800 %    \begin{macrocode}
2801   \ifhmode\@maybe@unskip\par\fi%
2802   \unskip%
2803 %    \end{macrocode}
2804 %
2805 % Now I'll look at the depth of the last box: if it's less deep than my
2806 % special strut, I'll cunningly backpedal by a bit, and add a box with the
2807 % appropriate depth.  Since this will lie on the previous baseline, it won't
2808 % alter the effective height of the box.  There's a snag here.  |\prevdepth|
2809 % may be wrong for example if the last thing inserted was a rule, or the
2810 % box is just empty.  Check for this specially.  (Thanks to Rowland McDonnell
2811 % for spotting this.)
2812 %
2813 %    \begin{macrocode}
2814   \ifdim\prevdepth>-\@m\p@\ifdim\prevdepth<\dp\@arstrutbox%
2815     \kern-\prevdepth%
2816     \nointerlineskip%
2817     \vtop to\dp\@arstrutbox{}%
2818   \fi\fi%
2819 %    \end{macrocode}
2820 %
2821 % I've finished the bottom of the box now: I'll close it, and start work on
2822 % the top again.
2823 %
2824 %    \begin{macrocode}
2825   \egroup%
2826 %    \end{macrocode}
2827 %
2828 % For top-alignment to work, the first item in the box must be another box.
2829 % (This is why I couldn't just set |\prevdepth| at the beginning.)  If the
2830 % box isn't high enough, I'll add a box of the right height and then kern
2831 % backwards so that the `real' first box ends up in the right place.
2832 %
2833 %    \begin{macrocode}
2834   \ifdim\ht\z@<\ht\@arstrutbox%
2835     \vbox to\ht\@arstrutbox{}%
2836     \kern-\ht\z@%
2837   \fi%
2838   \unvbox\z@%
2839   \egroup%
2840 }
2841 %    \end{macrocode}
2842 %
2843 % \end{macro}
2844 %
2845 %
2846 % \subsection{Gentle persuasion}
2847 %
2848 % To persuade \package{longtable} to work, we emulate some features of
2849 % the \package{array} way of doing things.  It's a shame, but we have to do
2850 % it, because \package{longtable} came first.
2851 %
2852 % Note the horribleness with the grouping here.  In order to get everything
2853 % expanded at the right time, |\@preamble| just replaces itself with the (not
2854 % expanded!) preamble string, using |\the|.  This means that the preamble
2855 % string must be visible in the group just above us.  Now,
2856 % \package{longtable} (and \package{array} for that matter) does
2857 % |\@mkpreamble| immediately after opening a new group.  So all we need to do
2858 % is close that group, do our stuff, and reopen the group again.  (Evil
2859 % laughter\dots)
2860 %
2861 %    \begin{macrocode}
2862 \def\@mkpream#1{%
2863   \endgroup%
2864   \colset{tabular}%
2865   \tab@initread%
2866   \def\tab@multicol{\@arstrut}%
2867   \tab@preamble{\tab@multicol}%
2868   \let\tab@lefttext\tab@lefttexthook%
2869   \let\tab@righttext\tab@righttexthook%
2870   \let\tab@leftruletext\tab@leftruletexthook%
2871   \let\tab@rightruletext\tab@rightruletexthook%
2872   \def\tab@midtext{\tab@setcr\ignorespaces\@sharp\@sharp\@maybe@unskip}%
2873   \tab@readpreamble{#1}%
2874   \gdef\@preamble{\the\tab@preamble}%
2875   \let\tab@bgroup\begingroup%
2876   \let\tab@egroup\endgroup%
2877   \begingroup%
2878 }
2879 %    \end{macrocode}
2880 %
2881 % \subsection{Debugging}
2882 %
2883 % This macro just parses a preamble and displays it on the terminal.  It
2884 % means I can see whether the thing's working.
2885 %
2886 %    \begin{macrocode}
2887 \def\showpream#1{%
2888   \tab@initread%
2889   \tab@readpreamble{#1}%
2890   \showthe\tab@preamble%
2891   \showthe\tab@shortline%
2892 }
2893 %    \end{macrocode}
2894 %
2895 % A quick macro for showing column types.
2896 %
2897 %    \begin{macrocode}
2898 \def\showcol#1{%
2899   \expandafter\show\csname\tab@colset!col.\string#1\endcsname%
2900 }
2901 %    \end{macrocode}
2902 %
2903 %
2904 % \subsection{The \env{tabular} and \env{array} environments}
2905 %
2906 % This is where we define the actual environments which users play with.
2907 %
2908 % \subsubsection{The environment routines}
2909 %
2910 % The real work is done in the |\@array| macro later.  We just set up lots
2911 % (and I mean \emph{lots}) of parameters first, and then call |\@array|.
2912 %
2913 % \begin{macro}{\tab@array}
2914 %
2915 % The |\tab@array| macro does most of the common array things.
2916 %
2917 %    \begin{macrocode}
2918 \def\tab@array{%
2919   \tab@width\z@%
2920   \let\tab@bgroup\tab@bmaths%
2921   \let\tab@egroup\tab@emaths%
2922   \@tabarray%
2923 }
2924 %    \end{macrocode}
2925 %
2926 % \end{macro}
2927 %
2928 % \begin{macro}{\tab@btext}
2929 % \begin{macro}{\tab@bmaths}
2930 % \begin{macro}{\tab@etext}
2931 % \begin{macro}{\tab@emaths}
2932 %
2933 % These macros contain appropriate things to use when typesetting
2934 % text or maths macros.  They're all trivial.  They're here only for
2935 % later modification by funny things like the \env{smarray} environment.
2936 %
2937 %    \begin{macrocode}
2938 \def\tab@btext{\begingroup}
2939 \def\tab@bmaths{\color@begingroup$}
2940 \def\tab@etext{\endgroup}
2941 \def\tab@emaths{\m@th$\color@endgroup}
2942 %    \end{macrocode}
2943 %
2944 % \end{macro}
2945 % \end{macro}
2946 % \end{macro}
2947 % \end{macro}
2948 %
2949 % \begin{environment}{array}
2950 %
2951 % Now for the \env{array} environment.  The `|$|' signs act as a group, so we
2952 % don't need to do extra grouping this time.  Closing the environment is
2953 % easy.
2954 %
2955 %    \begin{macrocode}
2956 \def\array{%
2957   \col@sep\arraycolsep%
2958   \let\tab@extrasep\arrayextrasep%
2959   \tab@normalstrut%
2960   \tab@array%
2961 }
2962 \def\endarray{%
2963   \crcr%
2964   \egroup%
2965   \tab@right%
2966   \endgroup%
2967   \tab@restorehlstate%
2968   \global\c@tabrow\count@%
2969   \def\@currentlabel{\p@tabrow\thetabrow}%
2970   \tab@endhook%
2971 }
2972 %    \end{macrocode}
2973 %
2974 % \end{environment}
2975 %
2976 % \begin{environment}{smarray}
2977 %
2978 % Now for something a little different.  The \env{smarray} environment
2979 % gives you an array with lots of small text.
2980 %
2981 %    \begin{macrocode}
2982 \def\smarray{%
2983   \extrarowheight\z@%
2984   \col@sep\smarraycolsep%
2985   \let\tab@extrasep\smarrayextrasep%
2986   \def\tab@bmaths{\color@begingroup$\scriptstyle}%
2987   \def\tab@btext{\begingroup\scriptsize}%
2988   \setbox\z@\hbox{\scriptsize\strut}%
2989   \dimen@\ht\z@\dimen@ii\dp\z@\tab@setstrut%
2990   \tab@array%
2991 }
2992 \let\endsmarray\endarray
2993 %    \end{macrocode}
2994 %
2995 % \end{environment}
2996 %
2997 % \begin{macro}{\tabstyle}
2998 %
2999 % This is a little hook that document designers can use to modify the
3000 % appearance of tables throughout a document.  For example, I've set it to
3001 % make the text size |\small| in all tables in this document.  Macro writers
3002 % shouldn't try to use it as a hook for their own evilness, though.  I've
3003 % used |\providecommand| to avoid nobbling an existing definition.
3004 %
3005 %    \begin{macrocode}
3006 \providecommand\tabstyle{}
3007 %    \end{macrocode}
3008 %
3009 % \end{macro}
3010 %
3011 % \begin{macro}{\@tabular}
3012 %
3013 % The two \env{tabular} environments share lots of common code, so we
3014 % separate that out.  (This needs to be done better.)  All we really do here
3015 % is set up the |\tab@bgroup| and |\tab@egroup| to localise things properly,
3016 % and then go.
3017 %
3018 %    \begin{macrocode}
3019 \def\@tabular#1{%
3020   \tabstyle%
3021   \setlength\tab@width{#1}%
3022   \let\tab@bgroup\tab@btext%
3023   \let\tab@egroup\tab@etext%
3024   \col@sep\tabcolsep%
3025   \let\tab@extrasep\tabextrasep%
3026   \tab@normalstrut%
3027   \@tabarray%
3028 }
3029 %    \end{macrocode}
3030 %
3031 % \end{macro}
3032 %
3033 % \begin{environment}{tabular}
3034 % \begin{environment}{tabular*}
3035 %
3036 % These environments just call a macro which does all the common stuff.
3037 %
3038 %    \begin{macrocode}
3039 \def\tabular{\@tabular\z@}
3040 \expandafter\let\csname tabular*\endcsname\@tabular
3041 \let\endtabular\endarray
3042 \expandafter\let\csname endtabular*\endcsname\endarray
3043 %    \end{macrocode}
3044 %
3045 % \end{environment}
3046 % \end{environment}
3047 %
3048 % \subsubsection{Setting the strut height}
3049 %
3050 % \begin{macro}{\tab@setstrut}
3051 %
3052 % We use a magical strut, called |\@arstrut|, which keeps the table from
3053 % collapsing around our heads.  This is where we set it up.
3054 %
3055 % It bases the array strut size on the given values of |\dimen@| and
3056 % |\dimen@ii|, amended by various appropriate fiddle values added in by
3057 % various people.
3058 %
3059 %    \begin{macrocode}
3060 \def\tab@setstrut{%
3061   \setbox\@arstrutbox\hbox{%
3062     \vrule%
3063       \@height\arraystretch\dimen@%
3064       \@depth\arraystretch\dimen@ii%
3065       \@width\z@%
3066   }%
3067 }
3068 %    \end{macrocode}
3069 %
3070 % \end{macro}
3071 %
3072 % \begin{macro}{\tab@normalstrut}
3073 %
3074 % This sets the strut the normal way, from the size of |\strutbox|.
3075 %
3076 %    \begin{macrocode}
3077 \def\tab@normalstrut{%
3078   \dimen@\ht\strutbox\advance\dimen@\extrarowheight%
3079   \dimen\tw@\dp\strutbox%
3080   \tab@setstrut%
3081 }
3082 %    \end{macrocode}
3083 %
3084 % \end{macro}
3085 %
3086 % \subsubsection{Setting up the alignment}
3087 %
3088 % The following bits are mainly for other packages to hook themselves onto.
3089 %
3090 %    \begin{macrocode}
3091 \let\@arrayleft\relax
3092 \let\@arrayright\relax
3093 \let\tab@beginhook\@empty
3094 \let\tab@lefttexthook\@empty
3095 \let\tab@righttexthook\@empty
3096 \let\tab@leftruletexthook\@empty
3097 \let\tab@rightruletexthook\@empty
3098 \let\tab@endhook\@empty
3099 %    \end{macrocode}
3100 %
3101 % For setting these hooks, we provide some handy commands.
3102 %
3103 %    \begin{macrocode}
3104 \def\tab@addhookbefore#1#2{%
3105   \toks@{#2}\toks@\expandafter{\the\expandafter\toks@#1}%
3106   \edef#1{\the\toks@}%
3107 }
3108 \def\tab@addhookafter#1#2{%
3109   \toks@\expandafter{#1#2}%
3110   \edef#1{\the\toks@}%
3111 }
3112 %    \end{macrocode}
3113 %
3114 % And now we get on with the real thing.
3115 %
3116 %    \begin{macrocode}
3117 \def\@tabarray{%
3118   \let\@arrayleft\relax%
3119   \let\@arrayright\relax%
3120   \@testopt\@array c%
3121 }
3122 %    \end{macrocode}
3123 %
3124 % \begin{macro}{\@array}
3125 %
3126 % The |\@array| macro does most of the real work for the environments.  The
3127 % first job is to set up the row strut, which keeps the table rows at the
3128 % right height.  We just take the normal strut box, and extend its height by
3129 % the |\extrarowheight| length parameter.
3130 %
3131 %    \begin{macrocode}
3132 \def\@array[#1]#2{%
3133 %    \end{macrocode}
3134 %
3135 % Sort out the hline state variable.  We'll store the old value in a
3136 % control sequence to avoid wasting any more count registers.
3137 %
3138 %    \begin{macrocode}
3139   \tab@beginhook%
3140   \count@\c@tabrow%
3141   \global\c@tabrow\z@%
3142   \edef\tab@restorehlstate{%
3143     \global\tab@endheight\the\tab@endheight%
3144     \gdef\noexpand\tab@hlstate{\tab@hlstate}%
3145   }%
3146   \begingroup%
3147   \def\tab@hlstate{n}%
3148 %    \end{macrocode}
3149 %
3150 % Now we read the preamble.  All the clever things we've already done are
3151 % terribly useful here.
3152 %
3153 % The |\tab@setcr| sets up |\\| to be a newline even if users have changed it
3154 % using something like |\raggedright|.
3155 %
3156 %    \begin{macrocode}
3157   \colset{tabular}%
3158   \tab@initread%
3159   \let\tab@lefttext\tab@lefttexthook%
3160   \let\tab@righttext\tab@righttexthook%
3161   \let\tab@leftruletext\tab@leftruletexthook%
3162   \let\tab@rightruletext\tab@rightruletexthook%
3163   \def\tab@midtext{\tab@setcr\ignorespaces####\@maybe@unskip}%
3164   \def\tab@multicol{\@arstrut\tab@startrow}%
3165   \tab@preamble{\tab@multicol\tabskip\z@skip}%
3166   \tab@readpreamble{#2}%
3167 %    \end{macrocode}
3168 %
3169 % Set up the default tabskip glue.  This is easy: there isn't any.
3170 %
3171 %    \begin{macrocode}
3172   \tab@leftskip\z@skip%
3173   \tab@rightskip\z@skip%
3174 %    \end{macrocode}
3175 %
3176 % Now set up the positioning of the table.  This is put into a separate macro
3177 % because it's rather complicated.
3178 %
3179 %    \begin{macrocode}
3180   \tab@setposn{#1}%
3181 %    \end{macrocode}
3182 %
3183 % Now work out how to start the alignment.
3184 %
3185 %    \begin{macrocode}
3186   \ifdim\tab@width=\z@%
3187     \def\tab@halign{}%
3188   \else%
3189     \def\tab@halign{to\tab@width}%
3190   \fi%
3191 %    \end{macrocode}
3192 %
3193 % Finally, do all the normal things we need to do before an alignment.  Note
3194 % that we define |\tabularnewline| first, then set |\\| from that (using
3195 % |\tab@setcr|).  Since |\\| is reset in the |\tab@midtext| of every table
3196 % cell, it becomes secondary to |\tabularnewline|.  Doing things this way
3197 % avoids the problems with declarations like |\raggedright| which redefine
3198 % |\\| in their own (usually rather strange) way, so you don't need to mess
3199 % about with things like the |\PreserveBackslash| command given in the
3200 % \textit{\LaTeX\ Companion}.
3201 %
3202 %    \begin{macrocode}
3203   \lineskip\z@\baselineskip\z@%
3204   \m@th%
3205   \def\tabularnewline{\tab@arraycr\tab@penalty}%
3206   \tab@setcr%
3207   \let\par\@empty%
3208   \everycr{}\tabskip\tab@leftskip%
3209   \tab@left\halign\tab@halign\expandafter\bgroup%
3210     \the\tab@preamble\tabskip\tab@rightskip\cr%
3211 }
3212 %    \end{macrocode}
3213 %
3214 % \end{macro}
3215 %
3216 % You've no doubt noticed the |\tab@left| and |\tab@right| macros above.
3217 % These are set up here and elsewhere to allow other things to gain control
3218 % at various points of the table (they include and take the place of the
3219 % |\@arrayleft| and |\@arrayright| hooks in \package{array}, put in for
3220 % \package{delarray}'s use.
3221 %
3222 % \subsubsection{Positioning the table}
3223 %
3224 % \begin{macro}{\tab@setposn}
3225 %
3226 % This macro sets everything up for the table's positioning.  It's rather
3227 % long, but not all that complicated.  Honest.
3228 %
3229 % First, we set up some defaults (for centring).  If anything goes wrong, we
3230 % just do the centring things.
3231 %
3232 %    \begin{macrocode}
3233 \def\tab@setposn#1{%
3234   \def\tab@left{%
3235     \savenotes%
3236     \leavevmode\hbox\bgroup$\@arrayleft\vcenter\bgroup%
3237   }%
3238   \def\tab@right{%
3239     \egroup%
3240     \m@th\@arrayright$\egroup%
3241     \spewnotes%
3242   }%
3243   \global\tab@endheight\z@%
3244 %    \end{macrocode}
3245 %
3246 % For the standard positioning things, we just do appropriate boxing things.
3247 % Note that the dollar signs are important, since \package{delarray} might
3248 % want to put its delimiters in here.
3249 %
3250 % The |\if@tempswa| switch it used to decide if we're doing an unboxed
3251 % tabular.  We'll set it if we find an unbox-type position code, and then
3252 % check that everything's OK for this.
3253 %
3254 %    \begin{macrocode}
3255   \@tempswafalse%
3256   \let\tab@penalty\relax%
3257   \if#1t%
3258     \def\tab@left{%
3259       \savenotes%
3260       \leavevmode\setbox\z@\hbox\bgroup$\@arrayleft\vtop\bgroup%
3261     }%
3262     \def\tab@right{%
3263       \egroup%
3264       \m@th\@arrayright$\egroup%
3265       \tab@raisebase%
3266       \spewnotes%
3267     }%
3268     \gdef\tab@hlstate{t}%
3269     \global\tab@endheight\ht\@arstrutbox%
3270   \else\if#1b%
3271     \def\tab@left{%
3272       \savenotes%
3273       \leavevmode\setbox\z@\hbox\bgroup$\@arrayleft\vbox\bgroup%
3274     }%
3275     \def\tab@right{%
3276       \egroup%
3277       \m@th\@arrayright$\egroup%
3278       \tab@lowerbase%
3279       \spewnotes%
3280     }%
3281     \gdef\tab@hlstate{b}%
3282   \else%
3283     \if#1L\@tempswatrue\fi%
3284     \if#1C\@tempswatrue\fi%
3285     \if#1R\@tempswatrue\fi%
3286   \fi\fi%
3287 %    \end{macrocode}
3288 %
3289 % Now for some tests to make sure we're allowed to do the unboxing.  We text
3290 % for |\@arrayleft| being defined, because people trying to hook us won't
3291 % understand unboxed tabulars.
3292 %
3293 %    \begin{macrocode}
3294   \if@tempswa\ifhmode%
3295     \ifinner\tab@err@unbrh\@tempswafalse\else\par\fi%
3296   \fi\fi%
3297   \if@tempswa\ifmmode\tab@err@unbmm\@tempswafalse\fi\fi%
3298   \if@tempswa\ifx\@arrayleft\relax\else%
3299     \tab@err@unbext\@tempswafalse%
3300   \fi\fi%
3301 %    \end{macrocode}
3302 %
3303 % Finally, if we're still doing an unboxed alignment, we need to sort out the
3304 % spacing.  We know that no-one's tried to hook on to the environment, so we
3305 % clear |\tab@left| and |\tab@right|.
3306 %
3307 %    \begin{macrocode}
3308   \if@tempswa%
3309     \def\tab@left{\vskip\parskip\medskip}%
3310     \def\tab@right{\par\@endpetrue\global\@ignoretrue}%
3311 %    \end{macrocode}
3312 %
3313 % Now we need to sort out the alignment.  The only way we can do this is by
3314 % playing with tabskip glue.  There are two possibilities:
3315 %
3316 % \begin{itemize}
3317 %
3318 % \item If this is a straight \env{tabular} or an \env{array}, we just use
3319 %       infinite glue.  This is reasonable, I think.
3320 %
3321 % \item If we have a width for the table, we calculate the fixed values of
3322 %       glue on either side.  This is fairly easy, and forces the table to
3323 %       the required width.
3324 %
3325 % \end{itemize}
3326 %
3327 % First, set up the left and right glues to represent the prevailing
3328 % margins set up by \env{list} environments.  I think this is the right
3329 % thing to do.
3330 %
3331 %    \begin{macrocode}
3332     \tab@leftskip\@totalleftmargin%
3333     \tab@rightskip\hsize%
3334     \advance\tab@rightskip-\linewidth%
3335     \advance\tab@rightskip-\@totalleftmargin%
3336 %    \end{macrocode}
3337 %
3338 % First of all, deal with the simple case.  I'm using 10000\,fill glue here,
3339 % in an attempt to suppress |\extracolsep| glue from making the table the
3340 % wrong width.  It can always use filll glue if it really needs to, though.
3341 %
3342 %    \begin{macrocode}
3343     \ifdim\tab@width=\z@%
3344       \if#1L\else\advance\tab@leftskip\z@\@plus10000fill\fi%
3345       \if#1R\else\advance\tab@rightskip\z@\@plus10000fill\fi%
3346 %    \end{macrocode}
3347 %
3348 % Now for the fun bit.  This isn't too hard really.  The extra space I must
3349 % add around the table adds up to $|\linewidth| - |\tab@width|$.  I just
3350 % need to add this onto the appropriate sides of the table.
3351 %
3352 %    \begin{macrocode}
3353     \else%
3354       \dimen@\linewidth%
3355       \advance\dimen@-\tab@width%
3356       \if#1L\advance\tab@rightskip\dimen@\fi%
3357       \if#1R\advance\tab@leftskip\dimen@\fi%
3358       \if#1C%
3359         \advance\tab@leftskip.5\dimen@%
3360         \advance\tab@rightskip.5\dimen@%
3361       \fi%
3362     \fi%
3363 %    \end{macrocode}
3364 %
3365 % Don't allow page breaks.  David Carlisle's wonderful \env{longtable}
3366 % package does page breaks far better than I could possibly do here, and
3367 % we're compatible with it (wahey!).
3368 %
3369 %    \begin{macrocode}
3370     \def\tab@penalty{\penalty\@M}%
3371 %    \end{macrocode}
3372 %
3373 % Finally, set the new width of the table, and leave.
3374 %
3375 %    \begin{macrocode}
3376     \tab@width\hsize%
3377   \fi%
3378 }
3379 %    \end{macrocode}
3380 %
3381 % \end{macro}
3382 %
3383 % \subsubsection{Handling tops and bottoms}
3384 %
3385 % This is how the tops and bottoms of tables are made to line up with the
3386 % text on the same line, in the presence of arbitrary rules and space.  The
3387 % old method, based on the way the \package{array} package worked, wasn't
3388 % terribly good.  This new version copes much better with almost anything
3389 % that gets thrown at it.
3390 %
3391 % I'll keep a state in a macro (|\tab@hlstate|), which tells me what I'm
3392 % meant to be doing.  The possible values are \lit{n}, which means I don't
3393 % have to do anything, \lit{t}, which means that I'm meant to be handling
3394 % top-aligned tables, and \lit{b}, which means that I'm meant to be lining
3395 % up the bottom.  There are several other `substates' which have various
3396 % magic meanings.
3397 %
3398 %    \begin{macrocode}
3399 \def\tab@hlstate{n}
3400 %    \end{macrocode}
3401 %
3402 % When all's said and done, I extract the box containing the table, and
3403 % play with the height and depth to try and make it correct.
3404 %
3405 % \begin{macro}{\tab@addruleheight}
3406 %
3407 % This macro is called by `inter-row' things to add their height to our
3408 % dimen register.
3409 %
3410 % Only do this if the state indicates that it's sensible.
3411 %
3412 %    \begin{macrocode}
3413 \def\tab@addruleheight#1{%
3414   \if\tab@hlstate n\else%
3415     \global\advance\tab@endheight#1\relax%
3416   \fi%
3417 }
3418 %    \end{macrocode}
3419 %
3420 % \end{macro}
3421 %
3422 % \begin{macro}{\tab@startrow}
3423 %
3424 % This is called at the start of a row, from within the array preamble.
3425 % Currently, this assumes that the rows aren't bigger than their struts:
3426 % this is reasonable, although slightly limiting, and it could be done better
3427 % if I was willing to rip the alignment apart and put it back together
3428 % again.
3429 %
3430 %    \begin{macrocode}
3431 \def\tab@startrow{%
3432   \if\tab@hlstate t%
3433     \gdef\tab@hlstate{n}%
3434   \else\if\tab@hlstate b%
3435     \global\tab@endheight\dp\@arstrutbox%
3436   \fi\fi%
3437 }
3438 %    \end{macrocode}
3439 %
3440 % \end{macro}
3441 %
3442 % \begin{macro}{\tab@raisebase}
3443 %
3444 % This macro is called at the end of it all, to set the height and depth
3445 % of the box correctly.  It sets the height to |\tab@endheight|, and the
3446 % depth to everything else.  The box is in |\box|~0 currently.
3447 %
3448 %    \begin{macrocode}
3449 \def\tab@raisebase{%
3450   \global\advance\tab@endheight-\ht\z@%
3451   \raise\tab@endheight\box\z@%
3452 }
3453 %    \end{macrocode}
3454 %
3455 % \end{macro}
3456 %
3457 % \begin{macro}{\tab@lowerbase}
3458 %
3459 % And, for symmetry's sake, here's how to set the bottom properly instead.
3460 %
3461 %    \begin{macrocode}
3462 \def\tab@lowerbase{%
3463   \global\advance\tab@endheight-\dp\z@%
3464   \lower\tab@endheight\box\z@%
3465 }
3466 %    \end{macrocode}
3467 %
3468 % \end{macro}
3469 %
3470 %
3471 % \subsection{Breaking tables into bits}
3472 %
3473 % Unboxed tables have a wonderful advantage over boxed ones: you can stop
3474 % halfway through and do something else for a bit.  Here's how:
3475 %
3476 % \begin{macro}{\tabpause}
3477 %
3478 % I'd like to avoid forbidding catcode changes here.  I'll use |\doafter|
3479 % now I've got it, to ensure that colour handling and things occur
3480 % \emph{inside} the |\noalign| (otherwise they'll mess up the alignment
3481 % very seriously).  We selectively include lots of stuff from
3482 % |\arrayparboxrestore|.
3483 %
3484 % We have to be careful here to ensure that everything works correctly within
3485 % lists.  (The \package{amsmath} package had this problem in its
3486 % |\intertext| macro, so I'm not alone here.)
3487 %
3488 %    \begin{macrocode}
3489 \def\tabpause#{%
3490   \noalign{\ifnum0=`}\fi%
3491   \let\if@nobreak\iffalse
3492   \let\if@noskipsec\iffalse
3493   \let\par\@@par
3494   \let\-\@dischyph
3495   \let\'\@acci\let\`\@accii\let\=\@acciii
3496   \everypar{}%
3497   \lineskip\normallineskip%
3498   \let\\\@normalcr%
3499   \color@begingroup%
3500   \tab@startpause%
3501   \vskip-\parskip%
3502   \parshape\@ne\@totalleftmargin\linewidth%
3503   \noindent%
3504   \doafter\tabpause@i%
3505 }
3506 \def\tabpause@i{%
3507   \nobreak%
3508   \tab@endpause%
3509   \color@endgroup%
3510   \ifnum0=`{\fi}%
3511 }
3512 %    \end{macrocode}
3513 %
3514 % \end{macro}
3515 %
3516 %
3517 % \subsection{The wonderful world of \cmd\multicolumn}
3518 %
3519 % \begin{macro}{\multicolumn}
3520 %
3521 % This is actually fantastically easy.  Watch and learn.  Make sure you
3522 % notice the |\long|s here: remember that some table cells can contain
3523 % paragraphs, so it seems sensible to allow |\par| into the argument.
3524 % (As far as I know, most other |\multicolumn| commands don't do this,
3525 % which seems a little silly.  Then again, I forgot to do it the first
3526 % time around.)
3527 %
3528 % Again, we have a sneaky |\kern| to prevent the final |\tabcolsep| glue from
3529 % being eaten by a later |\unskip|.
3530 %
3531 %    \begin{macrocode}
3532 \long\def\multicolumn#1#2#3{%
3533   \multispan{#1}%
3534   \begingroup%
3535     \tab@multicol%
3536     \tab@initsubread%
3537     \long\def\tab@midtext{#3}%
3538     \let\tab@looped\tab@err@multi%
3539     \tab@readpreamble{#2}%
3540     \the\tab@preamble%
3541     \kern\z@%
3542   \endgroup%
3543   \ignorespaces%
3544 }
3545 %    \end{macrocode}
3546 %
3547 % \end{macro}
3548 %
3549 %
3550 % \subsection{Interlude: range lists}
3551 %
3552 % For processing arguments to |\vgap| and |\cline|, we need to be able to
3553 % do things with lists of column ranges.  To save space, and to make my
3554 % fingers do less typing, here's some routines which do range handling.
3555 %
3556 % \begin{macro}{\ranges}
3557 %
3558 % Given a macro name and a comma separated list of ranges and simple numbers,
3559 % this macro will call the macro giving it each range in the list in turn.
3560 % Single numbers~$n$ will be turned into ranges $n$--$n$.
3561 %
3562 % The first job is to read the macro to do (which may already have some
3563 % arguments attached to it).  We'll also start a group to make sure that
3564 % our changes to temp registers don't affect anyone else.
3565 %
3566 % There's a space before the delimiting |\q@delim| to stop numbers being
3567 % parsed to far and expanding our quark (which will stop \TeX\ dead in its
3568 % tracks).  Since we use |\@ifnextchar| to look ahead, spaces in range lists
3569 % are perfectly all right.
3570 %
3571 %    \begin{macrocode}
3572 \def\ranges#1#2{%
3573   \gdef\ranges@temp{#1}%
3574   \begingroup%
3575   \ranges@i#2 \q@delim%
3576 }
3577 %    \end{macrocode}
3578 %
3579 %
3580 % We're at the beginning of the list.  We expect either the closing marker
3581 % (if this is an empty list) or a number, which we can scoop up into a
3582 % scratch register.
3583 %
3584 %    \begin{macrocode}
3585 \def\ranges@i{%
3586   \@ifnextchar\q@delim\ranges@done{\afterassignment\ranges@ii\count@}%
3587 }
3588 %    \end{macrocode}
3589 %
3590 % We've read the first number in the range.  If there's another number, we'll
3591 % expect a `|-|' sign to be next.  If there is no `|-|', call the user's code
3592 % with the number duplicated and then do the rest of the list.
3593 %
3594 %    \begin{macrocode}
3595 \def\ranges@ii{%
3596   \@ifnextchar-\ranges@iii{\ranges@do\count@\count@\ranges@v}%
3597 }
3598 %    \end{macrocode}
3599 %
3600 % Now we strip the `|-|' off and read the other number into a temporary
3601 % register.
3602 %
3603 %    \begin{macrocode}
3604 \def\ranges@iii-{\afterassignment\ranges@iv\@tempcnta}
3605 %    \end{macrocode}
3606 %
3607 % We have both ends of the range now, so call the user's code, passing it
3608 % both ends of the range.
3609 %
3610 %    \begin{macrocode}
3611 \def\ranges@iv{\ranges@do\count@\@tempcnta\ranges@v}
3612 %    \end{macrocode}
3613 %
3614 % We've finished doing an item now.  If we have a `|,|' next, then start
3615 % over with the next item.  Otherwise, if we're at the end of the list,
3616 % we can end happily.  Finally, if we're totally confused, raise an
3617 % error.
3618 %
3619 %    \begin{macrocode}
3620 \def\ranges@v{%
3621   \@ifnextchar,%
3622     \ranges@vi%
3623     {%
3624       \@ifnextchar\q@delim%
3625         \ranges@done%
3626         {\tab@err@range\ranges@vi,}%
3627     }%
3628 }
3629 %    \end{macrocode}
3630 %
3631 % We had a comma, so gobble it, read the next number, and go round again.
3632 %
3633 %    \begin{macrocode}
3634 \def\ranges@vi,{\afterassignment\ranges@ii\count@}
3635 %    \end{macrocode}
3636 %
3637 % Here's how we call the user's code, now.  We close the group, so that the
3638 % user's code doesn't have to do global things to remember its results, and
3639 % we expand the two range ends from their count registers.  We also ensure
3640 % that the range is the right way round.
3641 %
3642 %    \begin{macrocode}
3643 \def\ranges@do#1#2{%
3644   \ifnum#1>#2\else%
3645     \expandafter\endgroup%
3646     \expandafter\ranges@temp%
3647     \expandafter{%
3648     \the\expandafter#1%
3649     \expandafter}%
3650     \expandafter{%
3651     \the#2%
3652     }%
3653     \begingroup%
3654   \fi%
3655 }
3656 %    \end{macrocode}
3657 %
3658 % And finishing the scan is really easy.  We close the group after gobbling
3659 % the close token.
3660 %
3661 %    \begin{macrocode}
3662 \def\ranges@done\q@delim{\endgroup}
3663 %    \end{macrocode}
3664 %
3665 % \end{macro}
3666 %
3667 % \begin{macro}{\ifinrange}
3668 %
3669 % Something a little more useful, now.  |\ifinrange| takes four arguments:
3670 % a number, a range list (as above), and two token lists which I'll call
3671 % \emph{then} and \emph{else}.  If the number is in the list, I'll do
3672 % \emph{then}, otherwise I'll do \emph{else}.
3673 %
3674 %    \begin{macrocode}
3675 \def\ifinrange#1#2{%
3676   \@tempswafalse%
3677   \count@#1%
3678   \ranges\ifinrange@i{#2}%
3679   \if@tempswa%
3680     \expandafter\@firstoftwo%
3681   \else%
3682     \expandafter\@secondoftwo%
3683   \fi%
3684 }
3685 \def\ifinrange@i#1#2{%
3686   \ifnum\count@<#1 \else\ifnum\count@>#2 \else\@tempswatrue\fi\fi%
3687 }
3688 %    \end{macrocode}
3689 %
3690 % \end{macro}
3691 %
3692 %
3693 % \subsection{Horizontal rules OK}
3694 %
3695 % This is where all the gubbins for |\vgap| and friends is kept, lest it
3696 % contaminate fairly clean bits of code found elsewhere.
3697 %
3698 % \subsubsection{Common parsing for rule parameters twiddling}
3699 %
3700 % \begin{macro}{\tab@ruleparams}
3701 %
3702 % Given a macro name, make a (global) macro |\tab@ruledecls|, which sets
3703 % |\dimen0| to be the chosen rule thickness, and sets up colours and whatnot,
3704 % and then and calls the macro.  We parse a `|*|' to mean
3705 % |\arraythickrulewidth|, an optional argument which should be something
3706 % |\setlength| can understand, or nothing, which gives the default
3707 % |\arrayrulewidth|.
3708 %
3709 % To make this properly hookable, we need to make a list of properties and
3710 % gather them together.
3711 %
3712 %    \begin{macrocode}
3713 \let\tab@rp@inithook\@empty
3714 \let\tab@rp@sethook\@empty
3715 \let\tab@rp@donehook\@empty
3716 \let\tab@rp@default\@empty
3717 \def\tab@ruleparams#1{%
3718   {\ifnum0=`}\fi%
3719   \tab@rp@inithook%
3720   \def\tab@rp@next{\ifnum0=`{\fi}#1}%
3721   \expandafter\tab@rp@keys\expandafter{\tab@rp@default}%
3722   \@ifstar\tab@rp@star\tab@rp@what%
3723 }
3724 \def\tab@rp@star{\dimen@\arraythickrulewidth\tab@rp@what}
3725 \def\tab@rp@what{\@ifnextchar[\tab@rp@opt\tab@rp@done}
3726 \def\tab@rp@opt[#1]{\tab@rp@keys{#1}\tab@rp@done}
3727 \def\tab@rp@keys{\mkparse{mdwtab:rule}}
3728 \def\tab@rp@done{%
3729   \protected@xdef\tab@rp@{\tab@rp@sethook}%
3730   \tab@rp@donehook%
3731   \tab@rp@next%
3732 }
3733 \def\tab@withrp#1{\tab@ruleparams{\tab@withrp@i{#1}}}
3734 \def\tab@withrp@i#1{%
3735   \toks@{#1}%
3736   \toks@\expandafter{\the\expandafter\toks@\expandafter{\tab@rp@}}%
3737   \the\toks@%
3738 }
3739 %    \end{macrocode}
3740 %
3741 % And now to define the width parameters.
3742 %
3743 %    \begin{macrocode}
3744 \tab@addhookafter\tab@rp@inithook{\dimen@\arrayrulewidth}
3745 \tab@addhookafter\tab@rp@sethook{\dimen@\the\dimen@}
3746 \tab@addhookafter\tab@rp@donehook{\global\tab@rulewidth\dimen@}
3747 \mkdef{mdwtab:rule}{width}{\setlength\dimen@{#1}}
3748 \mkdef{mdwtab:rule}{thin}*{\dimen@\arrayrulewidth}
3749 \mkdef{mdwtab:rule}{thick}*{\dimen@\arraythickrulewidth}
3750 \mkdef*{mdwtab:rule}*{\setlength\dimen@{#1}}
3751 %    \end{macrocode}
3752 %
3753 % \end{macro}
3754 %
3755 % \begin{macro}{\tabsetruleparams}
3756 %
3757 % And the user default-parameter list.
3758 %
3759 %    \begin{macrocode}
3760 \def\tabsetruleparams{\def\tab@rp@default}
3761 %    \end{macrocode}
3762 %
3763 % \end{macro}
3764 %
3765 % \subsubsection{Drawing horizontal rules}
3766 %
3767 % \begin{macro}{\hline}
3768 %
3769 % Note the funny use of |\noalign| to allow \TeX\ stomach ops like
3770 % |\futurelet| without starting a new table row.  This lets us see if there's
3771 % another |\hline| coming up, so we can see if we need to insert extra
3772 % vertical space.
3773 %
3774 %    \begin{macrocode}
3775 \def\hline{\noalign\tab@ruleparams\hline@prep}
3776 \def\hline@prep{%
3777   \tab@dohline%
3778   \noalign{\ifnum0=`}\fi%
3779   \tab@penalty%
3780   \futurelet\@let@token\hline@i%
3781 }
3782 %    \end{macrocode}
3783 %
3784 % We check here for another |\hline| command, and insert glue if there is.
3785 % This looks terrible, though, and |\hlx{hvh}| is much nicer.  Still\dots
3786 %
3787 %    \begin{macrocode}
3788 \def\hline@i{%
3789   \@tempswafalse%
3790   \ifx\@let@token\hline\@tempswatrue\fi%
3791   \ifx\@let@token\hline@prep\@tempswatrue\fi%
3792   \if@tempswa%
3793     \vskip\doublerulesep%
3794     \tab@addruleheight\doublerulesep%
3795   \fi%
3796   \ifnum0=`{\fi}%
3797 }
3798 %    \end{macrocode}
3799 %
3800 % \end{macro}
3801 %
3802 % \begin{macro}{\tab@dohline}
3803 %
3804 % This is where hlines actually get drawn.
3805 % Drawing lines is more awkward than it used to be, particularly in unboxed
3806 % tables.  It used to be a case simply of saying |\noalign{\hrule}|.
3807 % However, since unboxed tables are actually much wider than they look, this
3808 % would make the rules stretch right across the page and look generally
3809 % horrible.
3810 %
3811 % The solution is simple: we basically do a dirty big |\cline|.
3812 %
3813 %    \begin{macrocode}
3814 \def\tab@dohline{%
3815   \multispan\tab@columns%
3816   \color@begingroup%
3817   \tab@rp@\leaders\hrule\@height\dimen@\hfil%
3818   \tab@addruleheight\dimen@%
3819   \color@endgroup%
3820   \cr%
3821 }
3822 %    \end{macrocode}
3823 %
3824 % \end{macro}
3825 %
3826 % \subsubsection{Vertical rules}
3827 %
3828 % I couldn't fit these in anywhere else, so they'll have to go here.  I'll
3829 % provide a new optional argument which specifies the width of the rule; this
3830 % gets rid of the problem described in the \emph{Companion}, where to get
3831 % an unusually wide vertical rule, you have to play with things like
3832 % \syntax{"\\vrule width" <dimen>} which really isn't too nice.
3833 %
3834 % \begin{macro}{\vline}
3835 %
3836 % Now uses the general |\tab@ruleparams| parser.  We save and restore the
3837 % global |\tab@rulewidth| parameter here.
3838 %
3839 %    \begin{macrocode}
3840 \def\vline{%
3841   \begingroup%
3842   \@tempdima\tab@rulewidth\let\safe@\tab@rp@%
3843   \tab@ruleparams\tab@vline%
3844 }
3845 \def\tab@vline{%
3846   \tab@rp@\vrule\@width\dimen@%
3847   \global\tab@rulewidth\@tempdima\global\let\tab@rp@\safe@%
3848   \endgroup%
3849 }
3850 %    \end{macrocode}
3851 %
3852 % \end{macro}
3853 %
3854 % \subsubsection{Drawing bits of lines}
3855 %
3856 % Just for a bit of fun, here's an extended version of |\cline| which takes
3857 % a list of columns to draw lines under, rather than just a single range.
3858 %
3859 % \begin{macro}{\cline}
3860 %
3861 % Not a single line of code written yet, and we already have a dilemma on
3862 % our hands.  Multiple consecutive |\cline| commands are meant to draw
3863 % on the same vertical bit of table.  But horizontal lines are meant to have
3864 % thickness now.  Worse, if the lines have real thickness then we leave gaps
3865 % in the vertical rules which aren't covered by our line.  But if we
3866 % backspace over the line, then we overwrite it with coloured blobs.
3867 %
3868 % We give up on doing the job properly -- that's just doomed.  Backspace over
3869 % the previous row, and provide a hack for doing the spacing right elsewhere.
3870 %
3871 % Now the problem remains how best to do the job.  The way I see it, there
3872 % are three possibilities:
3873 %
3874 % \begin{itemize}
3875 %
3876 % \item We can start a table row, and then for each column of the table
3877 %       (as recorded in |\tab@columns|) we look to see if that column is
3878 %       listed in the range list and if so draw the rule.  This requires
3879 %       lots of scanning of the range list.
3880 %
3881 % \item We can take each range in the list, and draw rules appropriately,
3882 %       just like the old |\cline| used to do, and starting a new table row
3883 %       for each.
3884 %
3885 % \item We can start a table row, and then for each range remember where we
3886 %       stopped drawing the last row, move to the start of the new one, and
3887 %       draw it.  If we start moving backwards, we close the current row
3888 %       and open a new one.
3889 %
3890 % \end{itemize}
3891 %
3892 % The last option looks the most efficient, and the most difficult.  This
3893 % is therefore what I shall do |;-)|.
3894 %
3895 % The first thing to do is to add in a little negative space, and start a
3896 % table row (omitting the first item).  Then scan the range list, and finally
3897 % close the table row and add some negative space again.
3898 %
3899 % We need a global count register to keep track of where we are.  Mixing
3900 % local and global assignments causes all sorts of tragedy, so I shall hijack
3901 % |\tab@state|.
3902 %
3903 %    \begin{macrocode}
3904 \def\cline{\noalign\tab@ruleparams\cline@do}
3905 %    \end{macrocode}
3906 %
3907 % Now for the tricky bit.  When we're given a range, we look to see if the
3908 % first number is less than |\tab@state|.  If so, we quickly close the
3909 % current row, kern backwards and start again with an |\omit| and reset
3910 % |\tab@state| to 1, and try again.  This is hardly perfect, but gets the job
3911 % done in many cases.  Correct |\vgap| insertion fixes the remaining bugs.
3912 %
3913 %    \begin{macrocode}
3914 \def\cline@do#1{%
3915   \noalign{\kern-\tab@rulewidth}%
3916   \omit%
3917   \global\tab@state\@ne%
3918   \ranges\cline@do@i{#1}\cr%
3919 }
3920 \def\cline@do@i#1#2{%
3921   \ifnum#1<\tab@state\relax%
3922     \tab@@cr%
3923     \noalign{\kern-\tab@rulewidth\tab@penalty}%
3924     \omit%
3925     \global\tab@state\@ne%
3926   \fi%
3927 %    \end{macrocode}
3928 %
3929 % We are now either at or in front of the column position required.  If
3930 % we're too far back, we must |\hfil&\omit| our way over to the correct
3931 % column.
3932 %
3933 %    \begin{macrocode}
3934   \@whilenum\tab@state<#1\do{%
3935     \hfil\tab@@tab@omit%
3936     \global\advance\tab@state\@ne%
3937   }%
3938 %    \end{macrocode}
3939 %
3940 % We've found the start correctly.  We must deal with a tiny problem now:
3941 % if this is not the first table cell, the left hand vertical rule is in the
3942 % column to the left, so our horizontal rule won't match up properly.  So
3943 % we skip back by a bit to compensate.  If there isn't actually a vertical
3944 % rule to line up with, no-one will notice, because the rules are so thin.
3945 % This adds a little touch of quality to the whole thing, which is after all
3946 % the point of this whole exercise.
3947 %
3948 %    \begin{macrocode}
3949   \ifnum\tab@state>\@ne%
3950     \kern-\arrayrulewidth%
3951   \fi%
3952 %    \end{macrocode}
3953 %
3954 % Now we must stretch this table cell to the correct width.
3955 %
3956 %    \begin{macrocode}
3957   \@whilenum\tab@state<#2\do{%
3958     \tab@@span@omit%
3959     \global\advance\tab@state\@ne%
3960   }%
3961 %    \end{macrocode}
3962 %
3963 % We're ready.  Draw the rule.  Note that this is |\hfill| glue, just in case
3964 % we start putting in |\hfil| glue when we step onto the next cell.
3965 %
3966 %    \begin{macrocode}
3967   \color@begingroup%
3968   \tab@rp@%
3969   \leaders\hrule\@height\tab@rulewidth\hfill%
3970   \color@endgroup%
3971 }
3972 %    \end{macrocode}
3973 %
3974 % Some alignment primitives are hidden inside macros so they don't get seen
3975 % at the wrong time.  This is what they look like:
3976 %
3977 %    \begin{macrocode}
3978 \def\tab@@cr{\cr}
3979 \def\tab@@tab@omit{&\omit}
3980 \def\tab@@span@omit{\span\omit}
3981 %    \end{macrocode}
3982 %
3983 % \end{macro}
3984 %
3985 % \subsubsection{Drawing short table rows}
3986 %
3987 % Before I start on a description of more code, I think I'll briefly discuss
3988 % my reasons for leaving the |\vgap| command in its current state.  There's a
3989 % reasonable case for introducing an interface between |\vgap| and
3990 % |\multicolumn|, to avoid all the tedious messing about with column
3991 % ranges.  There are good reasons why I'm not going to do this:
3992 %
3993 % \begin{itemize}
3994 %
3995 % \item It's very difficult to do: it requires either postprocessing of
3996 %       the table or delaying processing of each row until I know exactly
3997 %       what's in it; a |\multicolumn| in a row should be able to affect
3998 %       a |\vgap| before the row, which gets very nasty.  This package is
3999 %       probably far too large already, and adding more complexity and
4000 %       running the risk of exhausting \TeX's frustratingly finite capacity
4001 %       for the sake of relieving the user of a fairly trivial job doesn't
4002 %       seem worthwhile.
4003 %
4004 % \item Perhaps more importantly, there are perfectly valid occasions when
4005 %       it's useful to have the current vgap behaviour.  For example, the
4006 %       \texttt{MIX} word layout diagrams found in \emph{The Art of
4007 %       Computer Programming} use the little `stub lines' to show where
4008 %       data items cross byte boundaries:
4009 %
4010 %       ^^A This actually looks terrifyingly similar to the original.
4011 %       ^^A The leading @{} is there to stop the table looking off-centre,
4012 %       ^^A because there's no left hand rule telling you where the table
4013 %       ^^A starts, like there is on the right, just the \tabcolsep glue.
4014 %
4015 %       \begingroup
4016 %       \newcommand{\wide}[2]{\multicolumn{#1}{c|}{\ttfamily #2}}
4017 %       \begin{tabular}[C]{@{} r @{\qquad} | Mc | *{5}{c|}} \hlx{c{2-7} v}
4018 %          empty & - & 1 & 0 & 0 & 0 & 0                \\ \hlx{v c{2-7} v}
4019 %       occupied & + & \wide{2}{LINK} & \wide{3}{KEY}   \\ \hlx{v c{2-7}}
4020 %       \end{tabular}
4021 %       \endgroup
4022 %
4023 % \end{itemize}
4024 %
4025 % That's my excuses out of the way; now I'll press on with the actual
4026 % programming.
4027 %
4028 % \begin{macro}{\tab@checkrule}
4029 %
4030 % We have a range list in |\tab@xcols| and a number as an argument.  If we
4031 % find the number in the list, we just space out the following group,
4032 % otherwise we let it be.
4033 %
4034 %    \begin{macrocode}
4035 \def\tab@checkrule#1{%
4036   \count@#1\relax%
4037   \expandafter\ifinrange%
4038   \expandafter\count@%
4039   \expandafter{\tab@xcols}%
4040     {\tab@checkrule@i}%
4041     {}%
4042 }
4043 \def\tab@checkrule@i#1{\setbox\z@\hbox{#1}\hb@xt@\wd\z@{}}
4044 %    \end{macrocode}
4045 %
4046 % \end{macro}
4047 %
4048 % \begin{macro}{\vgap}
4049 %
4050 % We must tread carefully here.  A single misplaced stomach operation can
4051 % cause error messages.  We therefore start with an |\omit| so we can search
4052 % for optional arguments.
4053 %
4054 % So that |\hlx| can get control after |\vgap| has finished, we provide a
4055 % hook called |\vgap@after| which is expanded after |\vgap| has finished.
4056 % Here we make it work like |\@empty|, which expands to nothing.  (Note that
4057 % |\relax| will start a new table row, so we can't use that.)  There are
4058 % some penalty items here to stick the |\vgap| row to the text row and
4059 % |\hline| that are adjacent to it.  The \package{longtable} package will
4060 % split an |\hline| in half, so this is the correct thing to do.
4061 %
4062 %    \begin{macrocode}
4063 \def\vgap{%
4064   \noalign{\nobreak}%
4065   \omit%
4066   \global\let\vgap@after\@empty%
4067   \iffalse{\fi\ifnum0=`}\fi%
4068   \@ifnextchar[\vgap@i\vgap@simple%
4069 }
4070 %    \end{macrocode}
4071 %
4072 % We set up two different sorts of |\vgap| -- a simple one which allows all
4073 % rules to be passed through, and a specific one which carefully vets each
4074 % one (and is therefore slower).  We decide which to so based on the presence
4075 % of an optional argument.
4076 %
4077 % The optional argument handler just passes its argument to an interface
4078 % routine which is used by |\hlx|.
4079 %
4080 %    \begin{macrocode}
4081 \def\vgap@i[#1]{\vgap@spec{#1}}
4082 %    \end{macrocode}
4083 %
4084 % Now we handle specified columns.  Since we're in an omitted table cell, we
4085 % must set things up globally.  Assign the column spec to a macro, and set up
4086 % vetting by the routine above.  Then just go and do the job.
4087 %
4088 %    \begin{macrocode}
4089 \def\vgap@spec#1#2{%
4090   \gdef\tab@xcols{#1}%
4091   \global\let\tab@ckr\tab@checkrule%
4092   \vgap@do{#2}%
4093 }
4094 %    \end{macrocode}
4095 %
4096 % Handle all columns.  Just gobble the column number for each rule, and let
4097 % the drawing pass unharmed.  Easy.
4098 %
4099 %    \begin{macrocode}
4100 \def\vgap@simple#1{%
4101   \global\let\tab@ckr\@gobble%
4102   \vgap@do{#1}%
4103 }
4104 %    \end{macrocode}
4105 %
4106 % This is where stuff actually gets done.  We set the |\vgap| flag on while
4107 % we do the short row.  Then just expand the token list we built while
4108 % scanning the preamble.
4109 %
4110 % Note that the flag is cleared at the end of the last column, to allow other
4111 % funny things like |\noalign| and |\omit| before a new row is started.
4112 %
4113 %    \begin{macrocode}
4114 \def\vgap@do#1{%
4115   \ifnum0=`{}\fi%
4116   \global\tab@vgaptrue%
4117   \the\tab@shortline%
4118     \vrule\@height#1\@width\z@%
4119     \global\tab@vgapfalse
4120     \tab@addruleheight{#1}%
4121     \cr%
4122   \noalign{\nobreak}%
4123   \vgap@after%
4124 }
4125 %    \end{macrocode}
4126 %
4127 % \end{macro}
4128 %
4129 % \subsubsection{Prettifying syntax}
4130 %
4131 % \begin{macro}{\hlx}
4132 %
4133 % This is like a poor cousin to the preamble parser.  The whole loop is
4134 % carefully written to take place \emph{only} in \TeX's mouth, so the
4135 % alignment handling bits half way down the gullet don't see any of this.
4136 %
4137 % First, pass the string to another routine.
4138 %
4139 %    \begin{macrocode}
4140 \def\hlx{\noalign\tab@ruleparams\hlx@prep}
4141 \def\hlx@prep#1{\hlx@loop#1\q@delim}
4142 %    \end{macrocode}
4143 %
4144 % Now peel off a token, and dispatch using |\csname|.  We handle
4145 % undefinedness of the command in a fairly messy way, although it probably
4146 % works.  Maybe.
4147 %
4148 %    \begin{macrocode}
4149 \def\hlx@loop#1{%
4150   \ifx#1\q@delim\else%
4151     \@ifundefined{hlx@cmd@\string#1}{%
4152       \expandafter\hlx@loop%
4153     }{%
4154       \csname hlx@cmd@\string#1\expandafter\endcsname%
4155     }%
4156   \fi%
4157 }
4158 %    \end{macrocode}
4159 %
4160 % \end{macro}
4161 %
4162 % \begin{macro}{\hlxdef}
4163 %
4164 % New |\hlx| commands can be defined using |\hlxdef|.  This is a simple
4165 % abbreviation.
4166 %
4167 %    \begin{macrocode}
4168 \def\hlxdef#1{\@namedef{hlx@cmd@#1}}
4169 %    \end{macrocode}
4170 %
4171 % \end{macro}
4172 %
4173 % \begin{macro}{\hlx h}
4174 %
4175 % Handle an \lit{h} character.  Just do an |\hline| and return to the loop.
4176 % We look ahead to see if there's another \lit{h} coming up, and if so
4177 % insert two |\hline| commands.  This strange (and inefficient) behaviour
4178 % keeps packages which redefine |\hline| happy.
4179 %
4180 %    \begin{macrocode}
4181 \hlxdef h#1{%
4182   \noalign{%
4183     \ifx#1h\def\@tempa{\hline@prep\hline@prep\hlx@loop}%
4184     \else\def\@tempa{\hline@prep\hlx@loop#1}%
4185     \fi\expandafter
4186   }%
4187   \@tempa%
4188 }
4189 %    \end{macrocode}
4190 %
4191 % \end{macro}
4192 %
4193 % \begin{macro}{\hlx b}
4194 %
4195 % The \lit{b} character does a nifty backspace, for \package{longtable}'s
4196 % benefit.
4197 %
4198 %    \begin{macrocode}
4199 \hlxdef b{\noalign{\kern-\arrayrulewidth}\hlx@loop}
4200 %    \end{macrocode}
4201 %
4202 % \end{macro}
4203 %
4204 % \begin{macro}{\hlx /}
4205 %
4206 % The `"/"' character allows a page break at the current position.
4207 %
4208 %    \begin{macrocode}
4209 \hlxdef /{\noalign{\ifnum0=`}\fi\@testopt\hlx@cmd@break@i0}
4210 \def\hlx@cmd@break@i[#1]{\ifnum0=`{\fi}\pagebreak[#1]\hlx@loop}
4211 %    \end{macrocode}
4212 %
4213 % \end{macro}
4214 %
4215 % \begin{macro}{\hlx v}
4216 % \begin{macro}{\hlx z}
4217 %
4218 % Handle a \lit{v} or \lit{z} character.  This is rather like the |\vgap|
4219 % code above, although there are syntactic differences.
4220 %
4221 %    \begin{macrocode}
4222 \hlxdef v{\hlx@vgap\doublerulesep}
4223 \hlxdef z{\hlx@vgap\tab@rulewidth}
4224 \def\hlx@vgap#1{%
4225   \noalign{\nobreak}%
4226   \omit%
4227   \iffalse{\fi\ifnum0=`}\fi%
4228   \global\let\vgap@after\hlx@loop%
4229   \@ifnextchar[{\hlx@vgap@i{#1}}{\hlx@vgap@ii\vgap@simple{#1}}%
4230 }
4231 \def\hlx@vgap@i#1[#2]{%
4232   \ifx!#2!\def\@tempa{\hlx@vgap@ii\vgap@simple{#1}}%
4233   \else\def\@tempa{\hlx@vgap@ii{\vgap@spec{#2}}{#1}}\fi%
4234   \@tempa%
4235 }
4236 \def\hlx@vgap@ii#1#2{\@testopt{\hlx@vgap@iii{#1}}{#2}}
4237 \def\hlx@vgap@iii#1[#2]{#1{#2}}
4238 %    \end{macrocode}
4239 %
4240 % \end{macro}
4241 % \end{macro}
4242 %
4243 % \begin{macro}{\hlx s}
4244 %
4245 % Allow the user to leave a small gap using the \lit{s} command.
4246 %
4247 %    \begin{macrocode}
4248 \hlxdef s{%
4249   \noalign{\ifnum0=`}\fi%
4250   \nobreak%
4251   \@testopt\hlx@space@i\doublerulesep%
4252 }
4253 \def\hlx@space@i[#1]{%
4254   \vskip#1%
4255   \tab@addruleheight{#1}%
4256   \ifnum0=`{\fi}%
4257   \hlx@loop%
4258 }
4259 %    \end{macrocode}
4260 %
4261 % \end{macro}
4262 %
4263 % \begin{macro}{\hlx c}
4264 %
4265 % We might as well allow a \lit{c} command to do a |\cline|.  The fix to
4266 % |\cline| permeates here.
4267 %
4268 %    \begin{macrocode}
4269 \hlxdef c#1{\cline@do{#1}\hlx@loop}
4270 %    \end{macrocode}
4271 %
4272 % \end{macro}
4273 %
4274 % \begin{macro}{\hlx ?}
4275 %
4276 % Do some arbitrary stuff which won't typeset.  Put the stuff in a box which
4277 % is discarded, just in case.
4278 %
4279 %    \begin{macrocode}
4280 \hlxdef ?#1{%
4281   \noalign{\setbox\z@\hbox{\color@begingroup#1\color@endgroup}}\hlx@loop%
4282 }
4283 %    \end{macrocode}
4284 %
4285 % \end{macro}
4286 %
4287 % \begin{macro}{\hlx !}
4288 %
4289 % Change parameters in mid-flow.
4290 %
4291 %    \begin{macrocode}
4292 \hlxdef !#1{\noalign\tab@ruleparams\hlx@loop[{#1}]}
4293 %    \end{macrocode}
4294 %
4295 % \end{macro}
4296 %
4297 % \begin{macro}{\hlx .}
4298 %
4299 % The \lit{.} character forces a start of the new column.  There's a little
4300 % problem here.  Since the \lit{.} character starts the next column, we need
4301 % to gobble any spaces following the |\hlx| command before the cell contents
4302 % actually starts.  Unfortunately, |\ignorespaces| will start the column for
4303 % us, so we can't put it in always.  We'll handle it here, then.  We'll take
4304 % the rest of the `preamble' string, and warn if it's not empty.  Then we'll
4305 % |\ignorespaces| -- this will start the column for us, so we don't need to
4306 % |\relax| any more.
4307 %
4308 %    \begin{macrocode}
4309 \hlxdef .#1\q@delim{%
4310   \ifx @#1@\else%
4311     \PackageWarning{mdwtab}{%
4312       Ignoring \protect\hlx\space command characters following a
4313       `.'\MessageBreak command%
4314     }%
4315   \fi%
4316   \ignorespaces%
4317 }
4318 %    \end{macrocode}
4319 %
4320 % \end{macro}
4321 %
4322 % \begin{macro}{\hlx +}
4323 % \begin{macro}{\nextrow}
4324 %
4325 % The \lit{+} subcommand just steps the table-row counter.
4326 %
4327 %    \begin{macrocode}
4328 \hlxdef +{\nextrow\hlx@loop}
4329 \def\nextrow{\noalign{\ifnum0=`}\fi\@testopt\nextrow@i\@ne}
4330 \def\nextrow@i[#1]{\global\advance\c@tabrow#1\ifnum0=`{\fi}}
4331 %    \end{macrocode}
4332 %
4333 % \end{macro}
4334 % \end{macro}
4335 %
4336 %
4337 % \subsection{Starting new table rows}
4338 %
4339 % We take a break from careful mouthery at last, and start playing with
4340 % newlines.  The standard one allows pagebreaks in unboxed tables, which
4341 % isn't really too desirable.
4342 %
4343 % Anyway, we'll try to make this macro rather more reusable than the standard
4344 % one.  Here goes.
4345 %
4346 % \begin{macro}{\@arraycr}
4347 %
4348 % We pass lots of information to a main parser macro, and expect it to cope.
4349 %
4350 %    \begin{macrocode}
4351 \def\@arraycr{\tab@arraycr{}}
4352 \def\tab@arraycr#1{\tab@cr{\tab@tabcr{#1}}{}{}}
4353 %    \end{macrocode}
4354 %
4355 % Now to actually do the work.  |\tab@cr| passes us the skip size, and the
4356 % appropriate one of the two arguments given above (both of which are empty)
4357 % depending on the presence of the $*$.
4358 %
4359 %    \begin{macrocode}
4360 \def\tab@tabcr#1#2{%
4361 %    \end{macrocode}
4362 %
4363 % If the total height I need to add between rows (from the optional argument
4364 % and the `extrasep' parameter) is greater than zero, I'll handle this by
4365 % extending the strut slightly.  I'm not actually sure whether this is the
4366 % right thing to do, to be honest, although it's easier than trying to
4367 % to an automatic |\vgap|, because I need to know which columns to skip.
4368 % If the space is less than zero, I'll just insert the vertical space with
4369 % in a |\noalign|.
4370 %
4371 % First, to calculate how much space needs adding.
4372 %
4373 %    \begin{macrocode}
4374   \setlength\dimen@{#2}%
4375   \advance\dimen@\tab@extrasep%
4376 %    \end{macrocode}
4377 %
4378 % If the height is greater than zero, I need to play with the strut.  I must
4379 % bear in mind that the current table cell (which I'm still in, remember)
4380 % may be in vertical mode, and I may or may not be in a paragraph.
4381 %
4382 % If I am in vertical mode, I'll backpedal to the previous box and put the
4383 % strut in an hbox superimposed on the previous baseline.  Otherwise, I can
4384 % just put the strut at the end of the text.  (This works in either LR
4385 % or paragraph mode as long as I'm not between paragraphs.)  Again, Rowland's
4386 % empty cell bug strikes.  (See |\tab@epar| for details.)
4387 %
4388 %    \begin{macrocode}
4389   \ifdim\dimen@>\z@%
4390     \ifvmode%
4391       \unskip\ifdim\prevdepth>-\@m\p@\kern-\prevdepth\fi%
4392       \nointerlineskip\expandafter\hbox%
4393     \else%
4394       \@maybe@unskip\expandafter\@firstofone%
4395     \fi%
4396     {\advance\dimen@\dp\@arstrutbox\vrule\@depth\dimen@\@width\z@}%
4397   \fi%
4398 %    \end{macrocode}
4399 %
4400 % This table cell works as a group (which is annoying here).  I'll copy the
4401 % interrow gap into a global register so that I can use it in the |\noalign|.
4402 %
4403 %    \begin{macrocode}
4404   \global\dimen\@ne\dimen@%
4405   \cr%
4406   \noalign{%
4407     #1%
4408     \ifdim\dimen\@ne<\z@\vskip\dimen\@ne\relax\fi%
4409   }%
4410   \@gobble%
4411 }
4412 %    \end{macrocode}
4413 %
4414 % \end{macro}
4415 %
4416 % \begin{macro}{\tab@setcr}
4417 %
4418 % To set the |\\| command correctly in each table cell, we make it a part of
4419 % the preamble (in |\tab@midtext|) to call this routine.  It's easy -- just
4420 % saves the preamble from being huge.
4421 %
4422 %    \begin{macrocode}
4423 \def\tab@setcr{\let\\\tabularnewline}
4424 %    \end{macrocode}
4425 %
4426 % \end{macro}
4427 %
4428 % \begin{macro}{\tab@cr}
4429 %
4430 % Now we do the parsing work.  This is fun.  Note the revenge of the funny
4431 % braces here.  Nothing to worry about, honest.  The tricky bit is to keep
4432 % track of which arguments are which.  (Thanks to David Carlisle for pointing
4433 % out that I'd missed out the |\relax| here.)
4434 %
4435 %    \begin{macrocode}
4436 \def\tab@cr#1#2#3{%
4437   \relax%
4438   \iffalse{\fi\ifnum0=`}\fi%
4439   \@ifstar{\tab@cr@i{#1}{#3}}{\tab@cr@i{#1}{#2}}%
4440 }
4441 \def\tab@cr@i#1#2{\@testopt{\tab@cr@ii{#1}{#2}}\z@}
4442 \def\tab@cr@ii#1#2[#3]{\ifnum0=`{}\fi#1{#3}{#2}}
4443 %    \end{macrocode}
4444 %
4445 % \end{macro}
4446 %
4447 %
4448 % \subsection{Gratuitous grotesquery}
4449 %
4450 % So far we've had an easy-ish ride (or should that be \emph{queasy}?).  Now
4451 % for something unexplainably evil.  We convince \LaTeX\ that it's loaded the
4452 % \package{array} package, so that packages which need it think they've got
4453 % it.
4454 %
4455 % The bogus date is the same as the date for the \package{array} package I've
4456 % got here -- this will raise a warning if Frank updates his package which
4457 % should filter back to me telling me that there's something I need to
4458 % know about.
4459 %
4460 % The messing with |\xdef| and the funny parsing ought to insert the current
4461 % \package{mdwtab} version and date into the fake \package{array} version
4462 % string, giving a visible clue to the user that this isn't the real
4463 % \package{array} package.
4464 %
4465 %    \begin{macrocode}
4466 \begingroup
4467 \catcode`.=11
4468 \def\@tempa#1 #2 #3\@@{#1 #2}
4469 \xdef\ver@array.sty
4470   {1995/11/19 [mdwtab.sty \expandafter\@tempa\ver@mdwtab.sty\@@]}
4471 \endgroup
4472 %    \end{macrocode}
4473 %
4474 %
4475 % \subsection{Error messages}
4476 %
4477 % I've put all the error messages together, where I can find them, translate
4478 % them or whatever.
4479 %
4480 % First, some token-space saving (which also saves my fingers):
4481 %
4482 %    \begin{macrocode}
4483 \def\tab@error{\PackageError{mdwtab}}
4484 %    \end{macrocode}
4485 %
4486 % Now do the error messages.
4487 %
4488 %    \begin{macrocode}
4489 \def\tab@err@misscol{%
4490   \tab@error{Missing column type}{%
4491     I'm lost.  I was expecting something describing^^J%
4492     the type of the current column, but you seem to^^J%
4493     have missed it out.  I've inserted a type `l'^^J%
4494     column here in the hope that this makes sense.%
4495   }%
4496 }
4497 %    \end{macrocode}
4498 %
4499 %    \begin{macrocode}
4500 \def\tab@err@oddgroup{%
4501   \tab@error{Misplaced group in table preamble}{%
4502     I've found an open brace character in your preamble^^J%
4503     when I was expecting a specifier character.  I'm^^J%
4504     going to gobble the whole group and carry on as if^^J%
4505     I'd never seen it.%
4506   }%
4507 }
4508 %    \end{macrocode}
4509 %
4510 %    \begin{macrocode}
4511 \def\tab@err@undef#1{%
4512   \tab@error{Unknown `\tab@colset' preamble character `\string#1'}{%
4513     I don't understand what you meant by typing this^^J%
4514     character.  Anyway, I'll ignore it this time around.^^J%
4515     Just don't you do it again.%
4516   }%
4517 }
4518 %    \end{macrocode}
4519 %
4520 %    \begin{macrocode}
4521 \def\tab@err@unbrh{%
4522   \tab@error{Can't use unboxed tabular in LR mode}{%
4523     You've asked for a tabular or array environment with^^J%
4524     `L', `C' or `R' as the position specifier, but you're^^J%
4525     in LR (restricted horizontal) mode, so it won't work.^^J%
4526     I'll assume you really meant `c' and soldier on.%
4527   }%
4528 }
4529 %    \end{macrocode}
4530 %
4531 %    \begin{macrocode}
4532 \def\tab@err@unbmm{%
4533   \tab@error{Can't use unboxed tabular in maths mode}{%
4534     You've asked for a tabular or array environment with^^J%
4535     `L', `C' or `R' as the position specifier, but you're^^J%
4536     in maths mode, so it won't work.  I'll pretend that^^J%
4537     you really typed `c', and that this is all a bad dream.%
4538   }%
4539 }
4540 %    \end{macrocode}
4541 %
4542 %    \begin{macrocode}
4543 \def\tab@err@unbext{%
4544   \tab@error{Can't extend unboxed tabulars}{%
4545     You're trying to use kludgy extensions (e.g.,^^J%
4546     `delarray') on an array or tabular with `L', `C'^^J%
4547     or `R' as the position specifier.  I'll assume you^^J%
4548     subconsciously wanted a `c' type all along.%
4549   }%
4550 }
4551 %    \end{macrocode}
4552 %
4553 %    \begin{macrocode}
4554 \def\tab@err@multi{%
4555   \tab@error{More than one column in a \protect\multicolumn}{%
4556     You've put more than one column into a \string\multicolumn^^J%
4557     descriptor.  It won't work.  I have no idea what^^J%
4558     will happen, although it won't be pleasant.  Hold^^J%
4559     on tight now...%
4560   }%
4561 }
4562 %    \end{macrocode}
4563 %
4564 %    \begin{macrocode}
4565 \def\tab@err@range{%
4566   \tab@error{Expected `,' or `<end>' in range list}{%
4567     I was expecting either the end of the range list,^^J%
4568     or a comma, followed by another range.  I've^^J%
4569     inserted a comma to try and get me back on track.^^J%
4570     Good luck.%
4571   }%
4572 }
4573 %    \end{macrocode}
4574 %
4575 %
4576 % \subsection{Loading the colour package}
4577 %
4578 % If requested, we load the \package{mtcolour} package here.  This ensures
4579 % that it can patch this code if it needs to.
4580 %
4581 %    \begin{macrocode}
4582 \iftab@colour
4583   \RequirePackage{mtcolour}
4584 \fi
4585 %    \end{macrocode}
4586 %
4587 % That's it.  No more.  Move along please.
4588 %
4589 %    \begin{macrocode}
4590 %</mdwtab>
4591 %    \end{macrocode}
4592 %
4593 %
4594 %^^A-------------------------------------------------------------------------
4595 % \section{Implementation of \package{mtcolour}}
4596 %
4597 %
4598 % This is in a separate package to avoid dragging in the \package{color}
4599 % package if it's unwanted.
4600 %
4601 % I prefer English spellings.  Here's a trivial redirection for Americans.
4602 %
4603 %    \begin{macrocode}
4604 %<*color>
4605 \DeclareOption*{\PassOptionsToPackage{\CurrentOption}{mtcolour}}
4606 \ProcessOptions
4607 \RequirePackage{mtcolour}
4608 %</color>
4609 %    \end{macrocode}
4610 %
4611 % And now we can start the thing properly.
4612 %
4613 %    \begin{macrocode}
4614 %<*colour>
4615 \RequirePackage{color}
4616 %    \end{macrocode}
4617 %
4618 %
4619 % \subsection{Cell background colours}
4620 %
4621 % First, some simple preliminaries.  The |\iftab@colour| switch is set if the
4622 % current cell is meant to have a colour.
4623 %
4624 %    \begin{macrocode}
4625 \newif\iftab@colour
4626 \tab@colourfalse
4627 %    \end{macrocode}
4628 %
4629 % We shall store the cell colour information in |\tab@cellcolour|, and the
4630 % row colour information as |\tab@rowcolour|.  Because of the structure of
4631 % tables, we need to make global assignments; so we must copy the current
4632 % value away at the start of a table and put the value back at the end.  In
4633 % order to transfer the overhang information reliably, we use a separate
4634 % control sequence |\tab@colouroverhangs| for that -- otherwise |\color| can
4635 % corrupt it.
4636 %
4637 %    \begin{macrocode}
4638 \tab@addhookbefore\tab@beginhook{%
4639   \let\tab@saverowcolour\tab@rowcolour%
4640   \let\tab@savecolouroverhangs\tab@colouroverhangs%
4641   \let\tab@savecellcolour\tab@cellcolour%
4642 }
4643 \tab@addhookafter\tab@endhook{%
4644   \global\let\tab@rowcolour\tab@saverowcolour%
4645   \global\let\tab@colouroverhangs\tab@savecolouroverhangs%
4646   \global\let\tab@cellcolour\tab@savecellcolour%
4647 }
4648 %    \end{macrocode}
4649 %
4650 % Initially, there are no colours.
4651 %
4652 %    \begin{macrocode}
4653 \let\tab@rowcolour\@empty%
4654 \let\tab@cellcolour\@empty%
4655 \let\tab@colouroverhangs\@empty%
4656 %    \end{macrocode}
4657 %
4658 % \begin{macro}{\@snarfcolour}
4659 %
4660 % Reading a colour specification is something we'll need to do a few times,
4661 % so an abstraction is useful.  Its single argument is a continuation to
4662 % which we pass a colour-spec acceptable to the |\color| command.  (This is
4663 % the same code as found in the \package{sverb} package.  Remember to keep
4664 % them in step.)
4665 %
4666 %    \begin{macrocode}
4667 \def\@snarfcolour#1{%
4668   \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
4669 }
4670 \def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
4671 \def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
4672 %    \end{macrocode}
4673 %
4674 % \end{macro}
4675 %
4676 % \begin{macro}{\cellcolour}
4677 %
4678 % Setting a cell colour is a matter of stashing the right declarations in
4679 % |\tab@cellcolour| and |\tab@colouroverhangs|.  Note that the overhangs end
4680 % up in |\dimen0| and |\dimen2|.
4681 %
4682 %    \begin{macrocode}
4683 \def\cellcolour{%
4684   \@ifstar{\tab@ccol@i{\let\tab@rowcolour\@empty}}{\tab@ccol@i{}}%
4685 }
4686 \def\tab@ccol@i#1{\@snarfcolour{\tab@ccol@ii{#1}}}
4687 \def\tab@ccol@ii#1#2{\@testopt{\tab@ccol@iii{#2#1}}\z@}
4688 \def\tab@ccol@iii#1[#2]{\@testopt{\tab@ccol@iv{#1}{#2}}{#2}}
4689 \def\tab@ccol@iv#1#2[#3]{%
4690   \gdef\tab@cellcolour{\color#1\tab@colourtrue}%
4691   \gdef\tab@colouroverhangs{%
4692     \setlength\dimen@{#2}%
4693     \setlength{\dimen\tw@}{#3}%
4694   }%
4695 }
4696 %    \end{macrocode}
4697 %
4698 % \end{macro}
4699 %
4700 % \begin{macro}{\rowcolour}
4701 %
4702 % Setting the global row colour is simpler, because we don't mess with
4703 % overhangs.
4704 %
4705 %    \begin{macrocode}
4706 \def\rowcolour{\@snarfcolour\tab@setrowcolour}
4707 \let\rowcolor\rowcolour
4708 \def\tab@setrowcolour#1{%
4709   \gdef\tab@rowcolour{\color#1\tab@colourtrue}%
4710 }
4711 %    \end{macrocode}
4712 %
4713 % \end{macro}
4714 %
4715 % \begin{macro}{\rowcolouroff}
4716 %
4717 % And turning the global colouring off is easy.
4718 %
4719 %    \begin{macrocode}
4720 \def\rowcolouroff{\global\let\tab@rowcolour\@empty}
4721 \let\rowcoloroff\rowcolouroff
4722 %    \end{macrocode}
4723 %
4724 % \end{macro}
4725 %
4726 % \begin{macro}{\tab@colourleft}
4727 %
4728 % Now we start on the table-cell hooks.  The left hook starts a box which
4729 % will capture the cell's text and natural width.  We add the hook to the
4730 % rule list as well, so that we can colour the bits in |\vgap|s correctly.
4731 %
4732 %    \begin{macrocode}
4733 \tab@addhookbefore\tab@lefttexthook\tab@colourleft
4734 \tab@addhookbefore\tab@leftruletexthook\tab@colourleft
4735 \def\tab@colourleft{%
4736   \global\let\tab@cellcolour\@empty%
4737   \global\let\tab@colouroverhangs\@empty%
4738   \setbox\z@\hbox\bgroup\color@begingroup%
4739 }
4740 %    \end{macrocode}
4741 %
4742 % \end{macro}
4743 %
4744 % \begin{macro}{\tab@colourright}
4745 %
4746 % The right hook will insert an appropriate rule behind the cell and
4747 % retypeset the cell contents over the top.  Note that the stretch in a table
4748 % cell is exactly 1\,fil.  Because we add (leaders) and subtract (negative
4749 % |\hskip|) 1\,fil, we retain this stretch exactly.  Don't bother unless
4750 % there's actually some colouring.
4751 %
4752 %    \begin{macrocode}
4753 \tab@addhookafter\tab@righttexthook\tab@colourright
4754 \tab@addhookafter\tab@rightruletexthook\tab@colourright
4755 \def\tab@colourright{%
4756   \color@endgroup\egroup%
4757   \color@begingroup%
4758   \global\tab@colourfalse%
4759   \tab@cellcolour\tab@rowcolour%
4760   \dimen@\z@\dimen\tw@\z@\tab@colouroverhangs%
4761   \iftab@colour%
4762     \skip@\wd\z@\advance\skip@\z@\@plus1fil%
4763     \skip\tw@\skip@%
4764     \kern-\dimen@%
4765     \advance\skip\tw@\dimen@%
4766     \advance\skip\tw@\dimen\tw@%
4767     \leaders\vrule\hskip\skip\tw@%
4768     \kern-\dimen\tw@%
4769     \hskip-\skip@%
4770   \fi%
4771   \color@endgroup%
4772   \unhbox\z@%
4773 }
4774 %    \end{macrocode}
4775 %
4776 % \end{macro}
4777 %
4778 %
4779 % \subsection{Coloured rules}
4780 %
4781 % We hook ourselves onto the rule-parameters edifice.  This is rather
4782 % straightforward.
4783 %
4784 %    \begin{macrocode}
4785 \tab@addhookafter\tab@rp@inithook{%
4786   \let\tab@rulecolour\@empty%
4787   \let\tab@rulecolourmodel\@empty%
4788 }
4789 \mkdef{mdwtab:rule}{colour}{\tab@setrulecolour{#1}}
4790 \mkdef{mdwtab:rule}{colourmodel}{\tab@setrulecolourmodel{#1}}
4791 \mkdef{mdwtab:rule}{color}{\tab@setrulecolour{#1}}
4792 \mkdef{mdwtab:rule}{colormodel}{\tab@setrulecolourmodel{#1}}
4793 \mkdef{mdwtab:rule}{nocolour}*{\let\tab@rulecolour\@empty}
4794 \mkdef{mdwtab:rule}{nocolor}*{\let\tab@rulecolour\@empty}
4795 \mkdef{mdwtab:rule}{nocolourmodel}*{\let\tab@rulecolourmodel\@empty}
4796 \mkdef{mdwtab:rule}{nocolormodel}*{\let\tab@rulecolourmodel\@empty}
4797 \def\tab@setrulecolour#1{%
4798   \def\tab@rulecolour{\color\tab@rulecolourmodel{#1}}%
4799 }
4800 \def\tab@setrulecolourmodel#1{\def\tab@rulecolourmodel{[#1]}}
4801 \tab@addhookafter\tab@rp@sethook{\tab@rulecolour}
4802 %    \end{macrocode}
4803 %
4804 %
4805 % \subsection{Other stuff}
4806 %
4807 % \begin{macro}{\ifmod}
4808 %
4809 % \syntax{"\\ifmod{"$x$"}{"$m$"}{"$y$"}{"<yes>"}{"<no>"}"} -- if $x \bmod m =
4810 % y$ then do \<yes>; otherwise do \<no>.
4811 %
4812 %    \begin{macrocode}
4813 \def\ifmod#1#2#3{%
4814   \begingroup%
4815   \@tempcnta#1%
4816   \@tempcntb#2%
4817   \count@\@tempcnta%
4818   \divide\count@\@tempcntb%
4819   \multiply\count@\@tempcntb%
4820   \advance\@tempcnta-\count@%
4821   \count@#3\relax%
4822   \ifnum\@tempcnta=\count@\endgroup\expandafter\@firstoftwo%
4823   \else\endgroup\expandafter\@secondoftwo\fi%
4824 }
4825 %    \end{macrocode}
4826 %
4827 % \end{macro}
4828 %
4829 % Done.
4830 %
4831 %    \begin{macrocode}
4832 %</colour>
4833 %    \end{macrocode}
4834 %
4835 %^^A-------------------------------------------------------------------------
4836 % \section{Implementation of \package{mathenv}}
4837 %
4838 %
4839 % This is in a separate package, mainly to avoid wasting people's memory.
4840 %
4841 %    \begin{macrocode}
4842 %<*mathenv>
4843 %    \end{macrocode}
4844 %
4845 %
4846 % \subsection{Options handling}
4847 %
4848 % We need to be able to cope with \textsf{fleqn} and \textsf{leqno} options.
4849 % This will adjust our magic modified \env{eqnarray} environment
4850 % appropriately.
4851 %
4852 %    \begin{macrocode}
4853 \newif\if@fleqn
4854 \newif\if@leqno
4855 \DeclareOption{fleqn}{\@fleqntrue}
4856 \DeclareOption{leqno}{\@leqnotrue}
4857 \ProcessOptions
4858 %    \end{macrocode}
4859 %
4860 % We use the \package{mdwtab} package for all its nice table handling things.
4861 % (Oh, and to inflict it on users who want to do nice equations and don't
4862 % care about our tables.)
4863 %
4864 %    \begin{macrocode}
4865 \RequirePackage{mdwtab}
4866 %    \end{macrocode}
4867 %
4868 %
4869 % \subsection{Some useful registers}
4870 %
4871 % The old \LaTeX\ version puts the equation numbers in by keeping a count of
4872 % where it is in the alignment.  Since I don't know how may columns there are
4873 % going to be, I'll just use a switch in the preamble to tell me to stop
4874 % tabbing.
4875 %
4876 %    \begin{macrocode}
4877 \newif\if@eqalast
4878 %    \end{macrocode}
4879 %
4880 % Now define some useful length parameters.  First allocate them:
4881 %
4882 %    \begin{macrocode}
4883 \newskip\eqaopenskip
4884 \newskip\eqacloseskip
4885 \newskip\eqacolskip
4886 \newskip\eqainskip
4887 \newskip\splitleft
4888 \newskip\splitright
4889 %    \end{macrocode}
4890 %
4891 % Now assign some default values.  Users can play with these if they really
4892 % want although I can't see the point myself.
4893 %
4894 %    \begin{macrocode}
4895 \AtBeginDocument{%
4896   \eqacloseskip\@centering%
4897   \eqacolskip1.5em\@plus\@m\p@
4898   \eqainskip\z@%
4899   \if@fleqn%
4900     \eqaopenskip\mathindent%
4901     \splitleft\mathindent\relax%
4902     \splitright\mathindent\@minus\mathindent\relax%
4903   \else%
4904     \eqaopenskip\@centering%
4905     \splitleft2.5em\@minus2.5em%
4906     \splitright\splitleft%
4907   \fi%
4908   \relax%
4909 }
4910 %    \end{macrocode}
4911 %
4912 %
4913 % \subsection{A little display handling}
4914 %
4915 % I'm probably going a little far here, and invading territory already
4916 % claimed by the \package{amsmath} stuff (and done a good deal better than
4917 % I can be bothered to do), but just for completeness, this is how we handle
4918 % attempts to put displays inside other displays without screwing up the
4919 % spacing.
4920 %
4921 % \begin{macro}{\dsp@startouter}
4922 %
4923 % This is how we start an outermost display.  It's fairly easy really.  We
4924 % make |\dsp@start| start an inner display, and make |\dsp@end| close the
4925 % outer display.
4926 %
4927 %    \begin{macrocode}
4928 \def\dsp@startouter{%
4929   \let\dsp@end\dsp@endouter%
4930   $$%
4931 }
4932 %    \end{macrocode}
4933 %
4934 % \end{macro}
4935 %
4936 % \begin{macro}{\dsp@endouter}
4937 %
4938 % Ending the outer display is utterly trivial.
4939 %
4940 %    \begin{macrocode}
4941 \def\dsp@endouter{$$}
4942 %    \end{macrocode}
4943 %
4944 % \end{macro}
4945 %
4946 % \begin{macro}{\dsp@startinner}
4947 %
4948 % Starting inner displays is done in a vbox (actually I choose |\vbox| or
4949 % |\vtop| depending on the setting of \textsf{leqno} to put the equation
4950 % number the right way round).
4951 %
4952 %    \begin{macrocode}
4953 \def\dsp@startinner{%
4954   \let\dsp@end\dsp@endinner%
4955   \if@fleqn\kern-\mathindent\fi%
4956   \if@leqno\vtop\else\vtop\fi\bgroup%
4957 }
4958 %    \end{macrocode}
4959 %
4960 % \end{macro}
4961 %
4962 % \begin{macro}{\dsp@endinner}
4963 %
4964 % Ending an inner display is also really easy.
4965 %
4966 %    \begin{macrocode}
4967 \def\dsp@endinner{\egroup}
4968 %    \end{macrocode}
4969 %
4970 % \end{macro}
4971 %
4972 % \begin{macro}{\dsp@start}
4973 %
4974 % This is what other bits of code uses to start displays.  It's one of the
4975 % start macros up above, and outer by default.
4976 %
4977 %    \begin{macrocode}
4978 \def\dsp@start{%
4979   \ifmmode%
4980     %\ifinner\mth@err@mdsp\fi%
4981     \expandafter\dsp@startinner%
4982   \else%
4983     \ifhmode\ifinner\mth@err@hdsp\fi\fi%
4984     \expandafter\dsp@startouter%
4985   \fi%
4986 }
4987 %    \end{macrocode}
4988 %
4989 % \end{macro}
4990 %
4991 % \begin{macro}{\dsp@tabpause}
4992 %
4993 % This sets up the correct pre- and postambles for the |\tabpause| macro in
4994 % maths displays.  This is fairly simple stuff.
4995 %
4996 %    \begin{macrocode}
4997 \def\dsp@tabpause{%
4998   \def\tab@startpause%
4999     {\penalty\postdisplaypenalty\vskip\belowdisplayskip}%
5000   \def\tab@endpause%
5001     {\penalty\predisplaypenalty\vskip\abovedisplayskip}%
5002 }
5003 %    \end{macrocode}
5004 %
5005 % \end{macro}
5006 %
5007 %
5008 % \subsection{The \env{eqnarray} environment}
5009 %
5010 % We allow the user to play with the style if this is really wanted.  I dunno
5011 % why, really.  Maybe someone wants very small alignments.
5012 %
5013 %    \begin{macrocode}
5014 \let\eqastyle\displaystyle
5015 %    \end{macrocode}
5016 %
5017 % \subsubsection{The main environments}
5018 %
5019 % \begin{environment}{eqnarray}
5020 % \begin{environment}{eqnarray*}
5021 %
5022 % We define the toplevel commands here.  They just add in default arguments
5023 % and then call |\@eqnarray| with a preamble string.  We handle equation
5024 % numbers by setting up a default (|\eqa@defnumber|) which is put into
5025 % the final column.  At the beginning of each row, we globally |\let|
5026 % |\eqa@number| equal to |\eqa@defnumber|.  The |\eqnumber| macro just
5027 % changes |\eqa@number| as required.  Since |\eqa@number| is changed globally
5028 % we must save it in this environment.
5029 %
5030 % First, we must sort out the optional arguments and things.  This is really
5031 % easy.  The only difference between the starred and non-starred environments
5032 % is the default definition of |\eqa@defnumber|.
5033 %
5034 %    \begin{macrocode}
5035 \def\eqnarray{%
5036   \eqnarray@i\eqa@eqcount%
5037 }
5038 \@namedef{eqnarray*}{\eqnarray@i{}}
5039 \def\eqnarray@i#1{\@testopt{\eqnarray@ii{#1}}{rcl}}
5040 %    \end{macrocode}
5041 %
5042 % Right.  Now for the real work.  The first argument is the default numbering
5043 % tokens; the second is the preamble string.
5044 %
5045 %    \begin{macrocode}
5046 \def\eqnarray@ii#1[#2]{%
5047 %    \end{macrocode}
5048 %
5049 % Set up the equation counter and labels correctly.
5050 %
5051 % \medskip\par\noindent|\begin{rant}|\par
5052 % The hacking with |\@currentlabel| is here because (in the author's opinion)
5053 % \LaTeX's |\refstepcounter| macro is broken.  It's currently defined as
5054 % \begin{listing}
5055 %\def\refstepcounter#1{%
5056 %  \stepcounter{#1}%
5057 %  \protected@edef\@currentlabel%
5058 %    {\csname p@#1\endcsname\csname the#1\endcsname}%
5059 %}
5060 % \end{listing}
5061 % which means that the current label gets `frozen' as soon as you do the
5062 % counter step.  By redefining the macro as
5063 % \begin{listing}
5064 %\def\refstepcounter#1{%
5065 %  \stepcounter{#1}%
5066 %  \edef\@currentlabel{%
5067 %    \expandafter\noexpand\csname p@#1\endcsname%
5068 %    \expandafter\noexpand\csname the#1\endcsname%
5069 %  }%
5070 %}
5071 % \end{listing}
5072 % these sorts of problems would be avoided, without any loss of functionality
5073 % or compatibility that I can see.
5074 % \par\noindent|\end{rant}|\par
5075 %
5076 %    \begin{macrocode}
5077   \stepcounter{equation}%
5078   \def\@currentlabel{\p@equation\theequation}%
5079 %    \end{macrocode}
5080 %
5081 % The next step is to set up the numbering.  I must save the old numbering
5082 % so I can restore it later (once in the alignment, I must assign these
5083 % things globally).
5084 %
5085 %    \begin{macrocode}
5086   \let\eqa@oldnumber\eqa@number%
5087   \def\eqa@defnumber{#1}%
5088   \global\let\eqa@number\eqa@defnumber%
5089 %    \end{macrocode}
5090 %
5091 % The |\if@eqalastfalse| switch is false everywhere except when we're in the
5092 % final column.
5093 %
5094 %    \begin{macrocode}
5095   \@eqalastfalse%
5096 %    \end{macrocode}
5097 %
5098 % Remove the |\mathsurround| kerning, since it will look very odd inside
5099 % the display.  We have our own spacing parameters for configuring these
5100 % things, so |\mathsurround| is unnecessary.
5101 %
5102 %    \begin{macrocode}
5103   \m@th%
5104 %    \end{macrocode}
5105 %
5106 % Time to parse the preamble string now.  I must choose the correct column
5107 % set, initialise the preamble parser and set up the various macros.  The%
5108 % extra `|@{\tabskip\eqacloseskip}|' item sets up the tabskip glue to centre
5109 % the alignment properly.
5110 %
5111 %    \begin{macrocode}
5112   \colset{eqnarray}%
5113   \tab@initread%
5114   \def\tab@tabtext{&\tabskip\z@skip}%
5115   \tab@preamble{\tabskip\z@skip}%
5116   \tab@readpreamble{#2@{\tabskip\eqacloseskip}}%
5117   \dsp@tabpause%
5118 %    \end{macrocode}
5119 %
5120 % Now for some final setting up.  The column separation is set from the
5121 % user's parameter, the |\everycr| tokens are cleared, and I set up the
5122 % newline command appropriately.
5123 %
5124 %    \begin{macrocode}
5125   \col@sep.5\eqainskip%
5126   \everycr{}%
5127   \let\\\@eqncr%
5128 %    \end{macrocode}
5129 %
5130 % Now start a maths display and do the alignment.  Set up the left hand
5131 % tabskip glue to centre the alignment, and do the actual alignment.
5132 % The preamble used is mainly that generated from the user's string, although
5133 % the stuff at the end is how we set up the equation number -- it repeats
5134 % appropriately so we can always find it.
5135 %
5136 %    \begin{macrocode}
5137   \dsp@start%
5138   \tabskip\eqaopenskip%
5139   \halign to\displaywidth\expandafter\bgroup%
5140     \the\tab@preamble%
5141     &&\eqa@lastcol\hb@xt@\z@{\hss##}\tabskip\z@\cr%
5142 }
5143 %    \end{macrocode}
5144 %
5145 % Now for the end of the environment.  This is really easy.  Set the final
5146 % equation number, close the |\halign|, tidy up the equation counter (it's
5147 % been stepped once too many times) and close the display.
5148 %
5149 %    \begin{macrocode}
5150 \def\endeqnarray{%
5151   \eqa@eqnum%
5152   \egroup%
5153   \dsp@end%
5154   \global\let\eqa@number\eqa@oldnumber%
5155   \global\@ignoretrue%
5156   \global\advance\c@equation\m@ne%
5157 }
5158 \expandafter\let\csname endeqnarray*\endcsname\endeqnarray
5159 %    \end{macrocode}
5160 %
5161 % \end{environment}
5162 % \end{environment}
5163 %
5164 % Now we can define the column types.
5165 %
5166 %    \begin{macrocode}
5167 \colpush{eqnarray}
5168 %    \end{macrocode}
5169 %
5170 % Note the positioning of ord atoms in the stuff below.  This will space out
5171 % relations and binops correctly when they occur at the edges of columns, and
5172 % won't affect ord atoms at the edges, because ords pack closely.
5173 %
5174 % First the easy ones.  Just stick |\hfil| in the right places and
5175 % everything will be all right.
5176 %
5177 %    \begin{macrocode}
5178 \coldef r{\tabcoltype{\hfil$\eqastyle}{{}$}}
5179 \coldef c{\tabcoltype{\hfil$\eqastyle{}}{{}$\hfil}}
5180 \coldef l{\tabcoltype{$\eqastyle{}}{$\hfil}}
5181 \coldef x{\tabcoltype{\if@fleqn\else\hfil\fi$\eqastyle}{$\hfil}}
5182 %    \end{macrocode}
5183 %
5184 % Now for the textual ones.  This is also fairly easy.
5185 %
5186 %    \begin{macrocode}
5187 \collet T [tabular]T
5188 %    \end{macrocode}
5189 %
5190 % Sort of split types of equations.  I mustn't use |\rlap| here, or
5191 % everything goes wrong -- |\\| doesn't get noticed by \TeX\ in the same way
5192 % as |\cr| does.
5193 %
5194 %    \begin{macrocode}
5195 \coldef L{\tabcoltype{\hb@xt@2em\bgroup$\eqastyle}{$\hss\egroup}}
5196 %    \end{macrocode}
5197 %
5198 % The \lit{:} column type is fairly simple.
5199 %
5200 %    \begin{macrocode}
5201 \coldef :{\tabspctype{\tabskip\eqacolskip}}
5202 \coldef q{\tabspctype{\quad}}
5203 %    \end{macrocode}
5204 %
5205 % The other column types just insert given text in an appropriate way.
5206 %
5207 %    \begin{macrocode}
5208 \collet > [tabular]>
5209 \collet < [tabular]<
5210 \collet * [tabular]*
5211 \collet @ [tabular]@
5212 %    \end{macrocode}
5213 %
5214 % Finally, the magical `|\magic|' column type, which sets the equation
5215 % number.  We set up the |\tabskip| glue properly, tab on, and set the flag
5216 % which marks the final column.  The |\eqa@lastcol| command is there to
5217 % raise an error if the user tabs over to this column.  I'll temporarily
5218 % redefine it to |\@eqalasttrue| when I enter this column legitimately.
5219 % The extra magical bits here will make the final column repeat, so that we
5220 % can find it if necessary.  Well is this column type named.
5221 %
5222 % That's it.  We can return to normal now.
5223 %
5224 %    \begin{macrocode}
5225 \colpop
5226 %    \end{macrocode}
5227 %
5228 % \subsubsection{Newline codes}
5229 %
5230 % Newline sequences (|\\|) get turned into calls of |\@eqncr|.  The job is
5231 % fairly simple, really.
5232 %
5233 %    \begin{macrocode}
5234 \def\@eqncr{\tab@cr\eqacr@i\interdisplaylinepenalty\@M}%
5235 \def\eqacr@i#1#2{%
5236   \eqa@eqnum%
5237   \noalign{\penalty#2\vskip\jot\vskip#1}%
5238 }
5239 %    \end{macrocode}
5240 %
5241 % \subsubsection{Setting equation numbers}
5242 %
5243 % \begin{macro}{\eqa@eqpos}
5244 %
5245 % Before we start, we need to generalise the flush-left number handling bits.
5246 % The macro |\eqa@eqpos| will put its argument in the right place.
5247 %
5248 %    \begin{macrocode}
5249 \def\eqa@eqpos#1{%
5250   \if@leqno%
5251     \hb@xt@.01\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
5252   \else%
5253     \normalfont\normalcolor#1%
5254   \fi%
5255 }
5256 %    \end{macrocode}
5257 %
5258 % \end{macro}
5259 %
5260 % \begin{macro}{\eqa@eqnum}
5261 %
5262 % Here we typeset an equation number in roughly the right place.  First I'll
5263 % redefine |\eqa@lastcol| so that it tells me I'm in the right place, and
5264 % start a loop to find that place.
5265 %
5266 %    \begin{macrocode}
5267 \def\eqa@eqnum{%
5268   \global\let\eqa@lastcol\@eqalasttrue%
5269   \eqa@eqnum@i%
5270 }
5271 %    \end{macrocode}
5272 %
5273 % Now for the loop.  The |\relax| here is absolutely vital -- it starts the
5274 % table column, inserting useful tokens like `|\eqa@lastcol|' which tell
5275 % me where I am in the alignment.  Then, if I've reached the end, I can
5276 % typeset the equation number; otherwise I go off into another macro and
5277 % step on to the next column.
5278 %
5279 %    \begin{macrocode}
5280 \def\eqa@eqnum@i{%
5281   \relax%
5282   \if@eqalast%
5283     \expandafter\eqa@eqnum@ii%
5284   \else%
5285     \expandafter\eqa@eqnum@iii%
5286   \fi%
5287 }
5288 \def\eqa@eqnum@ii{%
5289   \eqa@eqpos\eqa@number%
5290   \global\let\eqa@number\eqa@defnumber%
5291   \global\let\eqa@lastcol\eqa@@lastcol%
5292   \cr%
5293 }
5294 \def\eqa@eqnum@iii{&\eqa@eqnum@i}
5295 %    \end{macrocode}
5296 %
5297 % \end{macro}
5298 %
5299 % \begin{macro}{\eqa@lastcol}
5300 %
5301 % This is used as a marker for the final column in an \env{eqnarray}
5302 % environment.  By default it informs the user that they've been very
5303 % silly and swallows the contents of the column.  I'll redefine it to
5304 % something more useful at appropriate times, and then turn it back again.
5305 %
5306 %    \begin{macrocode}
5307 \def\eqa@@lastcol{\mth@err@number\setbox\z@}
5308 \let\eqa@lastcol\eqa@@lastcol
5309 %    \end{macrocode}
5310 %
5311 % \end{macro}
5312 %
5313 % \subsubsection{Numbering control}
5314 %
5315 % \begin{macro}{\eqnumber}
5316 %
5317 % The |\eqnumber| command sets the equation number on the current equation.
5318 % This is really easy, actually.
5319 %
5320 %    \begin{macrocode}
5321 \newcommand\eqnumber[1][\eqa@eqcount]{\gdef\eqa@number{#1}}
5322 %    \end{macrocode}
5323 %
5324 % \end{macro}
5325 %
5326 % \begin{macro}{\eqa@eqcount}
5327 %
5328 % This is how a standard equation number is set, stepping the counter and
5329 % all.  It's really easy and obvious.
5330 %
5331 %    \begin{macrocode}
5332 \def\eqa@eqcount{(\theequation)\global\advance\c@equation\@ne}
5333 %    \end{macrocode}
5334 %
5335 % \end{macro}
5336 %
5337 % \begin{macro}{\nonumber}
5338 %
5339 % The \LaTeX\ |\nonumber| command could be defined by saying
5340 % \begin{listing}
5341 %\renewcommand{\nonumber}{\eqnumber[]}
5342 % \end{listing}
5343 % but I'll be slightly more efficient and redefine |\eqa@number| directly.
5344 %
5345 %    \begin{macrocode}
5346 \def\nonumber{\global\let\eqa@number\@empty}
5347 %    \end{macrocode}
5348 %
5349 % \end{macro}
5350 %
5351 % \subsubsection{The \env{eqnalign} environment}
5352 %
5353 % As a sort of companion to \env{eqnarray}, here's an environment which does
5354 % similar things inside a box, rather than taking up the whole display width.
5355 % It uses the same column types that we've already created, so there should
5356 % be no problems.
5357 %
5358 % \begin{environment}{eqnalign}
5359 %
5360 % First, sort out some simple things like optional arguments.
5361 %
5362 %    \begin{macrocode}
5363 \def\eqnalign{\@testopt\eqnalign@i{rcl}}
5364 \def\eqnalign@i[#1]{\@testopt{\eqnalign@ii{#1}}c}
5365 %    \end{macrocode}
5366 %
5367 % Now we actually do the environment.  This is fairly easy, actually.
5368 %
5369 %    \begin{macrocode}
5370 \def\eqnalign@ii#1[#2]{%
5371   \let\\\eqn@cr%
5372   \colset{eqnarray}%
5373   \tab@initread%
5374   \def\tab@tabtext{&\tabskip\z@skip}%
5375   \tabskip\z@skip%
5376   \col@sep.5\eqainskip%
5377   \tab@readpreamble{#1}%
5378   \everycr{}%
5379   \if#2t\vtop\else%
5380     \if#2b\vbox\else%
5381       \vcenter%
5382     \fi%
5383   \fi%
5384   \bgroup%
5385   \halign\expandafter\bgroup\the\tab@preamble\cr%
5386 }
5387 %    \end{macrocode}
5388 %
5389 % Finishing the environment is even simpler.
5390 %
5391 %    \begin{macrocode}
5392 \def\endeqnalign{%
5393   \crcr%
5394   \egroup%
5395   \egroup%
5396 }
5397 %    \end{macrocode}
5398 %
5399 % \end{environment}
5400 %
5401 % \begin{macro}{\eqn@cr}
5402 %
5403 % Newlines are really easy here.
5404 %
5405 %    \begin{macrocode}
5406 \def\eqn@cr{\tab@cr\eqn@cr@i{}{}}
5407 \def\eqn@cr@i#1{\cr\noalign{\vskip\jot\vskip#1}\@gobble}
5408 %    \end{macrocode}
5409 %
5410 % \end{macro}
5411 %
5412 %
5413 % \subsection{Simple multiline equations}
5414 %
5415 % As a sort of example and abbreviation, here's a multiline display
5416 % environment which just centres everything.
5417 %
5418 % \begin{environment}{eqlines}
5419 %
5420 % We just get |\eqnarray| to do everything for us.  This is really easy.
5421 %
5422 %    \begin{macrocode}
5423 \def\eqlines{\eqnarray[x]}
5424 \let\endeqlines\endeqnarray
5425 %    \end{macrocode}
5426 %
5427 % \end{environment}
5428 %
5429 % \begin{environment}{eqlines*}
5430 %
5431 % There's a $*$ version which omits numbers.  This is easy too.  Lots of
5432 % hacking with expansion here to try and reduce the number of tokens being
5433 % used.  Is it worth it?
5434 %
5435 %    \begin{macrocode}
5436 \expandafter\edef\csname eqlines*\endcsname{%
5437   \expandafter\noexpand\csname eqnarray*\endcsname[x]%
5438 }
5439 \expandafter\let\csname endeqlines*\expandafter\endcsname
5440                 \csname endeqnarray*\endcsname
5441 %    \end{macrocode}
5442 %
5443 % \end{environment}
5444 %
5445 %
5446 % \subsection{Split equations}
5447 %
5448 % Based on an idea from \textit{The \TeX book}, we provide some simple
5449 % environments for doing split equations.  There's plenty of scope for
5450 % improvement here, though.
5451 %
5452 % \begin{environment}{spliteqn}
5453 % \begin{environment}{spliteqn*}
5454 %
5455 % The only difference between these two is that the $*$-version doesn't put
5456 % in an equation number by default (although this behaviour can be
5457 % changed by |\eqnumber|).
5458 %
5459 % The fun here mainly concerns putting in the equation number at the right
5460 % place -- for |leqno| users, we need to put the number on the first line;
5461 % otherwise we put it on the last line.
5462 %
5463 % The way we handle this is to have two macros, |\\| (which clearly does
5464 % all the user line breaks) and |\seq@lastcr| which is used at the end of
5465 % the environment to wrap everything up.  The |\seq@eqnocr| macro puts an
5466 % equation number on the current line and then does a normal |\\|.  It also
5467 % resets |\\| and |\seq@lastcr| so that they don't try to put another
5468 % equation number in.  This must be done globally, although anyone who tries
5469 % to nest maths displays will get what they deserve.
5470 %
5471 % For the non-$*$ environment, then, we need to step the equation counter,
5472 % and set |\\| to |\seq@cr| or |\seq@eqnocr| as appropriate for the setting
5473 % of the |leqno| flag -- |\seq@lastcr| always gets set to put an equation
5474 % number in (because it will be reset if the number actually gets done
5475 % earlier -- this catches stupid users trying to put a single row into
5476 % a split environment).
5477 %
5478 %    \begin{macrocode}
5479 \def\spliteqn{%
5480   \let\eqa@oldnumber\eqa@number%
5481   \global\let\eqa@number\eqa@eqcount%
5482   \spliteqn@i%
5483 }
5484 %    \end{macrocode}
5485 %
5486 % For the $*$ variant, we don't need to bother with equation numbering, so
5487 % this is really easy.
5488 %
5489 %    \begin{macrocode}
5490 \@namedef{spliteqn*}{%
5491   \let\eqa@oldnumber\eqa@number%
5492   \gdef\eqa@number{}%
5493   \spliteqn@i%
5494 }
5495 %    \end{macrocode}
5496 %
5497 % Ending the environments is easy.  Most of the stuff here will be described
5498 % later.
5499 %
5500 %    \begin{macrocode}
5501 \def\endspliteqn{%
5502   \hfilneg\seq@lastcr%
5503   \egroup%
5504   \dsp@end%
5505   \global\let\eqa@number\eqa@oldnumber%
5506   \global\advance\c@equation\m@ne%
5507   \global\@ignoretrue%
5508 }
5509 \expandafter\let\csname endspliteqn*\endcsname\endspliteqn
5510 %    \end{macrocode}
5511 %
5512 % \end{environment}
5513 % \end{environment}
5514 %
5515 % \begin{macro}{\spliteqn@i}
5516 %
5517 % Here we handle the full display splits.  Start a maths display, and make
5518 % each row of the alignment take up the full display width.
5519 %
5520 % The macro |\seq@dosplit| does most of the real work for us -- setting up
5521 % the alignment and so forth.  The template column is interesting.  There
5522 % are two items glue on both sides of the actual text:
5523 %
5524 % \begin{itemize}
5525 %
5526 % \item Some glue which can shrink.  This keeps the display from the edges
5527 %       of the page unless we get a really wide item.
5528 %
5529 % \item An |\hfil| to do the alignment.  By default, this centres the
5530 %       equations.  On the first line, however, we put a leading |\hfilneg|
5531 %       which cancels the first |\hfil|, making the first row left aligned.
5532 %       Similarly, at the end, we put an |\hfilneg| after the last equation
5533 %       to right align the last line.
5534 %
5535 % \end{itemize}
5536 %
5537 % We pass this information on as an argument.  It's easy really.
5538 %
5539 %    \begin{macrocode}
5540 \def\spliteqn@i{%
5541 %    \end{macrocode}
5542 %
5543 % First, set up equation numbering properly.  See my rant about
5544 % |\refstepcounter| above.
5545 %
5546 %    \begin{macrocode}
5547   \stepcounter{equation}%
5548   \def\@currentlabel{\p@equation\theequation}%
5549 %    \end{macrocode}
5550 %
5551 % Right; now to sort out the numbering and newline handling.  If the number's
5552 % meant to be on the first line (for \textsf{leqno} users), then it gets
5553 % typeset on the first like; otherwise we just do a normal newline on
5554 % all lines except the first.  Once |\seq@eqnocr| has done its stuff, it
5555 % redefines all the newline handling not to insert another number.
5556 %
5557 %    \begin{macrocode}
5558   \if@leqno%
5559     \global\let\seq@docr\seq@eqnocr%
5560   \else%
5561     \global\let\seq@docr\seq@cr%
5562   \fi%
5563   \global\let\seq@lastcr\seq@eqnocr%
5564 %    \end{macrocode}
5565 %
5566 % For my next trick, I'll do some display handling -- start a (possibly
5567 % nested) maths display, set up the |\tabpause| macro appropriately, and
5568 % set the newline command to do the right thing.
5569 %
5570 %    \begin{macrocode}
5571   \dsp@start%
5572   \dsp@tabpause%
5573   \def\\{\seq@docr}%
5574 %    \end{macrocode}
5575 %
5576 % Finally, call another macro to do the remaining bits of setting up.
5577 %
5578 %    \begin{macrocode}
5579   \seq@dosplit%
5580     {\hb@xt@\displaywidth{%
5581       \hskip\splitleft\hfil$\displaystyle##$%
5582       \hfil\hskip\splitright}}%
5583     {\hfilneg}%
5584 }
5585 %    \end{macrocode}
5586 %
5587 % \end{macro}
5588 %
5589 % \begin{environment}{subsplit}
5590 %
5591 % For doing splits in the middle of equations, we provide a similar
5592 % environment.  Here, we make |\\| just start a new line.  We also use
5593 % a |\vcenter| rather than a full maths display.  The glue items are also
5594 % a bit different: we use plain double-quads on each side of the item, and
5595 % we need to remove them by hand at the extremities of the environment.
5596 %
5597 %    \begin{macrocode}
5598 \def\subsplit{\@ifnextchar[\subsplit@i{\subsplit@i[c]}}
5599 \def\subsplit@i[#1]{%
5600   \let\@tempa\vcenter%
5601   \if#1t\let\@tempa\vtop\fi%
5602   \if#1b\let\@tempa\vbox\fi%
5603   \let\\\seq@cr%
5604   \@tempa\bgroup%
5605   \seq@dosplit{\hfil\qquad$##$\qquad\hfil}{\hfilneg\hskip-2em}%
5606 }
5607 %    \end{macrocode}
5608 %
5609 % Ending the environment is fairly easy.  We remove the final glue item,
5610 % and close the alignment and the vbox.
5611 %
5612 %    \begin{macrocode}
5613 \def\endsubsplit{%
5614   \hfilneg\hskip-2em\cr%
5615   \egroup\egroup%
5616 }
5617 %    \end{macrocode}
5618 %
5619 % \end{environment}
5620 %
5621 % \begin{macro}{\seq@dosplit}
5622 %
5623 % Here we do most of the real work.  Actually, since the preamble is passed
5624 % in as an argument, most of the work is already done.  The only thing to
5625 % really note is the template for subsequent columns.  To stop users putting
5626 % in extra columns (which is where we put the equation number) we raise an
5627 % error and discard the input in a scratch box register.  This template is
5628 % repeated infinitely so as to allow us to put the equation number in nicely.
5629 % However, the final negative glue item won't work properly, so the equation
5630 % will look awful.
5631 %
5632 %    \begin{macrocode}
5633 \def\seq@dosplit#1#2{%
5634   \halign\bgroup%
5635     #1&&\mth@err@number\setbox\z@\hbox{##}\cr%
5636   #2\relax%
5637 }
5638 %    \end{macrocode}
5639 %
5640 % \end{macro}
5641 %
5642 % \begin{macro}{\seq@eqnocr}
5643 %
5644 % Here's how we set equation numbers.  Since the column provided raises
5645 % errors as soon as a token finds its way into it, we start with a |&\omit|.
5646 % Then we just put the equation number in a zero-width box.  Finally, we
5647 % reset the newline commands to avoid putting in more than one equation
5648 % number, and do normal newline things.
5649 %
5650 %    \begin{macrocode}
5651 \def\seq@eqnocr{%
5652   &\omit%
5653   \hb@xt@\z@{\hss\eqa@eqpos\eqa@number}%
5654   \global\let\seq@docr\seq@cr%
5655   \global\let\seq@lastcr\seq@cr%
5656   \seq@cr%
5657 }
5658 %    \end{macrocode}
5659 %
5660 % \end{macro}
5661 %
5662 % \begin{macro}{\seq@cr}
5663 %
5664 % Newlines are very easy.  We add a |\jot| of extra space, since this is
5665 % a nice thing to do.
5666 %
5667 %    \begin{macrocode}
5668 \def\seq@cr{\tab@cr\seq@cr@i\interdisplaylinepenalty\@M}
5669 \def\seq@cr@i#1#2{\cr\noalign{\penalty#2\vskip\jot\vskip#1}}
5670 %    \end{macrocode}
5671 %
5672 % \end{macro}
5673 %
5674 %
5675 % \subsection{Matrix handling}
5676 %
5677 % There's been a complete and total overhaul of the spacing calculations
5678 % for matrices here.  The vertical spacing now bears an uncanny similarity
5679 % to the rules \TeX\ uses to space out |\atop|-like fractions, the difference
5680 % being that you can have more than one column in a matrix.  This has the
5681 % interesting side-effect that we get an \package{amsmath}-style
5682 % sub/superscript environment almost free of charge with the matrix handling
5683 % (it just ends up being a script-size single-column matrix).
5684 %
5685 % What is rather gratifying is that our \env{matrix} environment looks
5686 % rather nicer than \package{amsmath}'s (which is based directly on
5687 % \env{array}, giving it nasty restrictions on the numbers of columns and
5688 % so on); in particular, the version here gives the `correct' result for
5689 % Knuth's exercise~18.42 (which states categorically that a |\smallskip|
5690 % should be placed between the rows of the big matrix).
5691 %
5692 % The reason the interrow space doesn't come out in the AMS version is
5693 % that \env{array} inserts extra vertical space by extending the depth of
5694 % the final row using a strut: the big matrix already extends deeper than
5695 % this, so the strut doesn't make any difference.  If the space was added
5696 % by |\hlx{s[\smallskipamount]}| instead of the |\\| command, things would
5697 % be different.
5698 %
5699 % \begin{figure}
5700 %
5701 % ^^A This is essentially what amsmath (version 1.2b) does.  The real
5702 % ^^A implementation requires a counter MaxMatrixCols, and has fewer braces:
5703 % ^^A that's all the difference.  Oh, and I turn off \arrayextrasep here,
5704 % ^^A since amsmath doesn't expect it to be there (accurate emulation, see?)
5705 % ^^A and I've used \hspace instead of \hskip since everything else is
5706 % ^^A `proper' LaTeX stuff.
5707 %
5708 % \newenvironment{ams-pmatrix}{^^A
5709 %   \setlength{\arrayextrasep}{0pt}^^A
5710 %   \left(^^A
5711 %   \hspace{-\arraycolsep}^^A
5712 %   \begin{array}{*{10}{c}}^^A
5713 % }{^^A
5714 %  \end{array}^^A
5715 %  \hspace{-\arraycolsep}^^A
5716 %  \right)^^A
5717 % }
5718 %
5719 % \begin{demo}{Exercise 18.42 from \emph{The \TeX book}}
5720 %\newcommand{\domatrix}[1]{
5721 %  \def\mat##1
5722 %    {\begin{#1}##1\end{#1}}
5723 %  \[ \begin{#1}
5724 %     \mat{a & b \\ c & d} &
5725 %     \mat{e & f \\ g & h}
5726 %     \\[\smallskipamount]
5727 %     0 &
5728 %     \mat{i & j \\ k & l}
5729 %     \end{#1}
5730 %  \]
5731 %}
5732 %\domatrix{pmatrix}
5733 %\domatrix{ams-pmatrix}
5734 % \end{demo}
5735 %
5736 % \end{figure}
5737 %
5738 % \begin{environment}{genmatrix}
5739 %
5740 % The first job is to store my maths style and font away, because I'll be
5741 % needing it lots later.
5742 %
5743 %    \begin{macrocode}
5744 \def\genmatrix#1#2#3#4#5{%
5745   \let\mat@style#1%
5746   \ifx#2\scriptstyle%
5747     \let\mat@font\scriptfont%
5748   \else\ifx#2\scriptscriptstyle%
5749     \let\mat@font\scriptscriptfont%
5750   \else%
5751     \let\mat@font\textfont%
5752   \fi\fi%
5753 %    \end{macrocode}
5754 %
5755 % Now to cope with inserted text.  This is easy.
5756 %
5757 %    \begin{macrocode}
5758   \ifx\mat@style\scriptstyle%
5759     \let\mat@textsize\scriptsize%
5760   \else\ifx\mat@style\scriptscriptstyle%
5761     \let\mat@textsize\scriptscriptsize%
5762   \else%
5763     \let\mat@textsize\relax%
5764   \fi\fi%
5765 %    \end{macrocode}
5766 %
5767 % Now for some fun.  I'll remember how to start and end the matrix in a
5768 % couple of macros |\mat@left| and |\mat@right|.  I haven't yet worked out
5769 % exactly what needs to be in |\mat@right| yet, though, so I'll build that
5770 % up in a scratch token list while I'm making my mind up.
5771 %
5772 % Initially, I want to open a group (to trap the style changes), set the
5773 % maths style (to get the right spacing), insert the left delimiter, insert
5774 % some spacing around the matrix, and start a centred box.  The ending just
5775 % closes all the groups and delimiters I opened.
5776 %
5777 %    \begin{macrocode}
5778   \def\mat@left{\bgroup\mat@style\left#4#3\vcenter\bgroup}%
5779   \toks@{\egroup#3\right#5\egroup}%
5780 %    \end{macrocode}
5781 %
5782 % Now comes a slightly trickier bit.  If the maths style is script or
5783 % scriptscript, then I need to raise the box by a little bit to make it look
5784 % really good.  The right amount is somewhere around \smallf 3/4\,pt, I
5785 % think, so that's what I'll use.
5786 %
5787 %    \begin{macrocode}
5788   \@tempswatrue%
5789   \ifx\mat@style\displaystyle\else\ifx\mat@style\textstyle\else%
5790     \@tempswafalse%
5791     \setbox\z@\hbox\bgroup$%
5792     \toks@\expandafter{\the\toks@$\m@th\egroup\raise.75\p@\box\z@}%
5793   \fi\fi%
5794 %    \end{macrocode}
5795 %
5796 % If I'm not in maths mode right now, then I should enter maths mode, and
5797 % remember to leave it later.
5798 %
5799 %    \begin{macrocode}
5800   \if@tempswa\ifmmode\else%
5801     $\m@th%
5802     \toks@\expandafter{\the\toks@$}%
5803   \fi\fi%
5804 %    \end{macrocode}
5805 %
5806 % Now I've sorted out how to end the environment properly, so I can set up
5807 % the macro, using |\edef|.
5808 %
5809 %    \begin{macrocode}
5810   \edef\mat@right{\the\toks@}%
5811 %    \end{macrocode}
5812 %
5813 % Now see if there's an optional argument.  If not, create lots of centred
5814 % columns.
5815 %
5816 %    \begin{macrocode}
5817   \@testopt\genmatrix@i{[c}%
5818 }
5819 %    \end{macrocode}
5820 %
5821 % Now to sort out everything else.
5822 %
5823 %    \begin{macrocode}
5824 \def\genmatrix@i[#1]{%
5825 %    \end{macrocode}
5826 %
5827 % Some initial setting up: choose the correct column set, and set up some
5828 % variables for reading the preamble.
5829 %
5830 %    \begin{macrocode}
5831   \colset{matrix}%
5832   \tab@initread%
5833 %    \end{macrocode}
5834 %
5835 % Now comes some of the tricky stuff.  The space between columns should be
5836 % 12\,mu (by trial and error).  We put the space in a box so we can measure
5837 % it in the correct mathstyle.
5838 %
5839 %    \begin{macrocode}
5840   \setbox\z@\hbox{$\mat@style\mskip12mu$}%
5841   \edef\tab@tabtext{&\kern\the\wd\z@}%
5842   \tab@readpreamble{#1}%
5843 %    \end{macrocode}
5844 %
5845 % Now we need to decide how to space out the rows.  The code here is based
5846 % on the information in appendix~G of \emph{The \TeX book}: I think it'd be
5847 % nice if my matrices were spaced out in the same way as normal fractions
5848 % (particularly |\choose|y things).  The standard |\baselineskip| and
5849 % |\lineskip| parameters come in really handy here.
5850 %
5851 % The parameters vary according to the size of the text, so I need to see
5852 % if we have scriptsize or less, or not.  The tricky |\if| sorts this out.
5853 %
5854 %    \begin{macrocode}
5855   \if1\ifx\mat@style\scriptstyle1\else%
5856       \ifx\mat@style\scriptscriptstyle1\else0\fi\fi%
5857     \baselineskip\fontdimen10\mat@font\tw@%
5858     \advance\baselineskip\fontdimen12\mat@font\tw@%
5859     \lineskip\thr@@\fontdimen8\mat@font\thr@@%
5860   \else%
5861     \baselineskip\fontdimen8\mat@font\tw@%
5862     \advance\baselineskip\fontdimen11\mat@font\tw@%
5863     \lineskip7\fontdimen8\mat@font\thr@@%
5864   \fi%
5865   \lineskiplimit\lineskip%
5866 %    \end{macrocode}
5867 %
5868 % Now actually set up for the alignment.  Assign |\\| to the correct value.
5869 % Set up the |\tabskip|.  Do the appropriate |\mat@left| thing set up above.
5870 % And then start the alignment.
5871 %
5872 %    \begin{macrocode}
5873   \let\\\mat@cr%
5874   \tabskip\z@skip%
5875   \col@sep\z@%
5876   \mat@left%
5877   \halign\expandafter\bgroup\the\tab@preamble\tabskip\z@skip\cr%
5878 %    \end{macrocode}
5879 %
5880 % Now for a little hack to make the spacing consistent between matrices of
5881 % the same height.  This comes directly from \PlainTeX.  This appears to
5882 % make the spacing \emph{exactly} the same as the \TeX\ primitives, oddly
5883 % enough.
5884 %
5885 %    \begin{macrocode}
5886   \ifx\mat@font\textfont%
5887     \omit$\mat@style\mathstrut$\cr\noalign{\kern-\baselineskip}%
5888   \fi%
5889 }
5890 %    \end{macrocode}
5891 %
5892 % Finishing the environment is really easy.  We do the spacing hack again
5893 % at the bottom, close the alignment and then tidy whatever we started in
5894 % |\mat@left|.
5895 %
5896 %    \begin{macrocode}
5897 \def\endgenmatrix{%
5898   \crcr%
5899   \ifx\mat@font\textfont%
5900     \omit$\mat@style\mathstrut$\cr\noalign{\kern-\baselineskip}%
5901   \fi%
5902   \egroup%
5903   \mat@right%
5904 }
5905 %    \end{macrocode}
5906 %
5907 % \end{environment}
5908 %
5909 % \begin{macro}{\mat@cr}
5910 %
5911 % Newlines are really easy.  The $*$-form means nothing here, so we ignore
5912 % it.
5913 %
5914 %    \begin{macrocode}
5915 \def\mat@cr{\tab@cr\mat@cr@i{}{}}
5916 \def\mat@cr@i#1{\cr\noalign{\vskip#1}\@gobble}
5917 %    \end{macrocode}
5918 %
5919 % \end{macro}
5920 %
5921 % \begin{macro}{\newmatrix}
5922 %
5923 % This is how we define new matrix environments.  It's simple fun with
5924 % |\csname| and |\expandafter|.
5925 %
5926 %    \begin{macrocode}
5927 \def\newmatrix#1#2{%
5928   \@namedef{#1}{\genmatrix#2}%
5929   \expandafter\let\csname end#1\endcsname\endgenmatrix%
5930 }
5931 %    \end{macrocode}
5932 %
5933 % \end{macro}
5934 %
5935 % \begin{environment}{matrix}
5936 % \begin{environment}{pmatrix}
5937 % \begin{environment}{dmatrix}
5938 % \begin{environment}{smatrix}
5939 % \begin{environment}{spmatrix}
5940 % \begin{environment}{sdmatrix}
5941 % \begin{environment}{smatrix*}
5942 % \begin{environment}{spmatrix*}
5943 % \begin{environment}{sdmatrix*}
5944 %
5945 % Now we define all the other environments we promised.  This is easy.
5946 %
5947 %    \begin{macrocode}
5948 \newmatrix{matrix}{{\textstyle}{\textstyle}{\,}{.}{.}}
5949 \newmatrix{pmatrix}{{\textstyle}{\textstyle}{\,}{(}{)}}
5950 \newmatrix{dmatrix}{{\textstyle}{\textstyle}{\,}}
5951 \newmatrix{smatrix}{{\scriptstyle}{\scriptstyle}{}{.}{.}}
5952 \newmatrix{spmatrix}{{\scriptstyle}{\scriptstyle}{}{(}{)}}
5953 \newmatrix{sdmatrix}{{\scriptstyle}{\scriptstyle}{}}
5954 \newmatrix{smatrix*}{{\scriptstyle}{\textstyle}{}{.}{.}}
5955 \newmatrix{spmatrix*}{{\scriptstyle}{\textstyle}{}{(}{)}}
5956 \newmatrix{sdmatrix*}{{\scriptstyle}{\textstyle}{}}
5957 %    \end{macrocode}
5958 %
5959 % \end{environment}
5960 % \end{environment}
5961 % \end{environment}
5962 % \end{environment}
5963 % \end{environment}
5964 % \end{environment}
5965 % \end{environment}
5966 % \end{environment}
5967 % \end{environment}
5968 %
5969 % \begin{environment}{script}
5970 %
5971 % Now for superscripts and subscripts.  This is fairly easy, because I
5972 % took so much care over the matrix handling.
5973 %
5974 %    \begin{macrocode}
5975 \def\script{%
5976   \let\mat@style\scriptstyle%
5977   \def\mat@left{\vcenter\bgroup}%
5978   \def\mat@right{\egroup}%
5979   \let\mat@font\scriptfont%
5980   \let\mat@textsize\scriptsize%
5981   \@testopt\genmatrix@i c%
5982 }
5983 \let\endscript\endgenmatrix
5984 %    \end{macrocode}
5985 %
5986 % \end{environment}
5987 %
5988 % Now define the column types.
5989 %
5990 %    \begin{macrocode}
5991 \colpush{matrix}
5992 \coldef l{\tabcoltype{\kern\z@$\mat@style}{\m@th$\hfil}}
5993 \coldef c{\tabcoltype{\hfil$\mat@style}{\m@th$\hfil}}
5994 \coldef r{\tabcoltype{\hfil$\mat@style}{\m@th$}}
5995 \coldef T#1{\tab@aligncol{#1}{\begingroup\mat@textsize}{\endgroup}}
5996 \collet > [tabular]>
5997 \collet < [tabular]<
5998 \collet * [tabular]*
5999 \collet @ [tabular]@
6000 %    \end{macrocode}
6001 %
6002 % The repeating type is more awkward.  Things will go wrong if this is
6003 % given before the first column, so we must do a whole repeat by hand.  We
6004 % can tell if we haven't contributed a column yet, since |\tab@column| will
6005 % be zero.  Otherwise, we fiddle the parser state to start a new column, and
6006 % insert the |&| character to make \TeX\ repeat the preamble.
6007 %
6008 %    \begin{macrocode}
6009 \coldef {[}{%
6010   \@firstoftwo{%
6011     \ifnum\tab@columns=\z@%
6012       \def\@tempa##1\q@delim{%
6013         \tab@mkpreamble##1[##1\q@delim%
6014       }%
6015       \expandafter\@tempa%
6016     \else%
6017       \tab@setstate\tab@prestate%
6018       \tab@append\tab@preamble{&}%
6019       \expandafter\tab@mkpreamble%
6020     \fi%
6021   }%
6022 }
6023 %    \end{macrocode}
6024 %
6025 % We're done defining columns now.
6026 %
6027 %    \begin{macrocode}
6028 \colpop
6029 %    \end{macrocode}
6030 %
6031 %
6032 % \subsection{Dots\dots}
6033 %
6034 % Nothing whatsoever to do with alignments, although vertical and diagonal
6035 % dots in small matrices look really silly.  The following hacky definitions
6036 % work rather better.
6037 %
6038 % \begin{macro}{\mdw@dots}
6039 %
6040 % First of all, here's some definitions common to both of the dots macros.
6041 % The macro takes as an argument the actual code to draw the dots, passing
6042 % it the scaled size of a point in the scratch register |\dimen@|; the
6043 % register |\box 0| is set to contain a dot of the appropriate size.
6044 %
6045 %    \begin{macrocode}
6046 \def\mdw@dots#1{\ensuremath{\mathpalette\mdw@dots@i{#1}}}
6047 \def\mdw@dots@i#1#2{%
6048   \setbox\z@\hbox{$#1\mskip1.8mu$}%
6049   \dimen@\wd\z@%
6050   \setbox\z@\hbox{$#1.$}%
6051   #2%
6052 }
6053 %    \end{macrocode}
6054 %
6055 % \end{macro}
6056 %
6057 % \begin{macro}{\vdots}
6058 %
6059 % I'll start with the easy one.  This is a simple translation of the original
6060 % implementation.
6061 %
6062 %    \begin{macrocode}
6063 \def\vdots{%
6064   \mdw@dots{\vbox{%
6065     \baselineskip4\dimen@%
6066     \lineskiplimit\z@%
6067     \kern6\dimen@%
6068     \copy\z@\copy\z@\box\z@%
6069   }}%
6070 }
6071 %    \end{macrocode}
6072 %
6073 % \end{macro}
6074 %
6075 % \begin{macro}{\ddots}
6076 %
6077 % And I'll end with the other easy one\dots
6078 %
6079 %    \begin{macrocode}
6080 \def\ddots{%
6081   \mdw@dots{\mathinner{%
6082     \mkern1mu%
6083     \raise7\dimen@\vbox{\kern7\dimen@\copy\z@}%
6084     \mkern2mu%
6085     \raise4\dimen@\copy\z@%
6086     \mkern2mu%
6087     \raise\dimen@\box\z@%
6088     \mkern1mu%
6089   }}%
6090 }
6091 %    \end{macrocode}
6092 %
6093 % \end{macro}
6094 %
6095 %
6096 % \subsection{Lucky dip}
6097 %
6098 % Time to round off with some trivial environments, just to show how easy
6099 % this stuff is.
6100 %
6101 % \begin{environment}{cases}
6102 % \begin{environment}{smcases}
6103 %
6104 % These are totally and utterly trivial.
6105 %
6106 %    \begin{macrocode}
6107 \def\cases{\left\{\,\array{@{}lTl@{}}}
6108 \def\endcases{\endarray\,\right.}
6109 \def\smcases{\left\{\smarray{@{}lTl@{}}}
6110 \def\endsmcases{\endsmarray\,\right.}
6111 %    \end{macrocode}
6112 %
6113 % \end{environment}
6114 % \end{environment}
6115 %
6116 % \subsection{Error messages}
6117 %
6118 % Some token saving:
6119 %
6120 %    \begin{macrocode}
6121 \def\mth@error{\PackageError{mathenv}}
6122 %    \end{macrocode}
6123 %
6124 % Now for the error messages.
6125 %
6126 %    \begin{macrocode}
6127 \def\mth@err@number{%
6128   \mth@error{Too many `&' characters found}{%
6129     You've put too many `&' characters in an alignment^^J%
6130     environment (like `eqnarray' or `spliteqn') and wandered^^J%
6131     into trouble.  I've gobbled the contents of that column^^J%
6132     and hopefully I can recover fairly easily.%
6133   }%
6134 }
6135 %    \end{macrocode}
6136 %
6137 %    \begin{macrocode}
6138 \def\mth@err@mdsp{%
6139   \mth@error{Can't do displays in nondisplay maths mode}{%
6140     You're trying to start a display environment, but you're^^J%
6141     in nondisplay maths mode.  The display will appear but^^J%
6142     don't blame me when it looks horrible.%
6143   }%
6144 }
6145 %    \end{macrocode}
6146 %
6147 %    \begin{macrocode}
6148 \def\mth@err@hdsp{%
6149   \mth@error{Can't do displays in LR mode}{%
6150     You're trying to start a display environment, but you're^^J%
6151     in LR (restricted horizontal) mode.  Everything will go^^J%
6152     totally wrong, so your best bet is to type `X', fix the^^J%
6153     mistake and start again.%
6154   }%
6155 }
6156 %    \end{macrocode}
6157 %
6158 % \vskip\parskip\vbox{ ^^A The best way I could find of keeping this lot
6159 %                      ^^A together, I'm afraid.
6160 % That's all there is.  Byebye.
6161 %
6162 %    \begin{macrocode}
6163 %</mathenv>
6164 %    \end{macrocode}
6165 % \nopagebreak
6166 %
6167 % \hfill Mark Wooding, \today
6168 % }
6169 %
6170 % \Finale
6171 %
6172 \endinput