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