mdwtools.tex, *.dtx: Provide a hack for setting `description' labels.
[mdwtools] / mdwtab.dtx
CommitLineData
86f6a31e 1% \begin{meta-comment}
2%
b57a27e1 3% $Id: mdwtab.dtx,v 1.3 2003/11/10 14:43:48 mdw Exp $
86f6a31e 4%
5% Another rewrite of the tabular environment, and maths alignments
6%
7% (c) 1996 Mark Wooding
8%
86f6a31e 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}
7abe48b3 35%<+mdwtab> [2003/08/24 1.10 Table typesetting with style]
86f6a31e 36%<+mathenv>\NeedsTeXFormat{LaTeX2e}
37%<+mathenv>\ProvidesPackage{mathenv}
7abe48b3 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]
86f6a31e 45% \end{meta-comment}
46%
7ef5ba2c 47% \CheckSum{3402}
86f6a31e 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}
7abe48b3 70\describespackage{mtcolour}
86f6a31e 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%
7abe48b3 225% \item David Carlisle's \package{colortbl} package entirely fails to work
226% with \package{mdwtab}. However, we now have colour support of our
eafdddad 227% own which is at times similar in style.
7abe48b3 228%
86f6a31e 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%
eafdddad 273% <tabular-env> ::= \[[
86f6a31e 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%
eafdddad 287% <preamble> ::= \[[
86f6a31e 288% <first-column>
289% \[ \< <column> \> \]
290% \]]
291%
292% <first-column> ::= \[[ \[ <rule> \] <column> \]]
293%
eafdddad 294% <column> ::= \[[
86f6a31e 295% \[ <spacing> \] \[ \< <user-pre-text> \> \] <column-type>
296% \[ \< <user-post-text> \> \] \[ <spacing> \] \[ <rule> \]
297% \]]
298%
eafdddad 299% <spacing> ::= \[[ "@" "{" <text> "}" \]]
86f6a31e 300%
7abe48b3 301% <user-pre-text> ::= \[[ \[ "?" \] ">" "{" <text> "}" \]]
86f6a31e 302%
eafdddad 303% <column-type> ::= \[[
86f6a31e 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%
7abe48b3 311% <user-post-text> ::= \[[ \[ "?" \] "<" "{" <text> "}" \]]
86f6a31e 312%
eafdddad 313% <rule> ::= \[[ \( "|" \\ "!" "{" <text> "}" \) \]]
86f6a31e 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}
eafdddad
MW
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.}
86f6a31e 340% "Ml", "Mc" and "Mr" & Left, centre and right aligned
eafdddad 341% equations.* \\ \hlx{.}
86f6a31e 342% "Tl", "Tc" and "Tr" & Left, centre and right aligned
eafdddad 343% text.* \\ \hlx{vhv.}
86f6a31e 344% "p{"<width>"}" & Top aligned paragraph with the given
eafdddad 345% width. \\ \hlx{.}
86f6a31e 346% "m{"<width>"}" & Vertically centred paragraph with
eafdddad 347% the given width. \\ \hlx{.}
86f6a31e 348% "b{"<width>"}" & Bottom aligned paragraph with the
eafdddad 349% given width. \\ \hlx{vhv.}
86f6a31e 350% "#{"<pre>"}{"<post>"}" & User defined column type:
eafdddad
MW
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{.}
7abe48b3 359% "$*["<params>"]" & Inserts a vertical rule of given
86f6a31e 360% width between columns; "*" selects
7abe48b3 361% "\arraythickrulewidth".* \\ \hlx{.}
eafdddad
MW
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{.}
7abe48b3 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.}
86f6a31e 374% "*{"<count>"}{"<chars>"}" & Inserts \<count>
eafdddad
MW
375% copies of the \<chars> into the
376% preamble. \\ \hlx{vhs}
86f6a31e 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}
86f6a31e 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{!}
7abe48b3 410% modifiers). It's now been given an optional argument which describes
411% parameters for the line. See section~\ref{sec:ruleparams}.
86f6a31e 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
7abe48b3 435% includes, based around \env{smarray}.} ^^A
86f6a31e 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}
eafdddad 449% <cline-cmd> ::= \[[
86f6a31e 450% "\\cline"
7abe48b3 451% \[ "*" \] \\ \[ "[" <rule-params> "]" \]
86f6a31e 452% "{" \< <number> \[ "-" <number> \] \\ "," \> "}"
453% \]]
454% \end{grammar}
455%
7abe48b3 456% The rules printed by |\cline| and |\hline| can be modified by rule
457% parameters: see section~\ref{sec:ruleparams}.
86f6a31e 458%
7abe48b3 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.
86f6a31e 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%
7abe48b3 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%
86f6a31e 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%
eafdddad 499% <vgap-cmd> ::= \[[
86f6a31e 500% "\\vgap" \[ "[" <which-cols> "]" \] "{" <length> "}"
501% \]]
502%
eafdddad 503% <which-cols> ::= \[[ \< <number> \[ "-" <number> \] \\ "," \> \]]
86f6a31e 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%
eafdddad 530% <hlx-cmd> ::= \[[
86f6a31e 531% "\\hlx"
7abe48b3 532% \[ "*" \] \[ "[" <rule-params> "]" \]
86f6a31e 533% "{"
534% \begin{rep}
535% \begin{stack}
536% "h" \\
537% \tok{"v["<which-cols>"]["<length>"]"} \\
7abe48b3 538% \tok{"z["<which-cols>"]["<length>"]"} \\
86f6a31e 539% \tok{"s["<length>"]"} \\
540% \tok{"c{"<which-cols>"}"} \\
541% "b" \\
542% \tok{"/["<number>"]"} \\
7abe48b3 543% \tok{"!{"<rule-params>"}"} \\
544% \tok{"?{"<stuff>"}"} \\
545% \tok{"+["<step>"]"} \\
86f6a31e 546% "."
547% \end{stack}
548% \end{rep}
549% "}"
550% \]]
551%
552% \end{grammar}
7abe48b3 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
e8e9e5d8 556% section~\ref{sec:ruleparams}.
86f6a31e 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%
7abe48b3 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
eafdddad
MW
573% \<rule-params>) rather than |\doublerulesep|. This is a good thing
574% to insert before a |\cline| row.
7abe48b3 575%
86f6a31e 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%
7abe48b3 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%
86f6a31e 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
e8e9e5d8 654% looks very odd.
86f6a31e 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%
7abe48b3 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%
78cdb9cc 716% \begin{description} \setdescriptionlabel{\ttfamily#1}
7abe48b3 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%
86f6a31e 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}
eafdddad
MW
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}
86f6a31e 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}
eafdddad 818% <colset-cmd> ::= \[[ "\\colset" "{" <set-name> "}" \]]
86f6a31e 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}
eafdddad
MW
834% <colpush-cmd> ::= \[[ "\\colpush" "{" <set-name> "}" \]]
835% <colpop-cmd> ::= \[[ "\\colpop" \]]
86f6a31e 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}
eafdddad 871% <coldef-cmd> ::= \[[
86f6a31e 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).
e8e9e5d8 892%
86f6a31e 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%
eafdddad 931% <collet-cmd> ::= \[[
86f6a31e 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}
eafdddad 1031% <tabcr-cmd> ::= \[[
86f6a31e 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%
7abe48b3 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> "}"
e8e9e5d8 1084% \[ "[" <left-overhang> "]"
7abe48b3 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%
86f6a31e 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%
eafdddad 1239% <eqa-column> ::= \[[
86f6a31e 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}
eafdddad
MW
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.}
86f6a31e 1271% "Tl", "Tc" and "Tr" & Left, centre and right aligned
eafdddad
MW
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.}
86f6a31e 1285% "*{"<count>"}{"<chars>"}" & Inserts \<count>
eafdddad
MW
1286% copies of the \<chars> into the
1287% preamble. \\ \hlx{vh}
86f6a31e 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]
eafdddad 1319% V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
86f6a31e 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 = \\
7abe48b3 1343% & a+b+c+d+e+{} \\
86f6a31e 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}
eafdddad
MW
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}
86f6a31e 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%
eafdddad 1630% <matrix-env> ::= \[[ <begin-matrix> <contents> <end-matrix> \]]
86f6a31e 1631%
1632% <begin-matrix> ::= \[[ "\\begin{matrix}" \[ "[" <matrix-cols> "]" \] \]]
1633%
eafdddad 1634% <matrix-cols> ::= \[[
86f6a31e 1635% \< \[ "[" \] \[ "T" \] \( "l" \\ "c" \\ "r" \) \>
1636% \]]
1637%
eafdddad 1638% <end-matrix> ::= \[[ "\\end{stack}" \]]
86f6a31e 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.
7abe48b3 1814% \item [\textsf{tabrow}] contains the row number in the table. It's a
1815% proper \LaTeX\ counter.
86f6a31e 1816% \end{description}
1817%
1818% \begin{macrocode}
1819\newcount\tab@state
1820\newcount\tab@columns
7abe48b3 1821\newcounter{tabrow}
86f6a31e 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
7abe48b3 1868\newif\iftab@colour
86f6a31e 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%
7abe48b3 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%
86f6a31e 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}
e8e9e5d8 1948%
86f6a31e 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.
e8e9e5d8 1955%
86f6a31e 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%
7abe48b3 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%
86f6a31e 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@%
7abe48b3 2021 \the\expandafter\tab@posttext%
2022 \tab@righttext%
86f6a31e 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}
eafdddad 2054% $\it tab\_state=tab\_loopState$; \\
86f6a31e 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}
eafdddad 2065% $\it do\_default(tab\_state)$; \\
86f6a31e 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%
7abe48b3 2105 \expandafter\tab@append\expandafter\tab@shortline%
2106 \expandafter{\tab@rightruletext}%
86f6a31e 2107 \tab@append\tab@shortline{&\omit}%
7abe48b3 2108 \expandafter\tab@append\expandafter\tab@shortline%
2109 \expandafter{\tab@leftruletext}%
86f6a31e 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
7abe48b3 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.
86f6a31e 2381%
2382% \begin{macrocode}
2383\def\tab@initread{%
7abe48b3 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{%
86f6a31e 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%
7abe48b3 2412% We clear the token lists to sensible values, mostly.
86f6a31e 2413%
2414% \begin{macrocode}
2415 \tab@preamble{}%
2416 \tab@shortline{}%
86f6a31e 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}
7abe48b3 2435
86f6a31e 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{%
7abe48b3 2448 \expandafter\tab@append\expandafter\tab@shortline%
2449 \expandafter{\tab@leftruletext}%
86f6a31e 2450 \tab@doreadpream{#1}%
2451 \iftab@initrule\global\tab@state\tab@prespcstate\fi%
2452 \tab@setstate\tab@rulestate%
7abe48b3 2453 \expandafter\tab@append\expandafter\tab@shortline%
2454 \expandafter{\tab@rightruletext}%
86f6a31e 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}
7abe48b3 2561\def\coldef{\@testopt\coldef@i\tab@colset}
86f6a31e 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}
7abe48b3 2578\def\collet{\@testopt\collet@i\tab@colset}
86f6a31e 2579\def\collet@i[#1]#2{%
2580 \@ifnextchar=%
2581 {\collet@ii[#1]{#2}}%
2582 {\collet@ii[#1]{#2}=}%
2583}
7abe48b3 2584\def\collet@ii[#1]#2={\@testopt{\collet@iii[#1]{#2}}\tab@colset}
86f6a31e 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}
7abe48b3 2604\def\newcolumntype#1{\@testopt{\nct@i{#1}}0}
86f6a31e 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.
7abe48b3 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.
86f6a31e 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}}
7abe48b3 2661\coldef c{\tabcoltype{\tab@halfhfil\tab@bgroup}{\tab@egroup\tab@halfhfil}}
86f6a31e 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%
7abe48b3 2675 \if#1c\tabcoltype{\tab@halfhfil#2}{#3\tab@halfhfil}\fi%
86f6a31e 2676 \if#1r\tabcoltype{\hfil#2}{#3}\fi%
2677}
2678% \end{macrocode}
2679%
2680% Now for the default rules.
2681%
2682% \begin{macrocode}
7abe48b3 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}
86f6a31e 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}}
7abe48b3 2714\coldef ?#1#2{%
2715 \ifx>#1\expandafter\tabuserpretype%
cd62ff5f 2716 \else\expandafter\tabuserposttype\fi%
7abe48b3 2717 {#2}%
2718 \tab@append\tab@shortline{#2}%
2719}
86f6a31e 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. This is really easy, and not
2729% at all like the original one.
2730%
2731% \begin{macrocode}
2732\coldef *#1#2{%
2733 \count@#1%
2734 \loop\ifnum\count@>0\relax%
2735 \tab@doreadpream{#2}%
2736 \advance\count@\m@ne%
2737 \repeat%
2738}
2739% \end{macrocode}
2740%
2741%
2742% \subsection{Paragraph handling}
2743%
2744% First of all, starting new paragraphs: the vbox token is already there, and
2745% we have the width as an argument.
2746%
2747% \begin{macro}{\tab@bpar}
2748%
2749% There are some gymnastics to do here to support lists which form the
2750% complete text of the parbox. One of the odd things I'll do here is to
2751% not insert a strut on the first line: instead, I'll put the text into a
2752% box register so that I can inspect it later. So that I have access to
2753% the height of the first line, I'll use a |\vtop| -- I can get at the
2754% final depth by using |\prevdepth|, so this seems to be the most general
2755% solution.
2756%
2757% \begin{macrocode}
2758\def\tab@bpar#1{%
2759 \bgroup%
2760 \setlength\hsize{#1}%
2761 \@arrayparboxrestore%
2762 \setbox\z@\vtop\bgroup%
2763 \global\@minipagetrue%
2764 \global\@noskipsecfalse%
2765 \everypar\expandafter{\the\everypar%
2766 \global\@minipagefalse%
2767 \everypar{}%
2768 }%
2769}
2770% \end{macrocode}
2771%
2772% \end{macro}
2773%
2774% \begin{macro}{\tab@epar}
2775%
2776% To end the paragraph, close the box. That sounds easy, doesn't it?
2777% I need to space out the top and bottom of the box so that it looks as if
2778% struts have been applied.
2779%
2780% \begin{macrocode}
2781\def\tab@epar{%
2782% \end{macrocode}
2783%
2784% Anyway, I should end the current paragraph if I'm still in horizontal
2785% mode. A simple |\par| will do this nicely. I'll also remove any trailing
2786% vertical glue (which may be left there by a list environment), because
2787% things will look very strange otherwise.
2788%
2789% \begin{macrocode}
2790 \ifhmode\@maybe@unskip\par\fi%
2791 \unskip%
2792% \end{macrocode}
2793%
2794% Now I'll look at the depth of the last box: if it's less deep than my
2795% special strut, I'll cunningly backpedal by a bit, and add a box with the
2796% appropriate depth. Since this will lie on the previous baseline, it won't
2797% alter the effective height of the box. There's a snag here. |\prevdepth|
2798% may be wrong for example if the last thing inserted was a rule, or the
7abe48b3 2799% box is just empty. Check for this specially. (Thanks to Rowland McDonnell
2800% for spotting this.)
86f6a31e 2801%
2802% \begin{macrocode}
2803 \ifdim\prevdepth>-\@m\p@\ifdim\prevdepth<\dp\@arstrutbox%
2804 \kern-\prevdepth%
2805 \nointerlineskip%
2806 \vtop to\dp\@arstrutbox{}%
2807 \fi\fi%
2808% \end{macrocode}
2809%
2810% I've finished the bottom of the box now: I'll close it, and start work on
2811% the top again.
2812%
2813% \begin{macrocode}
2814 \egroup%
2815% \end{macrocode}
2816%
2817% For top-alignment to work, the first item in the box must be another box.
2818% (This is why I couldn't just set |\prevdepth| at the beginning.) If the
2819% box isn't high enough, I'll add a box of the right height and then kern
2820% backwards so that the `real' first box ends up in the right place.
2821%
2822% \begin{macrocode}
2823 \ifdim\ht\z@<\ht\@arstrutbox%
2824 \vbox to\ht\@arstrutbox{}%
2825 \kern-\ht\z@%
2826 \fi%
2827 \unvbox\z@%
2828 \egroup%
2829}
2830% \end{macrocode}
2831%
2832% \end{macro}
2833%
2834%
2835% \subsection{Gentle persuasion}
2836%
2837% To persuade \package{longtable} to work, we emulate some features of
2838% the \package{array} way of doing things. It's a shame, but we have to do
2839% it, because \package{longtable} came first.
2840%
2841% Note the horribleness with the grouping here. In order to get everything
2842% expanded at the right time, |\@preamble| just replaces itself with the (not
2843% expanded!) preamble string, using |\the|. This means that the preamble
2844% string must be visible in the group just above us. Now,
2845% \package{longtable} (and \package{array} for that matter) does
2846% |\@mkpreamble| immediately after opening a new group. So all we need to do
2847% is close that group, do our stuff, and reopen the group again. (Evil
2848% laughter\dots)
2849%
2850% \begin{macrocode}
2851\def\@mkpream#1{%
2852 \endgroup%
2853 \colset{tabular}%
2854 \tab@initread%
2855 \def\tab@multicol{\@arstrut}%
2856 \tab@preamble{\tab@multicol}%
b1143cde
MW
2857 \let\tab@lefttext\tab@lefttexthook%
2858 \let\tab@righttext\tab@righttexthook%
2859 \let\tab@leftruletext\tab@leftruletexthook%
2860 \let\tab@rightruletext\tab@rightruletexthook%
2861 \def\tab@midtext{\tab@setcr\ignorespaces\@sharp\@sharp\@maybe@unskip}%
86f6a31e 2862 \tab@readpreamble{#1}%
2863 \gdef\@preamble{\the\tab@preamble}%
2864 \let\tab@bgroup\begingroup%
2865 \let\tab@egroup\endgroup%
2866 \begingroup%
2867}
2868% \end{macrocode}
2869%
86f6a31e 2870% \subsection{Debugging}
2871%
2872% This macro just parses a preamble and displays it on the terminal. It
2873% means I can see whether the thing's working.
2874%
2875% \begin{macrocode}
2876\def\showpream#1{%
2877 \tab@initread%
2878 \tab@readpreamble{#1}%
2879 \showthe\tab@preamble%
2880 \showthe\tab@shortline%
2881}
2882% \end{macrocode}
2883%
2884% A quick macro for showing column types.
2885%
2886% \begin{macrocode}
2887\def\showcol#1{%
2888 \expandafter\show\csname\tab@colset!col.\string#1\endcsname%
2889}
2890% \end{macrocode}
2891%
2892%
2893% \subsection{The \env{tabular} and \env{array} environments}
2894%
2895% This is where we define the actual environments which users play with.
2896%
2897% \subsubsection{The environment routines}
2898%
2899% The real work is done in the |\@array| macro later. We just set up lots
2900% (and I mean \emph{lots}) of parameters first, and then call |\@array|.
2901%
2902% \begin{macro}{\tab@array}
2903%
2904% The |\tab@array| macro does most of the common array things.
2905%
2906% \begin{macrocode}
2907\def\tab@array{%
2908 \tab@width\z@%
2909 \let\tab@bgroup\tab@bmaths%
2910 \let\tab@egroup\tab@emaths%
2911 \@tabarray%
2912}
2913% \end{macrocode}
2914%
2915% \end{macro}
2916%
2917% \begin{macro}{\tab@btext}
2918% \begin{macro}{\tab@bmaths}
2919% \begin{macro}{\tab@etext}
2920% \begin{macro}{\tab@emaths}
2921%
2922% These macros contain appropriate things to use when typesetting
2923% text or maths macros. They're all trivial. They're here only for
2924% later modification by funny things like the \env{smarray} environment.
2925%
2926% \begin{macrocode}
2927\def\tab@btext{\begingroup}
7abe48b3 2928\def\tab@bmaths{\color@begingroup$}
86f6a31e 2929\def\tab@etext{\endgroup}
7abe48b3 2930\def\tab@emaths{\m@th$\color@endgroup}
86f6a31e 2931% \end{macrocode}
2932%
2933% \end{macro}
2934% \end{macro}
2935% \end{macro}
2936% \end{macro}
2937%
2938% \begin{environment}{array}
2939%
2940% Now for the \env{array} environment. The `|$|' signs act as a group, so we
2941% don't need to do extra grouping this time. Closing the environment is
2942% easy.
2943%
2944% \begin{macrocode}
2945\def\array{%
2946 \col@sep\arraycolsep%
2947 \let\tab@extrasep\arrayextrasep%
2948 \tab@normalstrut%
2949 \tab@array%
2950}
2951\def\endarray{%
2952 \crcr%
2953 \egroup%
2954 \tab@right%
7abe48b3 2955 \endgroup%
86f6a31e 2956 \tab@restorehlstate%
7abe48b3 2957 \global\c@tabrow\count@%
2958 \def\@currentlabel{\p@tabrow\thetabrow}%
2959 \tab@endhook%
86f6a31e 2960}
2961% \end{macrocode}
2962%
2963% \end{environment}
2964%
2965% \begin{environment}{smarray}
2966%
2967% Now for something a little different. The \env{smarray} environment
2968% gives you an array with lots of small text.
2969%
2970% \begin{macrocode}
2971\def\smarray{%
2972 \extrarowheight\z@%
2973 \col@sep\smarraycolsep%
2974 \let\tab@extrasep\smarrayextrasep%
9d809eac 2975 \def\tab@bmaths{\color@begingroup$\scriptstyle}%
86f6a31e 2976 \def\tab@btext{\begingroup\scriptsize}%
2977 \setbox\z@\hbox{\scriptsize\strut}%
2978 \dimen@\ht\z@\dimen@ii\dp\z@\tab@setstrut%
2979 \tab@array%
2980}
2981\let\endsmarray\endarray
2982% \end{macrocode}
2983%
2984% \end{environment}
2985%
2986% \begin{macro}{\tabstyle}
2987%
2988% This is a little hook that document designers can use to modify the
2989% appearance of tables throughout a document. For example, I've set it to
2990% make the text size |\small| in all tables in this document. Macro writers
2991% shouldn't try to use it as a hook for their own evilness, though. I've
2992% used |\providecommand| to avoid nobbling an existing definition.
2993%
2994% \begin{macrocode}
2995\providecommand\tabstyle{}
2996% \end{macrocode}
2997%
2998% \end{macro}
2999%
3000% \begin{macro}{\@tabular}
3001%
3002% The two \env{tabular} environments share lots of common code, so we
3003% separate that out. (This needs to be done better.) All we really do here
3004% is set up the |\tab@bgroup| and |\tab@egroup| to localise things properly,
3005% and then go.
3006%
3007% \begin{macrocode}
3008\def\@tabular#1{%
3009 \tabstyle%
3010 \setlength\tab@width{#1}%
3011 \let\tab@bgroup\tab@btext%
3012 \let\tab@egroup\tab@etext%
3013 \col@sep\tabcolsep%
3014 \let\tab@extrasep\tabextrasep%
3015 \tab@normalstrut%
3016 \@tabarray%
3017}
3018% \end{macrocode}
3019%
3020% \end{macro}
3021%
3022% \begin{environment}{tabular}
3023% \begin{environment}{tabular*}
3024%
3025% These environments just call a macro which does all the common stuff.
3026%
3027% \begin{macrocode}
3028\def\tabular{\@tabular\z@}
3029\expandafter\let\csname tabular*\endcsname\@tabular
3030\let\endtabular\endarray
3031\expandafter\let\csname endtabular*\endcsname\endarray
3032% \end{macrocode}
3033%
3034% \end{environment}
3035% \end{environment}
3036%
3037% \subsubsection{Setting the strut height}
3038%
3039% \begin{macro}{\tab@setstrut}
3040%
3041% We use a magical strut, called |\@arstrut|, which keeps the table from
3042% collapsing around our heads. This is where we set it up.
3043%
3044% It bases the array strut size on the given values of |\dimen@| and
3045% |\dimen@ii|, amended by various appropriate fiddle values added in by
3046% various people.
3047%
3048% \begin{macrocode}
3049\def\tab@setstrut{%
3050 \setbox\@arstrutbox\hbox{%
3051 \vrule%
3052 \@height\arraystretch\dimen@%
3053 \@depth\arraystretch\dimen@ii%
3054 \@width\z@%
3055 }%
3056}
3057% \end{macrocode}
3058%
3059% \end{macro}
3060%
3061% \begin{macro}{\tab@normalstrut}
3062%
3063% This sets the strut the normal way, from the size of |\strutbox|.
3064%
3065% \begin{macrocode}
3066\def\tab@normalstrut{%
3067 \dimen@\ht\strutbox\advance\dimen@\extrarowheight%
3068 \dimen\tw@\dp\strutbox%
3069 \tab@setstrut%
3070}
3071% \end{macrocode}
3072%
3073% \end{macro}
3074%
3075% \subsubsection{Setting up the alignment}
3076%
3077% The following bits are mainly for other packages to hook themselves onto.
3078%
3079% \begin{macrocode}
7abe48b3 3080\let\@arrayleft\relax
3081\let\@arrayright\relax
3082\let\tab@beginhook\@empty
3083\let\tab@lefttexthook\@empty
3084\let\tab@righttexthook\@empty
3085\let\tab@leftruletexthook\@empty
3086\let\tab@rightruletexthook\@empty
3087\let\tab@endhook\@empty
3088% \end{macrocode}
3089%
3090% For setting these hooks, we provide some handy commands.
3091%
3092% \begin{macrocode}
3093\def\tab@addhookbefore#1#2{%
3094 \toks@{#2}\toks@\expandafter{\the\expandafter\toks@#1}%
3095 \edef#1{\the\toks@}%
3096}
3097\def\tab@addhookafter#1#2{%
3098 \toks@\expandafter{#1#2}%
3099 \edef#1{\the\toks@}%
3100}
86f6a31e 3101% \end{macrocode}
3102%
7abe48b3 3103% And now we get on with the real thing.
3104%
86f6a31e 3105% \begin{macrocode}
3106\def\@tabarray{%
3107 \let\@arrayleft\relax%
3108 \let\@arrayright\relax%
7abe48b3 3109 \@testopt\@array c%
86f6a31e 3110}
3111% \end{macrocode}
3112%
3113% \begin{macro}{\@array}
3114%
3115% The |\@array| macro does most of the real work for the environments. The
3116% first job is to set up the row strut, which keeps the table rows at the
3117% right height. We just take the normal strut box, and extend its height by
3118% the |\extrarowheight| length parameter.
3119%
3120% \begin{macrocode}
3121\def\@array[#1]#2{%
3122% \end{macrocode}
3123%
3124% Sort out the hline state variable. We'll store the old value in a
3125% control sequence to avoid wasting any more count registers.
3126%
3127% \begin{macrocode}
7abe48b3 3128 \tab@beginhook%
3129 \count@\c@tabrow%
3130 \global\c@tabrow\z@%
86f6a31e 3131 \edef\tab@restorehlstate{%
3132 \global\tab@endheight\the\tab@endheight%
3133 \gdef\noexpand\tab@hlstate{\tab@hlstate}%
3134 }%
7abe48b3 3135 \begingroup%
86f6a31e 3136 \def\tab@hlstate{n}%
3137% \end{macrocode}
3138%
3139% Now we read the preamble. All the clever things we've already done are
3140% terribly useful here.
3141%
3142% The |\tab@setcr| sets up |\\| to be a newline even if users have changed it
3143% using something like |\raggedright|.
3144%
3145% \begin{macrocode}
3146 \colset{tabular}%
3147 \tab@initread%
7abe48b3 3148 \let\tab@lefttext\tab@lefttexthook%
3149 \let\tab@righttext\tab@righttexthook%
3150 \let\tab@leftruletext\tab@leftruletexthook%
3151 \let\tab@rightruletext\tab@rightruletexthook%
86f6a31e 3152 \def\tab@midtext{\tab@setcr\ignorespaces####\@maybe@unskip}%
3153 \def\tab@multicol{\@arstrut\tab@startrow}%
3154 \tab@preamble{\tab@multicol\tabskip\z@skip}%
3155 \tab@readpreamble{#2}%
3156% \end{macrocode}
3157%
3158% Set up the default tabskip glue. This is easy: there isn't any.
3159%
3160% \begin{macrocode}
3161 \tab@leftskip\z@skip%
3162 \tab@rightskip\z@skip%
3163% \end{macrocode}
3164%
3165% Now set up the positioning of the table. This is put into a separate macro
3166% because it's rather complicated.
3167%
3168% \begin{macrocode}
3169 \tab@setposn{#1}%
3170% \end{macrocode}
3171%
3172% Now work out how to start the alignment.
3173%
3174% \begin{macrocode}
3175 \ifdim\tab@width=\z@%
3176 \def\tab@halign{}%
3177 \else%
3178 \def\tab@halign{to\tab@width}%
3179 \fi%
3180% \end{macrocode}
3181%
3182% Finally, do all the normal things we need to do before an alignment. Note
3183% that we define |\tabularnewline| first, then set |\\| from that (using
3184% |\tab@setcr|). Since |\\| is reset in the |\tab@midtext| of every table
3185% cell, it becomes secondary to |\tabularnewline|. Doing things this way
3186% avoids the problems with declarations like |\raggedright| which redefine
3187% |\\| in their own (usually rather strange) way, so you don't need to mess
3188% about with things like the |\PreserveBackslash| command given in the
3189% \textit{\LaTeX\ Companion}.
3190%
3191% \begin{macrocode}
3192 \lineskip\z@\baselineskip\z@%
3193 \m@th%
3194 \def\tabularnewline{\tab@arraycr\tab@penalty}%
3195 \tab@setcr%
3196 \let\par\@empty%
3197 \everycr{}\tabskip\tab@leftskip%
3198 \tab@left\halign\tab@halign\expandafter\bgroup%
3199 \the\tab@preamble\tabskip\tab@rightskip\cr%
3200}
3201% \end{macrocode}
3202%
3203% \end{macro}
3204%
3205% You've no doubt noticed the |\tab@left| and |\tab@right| macros above.
3206% These are set up here and elsewhere to allow other things to gain control
3207% at various points of the table (they include and take the place of the
3208% |\@arrayleft| and |\@arrayright| hooks in \package{array}, put in for
3209% \package{delarray}'s use.
3210%
3211% \subsubsection{Positioning the table}
3212%
3213% \begin{macro}{\tab@setposn}
3214%
3215% This macro sets everything up for the table's positioning. It's rather
3216% long, but not all that complicated. Honest.
3217%
3218% First, we set up some defaults (for centring). If anything goes wrong, we
3219% just do the centring things.
3220%
3221% \begin{macrocode}
3222\def\tab@setposn#1{%
3223 \def\tab@left{%
3224 \savenotes%
3225 \leavevmode\hbox\bgroup$\@arrayleft\vcenter\bgroup%
3226 }%
3227 \def\tab@right{%
3228 \egroup%
3229 \m@th\@arrayright$\egroup%
3230 \spewnotes%
3231 }%
3232 \global\tab@endheight\z@%
3233% \end{macrocode}
3234%
3235% For the standard positioning things, we just do appropriate boxing things.
3236% Note that the dollar signs are important, since \package{delarray} might
3237% want to put its delimiters in here.
3238%
3239% The |\if@tempswa| switch it used to decide if we're doing an unboxed
3240% tabular. We'll set it if we find an unbox-type position code, and then
3241% check that everything's OK for this.
3242%
3243% \begin{macrocode}
3244 \@tempswafalse%
3245 \let\tab@penalty\relax%
3246 \if#1t%
3247 \def\tab@left{%
3248 \savenotes%
3249 \leavevmode\setbox\z@\hbox\bgroup$\@arrayleft\vtop\bgroup%
3250 }%
3251 \def\tab@right{%
3252 \egroup%
3253 \m@th\@arrayright$\egroup%
3254 \tab@raisebase%
3255 \spewnotes%
3256 }%
3257 \gdef\tab@hlstate{t}%
3258 \global\tab@endheight\ht\@arstrutbox%
3259 \else\if#1b%
3260 \def\tab@left{%
3261 \savenotes%
3262 \leavevmode\setbox\z@\hbox\bgroup$\@arrayleft\vbox\bgroup%
3263 }%
3264 \def\tab@right{%
3265 \egroup%
3266 \m@th\@arrayright$\egroup%
3267 \tab@lowerbase%
3268 \spewnotes%
3269 }%
3270 \gdef\tab@hlstate{b}%
3271 \else%
3272 \if#1L\@tempswatrue\fi%
3273 \if#1C\@tempswatrue\fi%
3274 \if#1R\@tempswatrue\fi%
3275 \fi\fi%
3276% \end{macrocode}
3277%
3278% Now for some tests to make sure we're allowed to do the unboxing. We text
3279% for |\@arrayleft| being defined, because people trying to hook us won't
3280% understand unboxed tabulars.
3281%
3282% \begin{macrocode}
3283 \if@tempswa\ifhmode%
3284 \ifinner\tab@err@unbrh\@tempswafalse\else\par\fi%
3285 \fi\fi%
3286 \if@tempswa\ifmmode\tab@err@unbmm\@tempswafalse\fi\fi%
3287 \if@tempswa\ifx\@arrayleft\relax\else%
3288 \tab@err@unbext\@tempswafalse%
3289 \fi\fi%
3290% \end{macrocode}
3291%
3292% Finally, if we're still doing an unboxed alignment, we need to sort out the
3293% spacing. We know that no-one's tried to hook on to the environment, so we
3294% clear |\tab@left| and |\tab@right|.
3295%
3296% \begin{macrocode}
3297 \if@tempswa%
3298 \def\tab@left{\vskip\parskip\medskip}%
3299 \def\tab@right{\par\@endpetrue\global\@ignoretrue}%
3300% \end{macrocode}
3301%
3302% Now we need to sort out the alignment. The only way we can do this is by
3303% playing with tabskip glue. There are two possibilities:
3304%
3305% \begin{itemize}
3306%
3307% \item If this is a straight \env{tabular} or an \env{array}, we just use
3308% infinite glue. This is reasonable, I think.
3309%
3310% \item If we have a width for the table, we calculate the fixed values of
3311% glue on either side. This is fairly easy, and forces the table to
3312% the required width.
3313%
3314% \end{itemize}
3315%
3316% First, set up the left and right glues to represent the prevailing
3317% margins set up by \env{list} environments. I think this is the right
3318% thing to do.
3319%
3320% \begin{macrocode}
3321 \tab@leftskip\@totalleftmargin%
3322 \tab@rightskip\hsize%
3323 \advance\tab@rightskip-\linewidth%
3324 \advance\tab@rightskip-\@totalleftmargin%
3325% \end{macrocode}
3326%
3327% First of all, deal with the simple case. I'm using 10000\,fill glue here,
3328% in an attempt to suppress |\extracolsep| glue from making the table the
3329% wrong width. It can always use filll glue if it really needs to, though.
3330%
3331% \begin{macrocode}
3332 \ifdim\tab@width=\z@%
3333 \if#1L\else\advance\tab@leftskip\z@\@plus10000fill\fi%
3334 \if#1R\else\advance\tab@rightskip\z@\@plus10000fill\fi%
3335% \end{macrocode}
3336%
3337% Now for the fun bit. This isn't too hard really. The extra space I must
3338% add around the table adds up to $|\linewidth| - |\tab@width|$. I just
3339% need to add this onto the appropriate sides of the table.
3340%
3341% \begin{macrocode}
3342 \else%
3343 \dimen@\linewidth%
3344 \advance\dimen@-\tab@width%
3345 \if#1L\advance\tab@rightskip\dimen@\fi%
3346 \if#1R\advance\tab@leftskip\dimen@\fi%
3347 \if#1C%
3348 \advance\tab@leftskip.5\dimen@%
3349 \advance\tab@rightskip.5\dimen@%
3350 \fi%
3351 \fi%
3352% \end{macrocode}
3353%
3354% Don't allow page breaks. David Carlisle's wonderful \env{longtable}
3355% package does page breaks far better than I could possibly do here, and
3356% we're compatible with it (wahey!).
3357%
3358% \begin{macrocode}
3359 \def\tab@penalty{\penalty\@M}%
3360% \end{macrocode}
3361%
3362% Finally, set the new width of the table, and leave.
3363%
3364% \begin{macrocode}
3365 \tab@width\hsize%
3366 \fi%
3367}
3368% \end{macrocode}
3369%
3370% \end{macro}
3371%
3372% \subsubsection{Handling tops and bottoms}
3373%
3374% This is how the tops and bottoms of tables are made to line up with the
3375% text on the same line, in the presence of arbitrary rules and space. The
3376% old method, based on the way the \package{array} package worked, wasn't
3377% terribly good. This new version copes much better with almost anything
3378% that gets thrown at it.
3379%
3380% I'll keep a state in a macro (|\tab@hlstate|), which tells me what I'm
3381% meant to be doing. The possible values are \lit{n}, which means I don't
3382% have to do anything, \lit{t}, which means that I'm meant to be handling
3383% top-aligned tables, and \lit{b}, which means that I'm meant to be lining
3384% up the bottom. There are several other `substates' which have various
3385% magic meanings.
3386%
3387% \begin{macrocode}
3388\def\tab@hlstate{n}
3389% \end{macrocode}
3390%
3391% When all's said and done, I extract the box containing the table, and
3392% play with the height and depth to try and make it correct.
3393%
3394% \begin{macro}{\tab@addruleheight}
3395%
3396% This macro is called by `inter-row' things to add their height to our
3397% dimen register.
3398%
3399% Only do this if the state indicates that it's sensible.
3400%
3401% \begin{macrocode}
3402\def\tab@addruleheight#1{%
3403 \if\tab@hlstate n\else%
3404 \global\advance\tab@endheight#1\relax%
3405 \fi%
3406}
3407% \end{macrocode}
3408%
3409% \end{macro}
3410%
3411% \begin{macro}{\tab@startrow}
3412%
3413% This is called at the start of a row, from within the array preamble.
3414% Currently, this assumes that the rows aren't bigger than their struts:
3415% this is reasonable, although slightly limiting, and it could be done better
3416% if I was willing to rip the alignment apart and put it back together
3417% again.
3418%
3419% \begin{macrocode}
3420\def\tab@startrow{%
3421 \if\tab@hlstate t%
3422 \gdef\tab@hlstate{n}%
3423 \else\if\tab@hlstate b%
3424 \global\tab@endheight\dp\@arstrutbox%
3425 \fi\fi%
3426}
3427% \end{macrocode}
3428%
3429% \end{macro}
3430%
3431% \begin{macro}{\tab@raisebase}
3432%
3433% This macro is called at the end of it all, to set the height and depth
3434% of the box correctly. It sets the height to |\tab@endheight|, and the
3435% depth to everything else. The box is in |\box|~0 currently.
3436%
3437% \begin{macrocode}
3438\def\tab@raisebase{%
3439 \global\advance\tab@endheight-\ht\z@%
3440 \raise\tab@endheight\box\z@%
3441}
3442% \end{macrocode}
3443%
3444% \end{macro}
3445%
3446% \begin{macro}{\tab@lowerbase}
3447%
3448% And, for symmetry's sake, here's how to set the bottom properly instead.
3449%
3450% \begin{macrocode}
3451\def\tab@lowerbase{%
3452 \global\advance\tab@endheight-\dp\z@%
3453 \lower\tab@endheight\box\z@%
3454}
3455% \end{macrocode}
3456%
3457% \end{macro}
3458%
3459%
3460% \subsection{Breaking tables into bits}
3461%
3462% Unboxed tables have a wonderful advantage over boxed ones: you can stop
3463% halfway through and do something else for a bit. Here's how:
3464%
3465% \begin{macro}{\tabpause}
3466%
3467% I'd like to avoid forbidding catcode changes here. I'll use |\doafter|
3468% now I've got it, to ensure that colour handling and things occur
3469% \emph{inside} the |\noalign| (otherwise they'll mess up the alignment
3470% very seriously). We selectively include lots of stuff from
3471% |\arrayparboxrestore|.
3472%
3473% We have to be careful here to ensure that everything works correctly within
3474% lists. (The \package{amsmath} package had this problem in its
3475% |\intertext| macro, so I'm not alone here.)
3476%
3477% \begin{macrocode}
3478\def\tabpause#{%
3479 \noalign{\ifnum0=`}\fi%
3480 \let\if@nobreak\iffalse
3481 \let\if@noskipsec\iffalse
3482 \let\par\@@par
3483 \let\-\@dischyph
3484 \let\'\@acci\let\`\@accii\let\=\@acciii
3485 \everypar{}%
3486 \lineskip\normallineskip%
3487 \let\\\@normalcr%
7abe48b3 3488 \color@begingroup%
86f6a31e 3489 \tab@startpause%
3490 \vskip-\parskip%
3491 \parshape\@ne\@totalleftmargin\linewidth%
3492 \noindent%
3493 \doafter\tabpause@i%
3494}
3495\def\tabpause@i{%
3496 \nobreak%
3497 \tab@endpause%
7abe48b3 3498 \color@endgroup%
86f6a31e 3499 \ifnum0=`{\fi}%
3500}
3501% \end{macrocode}
3502%
3503% \end{macro}
3504%
3505%
3506% \subsection{The wonderful world of \cmd\multicolumn}
3507%
3508% \begin{macro}{\multicolumn}
3509%
3510% This is actually fantastically easy. Watch and learn. Make sure you
3511% notice the |\long|s here: remember that some table cells can contain
3512% paragraphs, so it seems sensible to allow |\par| into the argument.
3513% (As far as I know, most other |\multicolumn| commands don't do this,
3514% which seems a little silly. Then again, I forgot to do it the first
3515% time around.)
3516%
3517% \begin{macrocode}
3518\long\def\multicolumn#1#2#3{%
3519 \multispan{#1}%
3520 \begingroup%
3521 \tab@multicol%
7abe48b3 3522 \tab@initsubread%
86f6a31e 3523 \long\def\tab@midtext{#3}%
3524 \let\tab@looped\tab@err@multi%
3525 \tab@readpreamble{#2}%
3526 \the\tab@preamble%
3527 \endgroup%
3528 \ignorespaces%
3529}
3530% \end{macrocode}
3531%
3532% \end{macro}
3533%
3534%
3535% \subsection{Interlude: range lists}
3536%
3537% For processing arguments to |\vgap| and |\cline|, we need to be able to
3538% do things with lists of column ranges. To save space, and to make my
3539% fingers do less typing, here's some routines which do range handling.
3540%
3541% \begin{macro}{\ranges}
3542%
3543% Given a macro name and a comma separated list of ranges and simple numbers,
3544% this macro will call the macro giving it each range in the list in turn.
3545% Single numbers~$n$ will be turned into ranges $n$--$n$.
3546%
3547% The first job is to read the macro to do (which may already have some
3548% arguments attached to it). We'll also start a group to make sure that
3549% our changes to temp registers don't affect anyone else.
3550%
3551% There's a space before the delimiting |\q@delim| to stop numbers being
3552% parsed to far and expanding our quark (which will stop \TeX\ dead in its
3553% tracks). Since we use |\@ifnextchar| to look ahead, spaces in range lists
3554% are perfectly all right.
3555%
3556% \begin{macrocode}
3557\def\ranges#1#2{%
3558 \gdef\ranges@temp{#1}%
3559 \begingroup%
3560 \ranges@i#2 \q@delim%
3561}
3562% \end{macrocode}
3563%
3564%
3565% We're at the beginning of the list. We expect either the closing marker
3566% (if this is an empty list) or a number, which we can scoop up into a
3567% scratch register.
3568%
3569% \begin{macrocode}
3570\def\ranges@i{%
3571 \@ifnextchar\q@delim\ranges@done{\afterassignment\ranges@ii\count@}%
3572}
3573% \end{macrocode}
3574%
3575% We've read the first number in the range. If there's another number, we'll
3576% expect a `|-|' sign to be next. If there is no `|-|', call the user's code
3577% with the number duplicated and then do the rest of the list.
3578%
3579% \begin{macrocode}
3580\def\ranges@ii{%
3581 \@ifnextchar-\ranges@iii{\ranges@do\count@\count@\ranges@v}%
3582}
3583% \end{macrocode}
3584%
3585% Now we strip the `|-|' off and read the other number into a temporary
3586% register.
3587%
3588% \begin{macrocode}
3589\def\ranges@iii-{\afterassignment\ranges@iv\@tempcnta}
3590% \end{macrocode}
3591%
3592% We have both ends of the range now, so call the user's code, passing it
3593% both ends of the range.
3594%
3595% \begin{macrocode}
3596\def\ranges@iv{\ranges@do\count@\@tempcnta\ranges@v}
3597% \end{macrocode}
3598%
3599% We've finished doing an item now. If we have a `|,|' next, then start
3600% over with the next item. Otherwise, if we're at the end of the list,
3601% we can end happily. Finally, if we're totally confused, raise an
3602% error.
3603%
3604% \begin{macrocode}
3605\def\ranges@v{%
3606 \@ifnextchar,%
3607 \ranges@vi%
3608 {%
3609 \@ifnextchar\q@delim%
3610 \ranges@done%
3611 {\tab@err@range\ranges@vi,}%
3612 }%
3613}
3614% \end{macrocode}
3615%
3616% We had a comma, so gobble it, read the next number, and go round again.
3617%
3618% \begin{macrocode}
3619\def\ranges@vi,{\afterassignment\ranges@ii\count@}
3620% \end{macrocode}
3621%
3622% Here's how we call the user's code, now. We close the group, so that the
3623% user's code doesn't have to do global things to remember its results, and
3624% we expand the two range ends from their count registers. We also ensure
3625% that the range is the right way round.
3626%
3627% \begin{macrocode}
3628\def\ranges@do#1#2{%
3629 \ifnum#1>#2\else%
3630 \expandafter\endgroup%
3631 \expandafter\ranges@temp%
3632 \expandafter{%
3633 \the\expandafter#1%
3634 \expandafter}%
3635 \expandafter{%
3636 \the#2%
3637 }%
3638 \begingroup%
3639 \fi%
3640}
3641% \end{macrocode}
3642%
3643% And finishing the scan is really easy. We close the group after gobbling
3644% the close token.
3645%
3646% \begin{macrocode}
3647\def\ranges@done\q@delim{\endgroup}
3648% \end{macrocode}
3649%
3650% \end{macro}
3651%
3652% \begin{macro}{\ifinrange}
3653%
3654% Something a little more useful, now. |\ifinrange| takes four arguments:
3655% a number, a range list (as above), and two token lists which I'll call
3656% \emph{then} and \emph{else}. If the number is in the list, I'll do
3657% \emph{then}, otherwise I'll do \emph{else}.
3658%
3659% \begin{macrocode}
3660\def\ifinrange#1#2{%
3661 \@tempswafalse%
3662 \count@#1%
3663 \ranges\ifinrange@i{#2}%
3664 \if@tempswa%
3665 \expandafter\@firstoftwo%
3666 \else%
3667 \expandafter\@secondoftwo%
3668 \fi%
3669}
3670\def\ifinrange@i#1#2{%
3671 \ifnum\count@<#1 \else\ifnum\count@>#2 \else\@tempswatrue\fi\fi%
3672}
3673% \end{macrocode}
3674%
3675% \end{macro}
3676%
3677%
3678% \subsection{Horizontal rules OK}
3679%
3680% This is where all the gubbins for |\vgap| and friends is kept, lest it
3681% contaminate fairly clean bits of code found elsewhere.
3682%
7abe48b3 3683% \subsubsection{Common parsing for rule parameters twiddling}
3684%
3685% \begin{macro}{\tab@ruleparams}
86f6a31e 3686%
7abe48b3 3687% Given a macro name, make a (global) macro |\tab@ruledecls|, which sets
3688% |\dimen0| to be the chosen rule thickness, and sets up colours and whatnot,
3689% and then and calls the macro. We parse a `|*|' to mean
3690% |\arraythickrulewidth|, an optional argument which should be something
3691% |\setlength| can understand, or nothing, which gives the default
3692% |\arrayrulewidth|.
86f6a31e 3693%
7abe48b3 3694% To make this properly hookable, we need to make a list of properties and
3695% gather them together.
86f6a31e 3696%
3697% \begin{macrocode}
7abe48b3 3698\let\tab@rp@inithook\@empty
3699\let\tab@rp@sethook\@empty
3700\let\tab@rp@donehook\@empty
3701\let\tab@rp@default\@empty
3702\def\tab@ruleparams#1{%
3703 {\ifnum0=`}\fi%
3704 \tab@rp@inithook%
3705 \def\tab@rp@next{\ifnum0=`{\fi}#1}%
3706 \expandafter\tab@rp@keys\expandafter{\tab@rp@default}%
3707 \@ifstar\tab@rp@star\tab@rp@what%
86f6a31e 3708}
7abe48b3 3709\def\tab@rp@star{\dimen@\arraythickrulewidth\tab@rp@what}
3710\def\tab@rp@what{\@ifnextchar[\tab@rp@opt\tab@rp@done}
3711\def\tab@rp@opt[#1]{\tab@rp@keys{#1}\tab@rp@done}
3712\def\tab@rp@keys{\mkparse{mdwtab:rule}}
3713\def\tab@rp@done{%
3714 \protected@xdef\tab@rp@{\tab@rp@sethook}%
3715 \tab@rp@donehook%
3716 \tab@rp@next%
86f6a31e 3717}
7abe48b3 3718\def\tab@withrp#1{\tab@ruleparams{\tab@withrp@i{#1}}}
3719\def\tab@withrp@i#1{%
3720 \toks@{#1}%
3721 \toks@\expandafter{\the\expandafter\toks@\expandafter{\tab@rp@}}%
3722 \the\toks@%
3723}
3724% \end{macrocode}
3725%
3726% And now to define the width parameters.
3727%
3728% \begin{macrocode}
3729\tab@addhookafter\tab@rp@inithook{\dimen@\arrayrulewidth}
3730\tab@addhookafter\tab@rp@sethook{\dimen@\the\dimen@}
3731\tab@addhookafter\tab@rp@donehook{\global\tab@rulewidth\dimen@}
3732\mkdef{mdwtab:rule}{width}{\setlength\dimen@{#1}}
3733\mkdef{mdwtab:rule}{thin}*{\dimen@\arrayrulewidth}
3734\mkdef{mdwtab:rule}{thick}*{\dimen@\arraythickrulewidth}
3735\mkdef*{mdwtab:rule}*{\setlength\dimen@{#1}}
3736% \end{macrocode}
3737%
3738% \end{macro}
3739%
3740% \begin{macro}{\tabsetruleparams}
3741%
3742% And the user default-parameter list.
3743%
3744% \begin{macrocode}
3745\def\tabsetruleparams{\def\tab@rp@default}
86f6a31e 3746% \end{macrocode}
3747%
3748% \end{macro}
3749%
3750% \subsubsection{Drawing horizontal rules}
3751%
3752% \begin{macro}{\hline}
3753%
3754% Note the funny use of |\noalign| to allow \TeX\ stomach ops like
3755% |\futurelet| without starting a new table row. This lets us see if there's
3756% another |\hline| coming up, so we can see if we need to insert extra
3757% vertical space.
3758%
3759% \begin{macrocode}
7abe48b3 3760\def\hline{\noalign\tab@ruleparams\hline@prep}
86f6a31e 3761\def\hline@prep{%
3762 \tab@dohline%
3763 \noalign{\ifnum0=`}\fi%
3764 \tab@penalty%
3765 \futurelet\@let@token\hline@i%
3766}
3767% \end{macrocode}
3768%
3769% We check here for another |\hline| command, and insert glue if there is.
3770% This looks terrible, though, and |\hlx{hvh}| is much nicer. Still\dots
3771%
3772% \begin{macrocode}
3773\def\hline@i{%
3774 \@tempswafalse%
3775 \ifx\@let@token\hline\@tempswatrue\fi%
3776 \ifx\@let@token\hline@prep\@tempswatrue\fi%
3777 \if@tempswa%
3778 \vskip\doublerulesep%
3779 \tab@addruleheight\doublerulesep%
3780 \fi%
3781 \ifnum0=`{\fi}%
3782}
3783% \end{macrocode}
3784%
3785% \end{macro}
3786%
3787% \begin{macro}{\tab@dohline}
3788%
e8e9e5d8 3789% This is where hlines actually get drawn.
86f6a31e 3790% Drawing lines is more awkward than it used to be, particularly in unboxed
3791% tables. It used to be a case simply of saying |\noalign{\hrule}|.
3792% However, since unboxed tables are actually much wider than they look, this
3793% would make the rules stretch right across the page and look generally
3794% horrible.
3795%
3796% The solution is simple: we basically do a dirty big |\cline|.
3797%
3798% \begin{macrocode}
3799\def\tab@dohline{%
7abe48b3 3800 \multispan\tab@columns%
3801 \color@begingroup%
3802 \tab@rp@\leaders\hrule\@height\dimen@\hfil%
3803 \tab@addruleheight\dimen@%
3804 \color@endgroup%
86f6a31e 3805 \cr%
3806}
3807% \end{macrocode}
3808%
3809% \end{macro}
3810%
3811% \subsubsection{Vertical rules}
3812%
3813% I couldn't fit these in anywhere else, so they'll have to go here. I'll
3814% provide a new optional argument which specifies the width of the rule; this
3815% gets rid of the problem described in the \emph{Companion}, where to get
3816% an unusually wide vertical rule, you have to play with things like
3817% \syntax{"\\vrule width" <dimen>} which really isn't too nice.
3818%
3819% \begin{macro}{\vline}
3820%
7abe48b3 3821% Now uses the general |\tab@ruleparams| parser. We save and restore the
3822% global |\tab@rulewidth| parameter here.
86f6a31e 3823%
3824% \begin{macrocode}
3825\def\vline{%
3826 \begingroup%
7abe48b3 3827 \@tempdima\tab@rulewidth\let\safe@\tab@rp@%
3828 \tab@ruleparams\tab@vline%
3829}
3830\def\tab@vline{%
3831 \tab@rp@\vrule\@width\dimen@%
3832 \global\tab@rulewidth\@tempdima\global\let\tab@rp@\safe@%
3833 \endgroup%
86f6a31e 3834}
3835% \end{macrocode}
3836%
3837% \end{macro}
3838%
3839% \subsubsection{Drawing bits of lines}
3840%
3841% Just for a bit of fun, here's an extended version of |\cline| which takes
3842% a list of columns to draw lines under, rather than just a single range.
3843%
3844% \begin{macro}{\cline}
3845%
3846% Not a single line of code written yet, and we already have a dilemma on
3847% our hands. Multiple consecutive |\cline| commands are meant to draw
3848% on the same vertical bit of table. But horizontal lines are meant to have
7abe48b3 3849% thickness now. Worse, if the lines have real thickness then we leave gaps
3850% in the vertical rules which aren't covered by our line. But if we
3851% backspace over the line, then we overwrite it with coloured blobs.
3852%
3853% We give up on doing the job properly -- that's just doomed. Backspace over
3854% the previous row, and provide a hack for doing the spacing right elsewhere.
86f6a31e 3855%
3856% Now the problem remains how best to do the job. The way I see it, there
3857% are three possibilities:
3858%
3859% \begin{itemize}
3860%
3861% \item We can start a table row, and then for each column of the table
3862% (as recorded in |\tab@columns|) we look to see if that column is
3863% listed in the range list and if so draw the rule. This requires
3864% lots of scanning of the range list.
3865%
3866% \item We can take each range in the list, and draw rules appropriately,
3867% just like the old |\cline| used to do, and starting a new table row
3868% for each.
3869%
3870% \item We can start a table row, and then for each range remember where we
3871% stopped drawing the last row, move to the start of the new one, and
3872% draw it. If we start moving backwards, we close the current row
3873% and open a new one.
3874%
3875% \end{itemize}
3876%
3877% The last option looks the most efficient, and the most difficult. This
3878% is therefore what I shall do |;-)|.
3879%
3880% The first thing to do is to add in a little negative space, and start a
3881% table row (omitting the first item). Then scan the range list, and finally
3882% close the table row and add some negative space again.
3883%
3884% We need a global count register to keep track of where we are. Mixing
3885% local and global assignments causes all sorts of tragedy, so I shall hijack
3886% |\tab@state|.
3887%
3888% \begin{macrocode}
7abe48b3 3889\def\cline{\noalign\tab@ruleparams\cline@do}
86f6a31e 3890% \end{macrocode}
3891%
3892% Now for the tricky bit. When we're given a range, we look to see if the
3893% first number is less than |\tab@state|. If so, we quickly close the
3894% current row, kern backwards and start again with an |\omit| and reset
7abe48b3 3895% |\tab@state| to 1, and try again. This is hardly perfect, but gets the job
3896% done in many cases. Correct |\vgap| insertion fixes the remaining bugs.
86f6a31e 3897%
3898% \begin{macrocode}
7abe48b3 3899\def\cline@do#1{%
3900 \noalign{\kern-\tab@rulewidth}%
3901 \omit%
3902 \global\tab@state\@ne%
3903 \ranges\cline@do@i{#1}\cr%
3904}
3905\def\cline@do@i#1#2{%
86f6a31e 3906 \ifnum#1<\tab@state\relax%
3907 \tab@@cr%
3908 \noalign{\kern-\tab@rulewidth\tab@penalty}%
3909 \omit%
3910 \global\tab@state\@ne%
3911 \fi%
3912% \end{macrocode}
3913%
3914% We are now either at or in front of the column position required. If
7abe48b3 3915% we're too far back, we must |\hfil&\omit| our way over to the correct
86f6a31e 3916% column.
3917%
3918% \begin{macrocode}
3919 \@whilenum\tab@state<#1\do{%
3920 \hfil\tab@@tab@omit%
3921 \global\advance\tab@state\@ne%
3922 }%
3923% \end{macrocode}
3924%
3925% We've found the start correctly. We must deal with a tiny problem now:
3926% if this is not the first table cell, the left hand vertical rule is in the
3927% column to the left, so our horizontal rule won't match up properly. So
3928% we skip back by a bit to compensate. If there isn't actually a vertical
3929% rule to line up with, no-one will notice, because the rules are so thin.
3930% This adds a little touch of quality to the whole thing, which is after all
3931% the point of this whole exercise.
3932%
3933% \begin{macrocode}
3934 \ifnum\tab@state>\@ne%
3935 \kern-\arrayrulewidth%
3936 \fi%
3937% \end{macrocode}
3938%
3939% Now we must stretch this table cell to the correct width.
3940%
3941% \begin{macrocode}
3942 \@whilenum\tab@state<#2\do{%
3943 \tab@@span@omit%
3944 \global\advance\tab@state\@ne%
3945 }%
3946% \end{macrocode}
3947%
3948% We're ready. Draw the rule. Note that this is |\hfill| glue, just in case
3949% we start putting in |\hfil| glue when we step onto the next cell.
3950%
3951% \begin{macrocode}
7abe48b3 3952 \color@begingroup%
3953 \tab@rp@%
86f6a31e 3954 \leaders\hrule\@height\tab@rulewidth\hfill%
7abe48b3 3955 \color@endgroup%
86f6a31e 3956}
3957% \end{macrocode}
3958%
3959% Some alignment primitives are hidden inside macros so they don't get seen
3960% at the wrong time. This is what they look like:
3961%
3962% \begin{macrocode}
3963\def\tab@@cr{\cr}
3964\def\tab@@tab@omit{&\omit}
3965\def\tab@@span@omit{\span\omit}
3966% \end{macrocode}
3967%
3968% \end{macro}
3969%
3970% \subsubsection{Drawing short table rows}
3971%
3972% Before I start on a description of more code, I think I'll briefly discuss
3973% my reasons for leaving the |\vgap| command in its current state. There's a
3974% reasonable case for introducing an interface between |\vgap| and
3975% |\multicolumn|, to avoid all the tedious messing about with column
3976% ranges. There are good reasons why I'm not going to do this:
3977%
3978% \begin{itemize}
3979%
3980% \item It's very difficult to do: it requires either postprocessing of
3981% the table or delaying processing of each row until I know exactly
3982% what's in it; a |\multicolumn| in a row should be able to affect
3983% a |\vgap| before the row, which gets very nasty. This package is
3984% probably far too large already, and adding more complexity and
3985% running the risk of exhausting \TeX's frustratingly finite capacity
3986% for the sake of relieving the user of a fairly trivial job doesn't
3987% seem worthwhile.
3988%
3989% \item Perhaps more importantly, there are perfectly valid occasions when
3990% it's useful to have the current vgap behaviour. For example, the
3991% \texttt{MIX} word layout diagrams found in \emph{The Art of
3992% Computer Programming} use the little `stub lines' to show where
3993% data items cross byte boundaries:
3994%
eafdddad
MW
3995% ^^A This actually looks terrifyingly similar to the original.
3996% ^^A The leading @{} is there to stop the table looking off-centre,
3997% ^^A because there's no left hand rule telling you where the table
3998% ^^A starts, like there is on the right, just the \tabcolsep glue.
3999%
4000% \begingroup
4001% \newcommand{\wide}[2]{\multicolumn{#1}{c|}{\ttfamily #2}}
4002% \begin{tabular}[C]{@{} r @{\qquad} | Mc | *{5}{c|}} \hlx{c{2-7} v}
4003% empty & - & 1 & 0 & 0 & 0 & 0 \\ \hlx{v c{2-7} v}
4004% occupied & + & \wide{2}{LINK} & \wide{3}{KEY} \\ \hlx{v c{2-7}}
4005% \end{tabular}
4006% \endgroup
86f6a31e 4007%
4008% \end{itemize}
4009%
4010% That's my excuses out of the way; now I'll press on with the actual
4011% programming.
4012%
4013% \begin{macro}{\tab@checkrule}
4014%
4015% We have a range list in |\tab@xcols| and a number as an argument. If we
4016% find the number in the list, we just space out the following group,
4017% otherwise we let it be.
4018%
4019% \begin{macrocode}
4020\def\tab@checkrule#1{%
4021 \count@#1\relax%
4022 \expandafter\ifinrange%
4023 \expandafter\count@%
4024 \expandafter{\tab@xcols}%
4025 {\tab@checkrule@i}%
4026 {}%
4027}
4028\def\tab@checkrule@i#1{\setbox\z@\hbox{#1}\hb@xt@\wd\z@{}}
4029% \end{macrocode}
4030%
4031% \end{macro}
4032%
4033% \begin{macro}{\vgap}
4034%
4035% We must tread carefully here. A single misplaced stomach operation can
4036% cause error messages. We therefore start with an |\omit| so we can search
4037% for optional arguments.
4038%
4039% So that |\hlx| can get control after |\vgap| has finished, we provide a
4040% hook called |\vgap@after| which is expanded after |\vgap| has finished.
4041% Here we make it work like |\@empty|, which expands to nothing. (Note that
4042% |\relax| will start a new table row, so we can't use that.) There are
4043% some penalty items here to stick the |\vgap| row to the text row and
4044% |\hline| that are adjacent to it. The \package{longtable} package will
4045% split an |\hline| in half, so this is the correct thing to do.
4046%
4047% \begin{macrocode}
4048\def\vgap{%
4049 \noalign{\nobreak}%
4050 \omit%
4051 \global\let\vgap@after\@empty%
4052 \iffalse{\fi\ifnum0=`}\fi%
4053 \@ifnextchar[\vgap@i\vgap@simple%
4054}
4055% \end{macrocode}
4056%
4057% We set up two different sorts of |\vgap| -- a simple one which allows all
4058% rules to be passed through, and a specific one which carefully vets each
4059% one (and is therefore slower). We decide which to so based on the presence
4060% of an optional argument.
4061%
4062% The optional argument handler just passes its argument to an interface
4063% routine which is used by |\hlx|.
4064%
4065% \begin{macrocode}
4066\def\vgap@i[#1]{\vgap@spec{#1}}
4067% \end{macrocode}
4068%
4069% Now we handle specified columns. Since we're in an omitted table cell, we
4070% must set things up globally. Assign the column spec to a macro, and set up
4071% vetting by the routine above. Then just go and do the job.
4072%
4073% \begin{macrocode}
4074\def\vgap@spec#1#2{%
4075 \gdef\tab@xcols{#1}%
4076 \global\let\tab@ckr\tab@checkrule%
4077 \vgap@do{#2}%
4078}
4079% \end{macrocode}
4080%
4081% Handle all columns. Just gobble the column number for each rule, and let
4082% the drawing pass unharmed. Easy.
4083%
4084% \begin{macrocode}
4085\def\vgap@simple#1{%
4086 \global\let\tab@ckr\@gobble%
4087 \vgap@do{#1}%
4088}
4089% \end{macrocode}
4090%
4091% This is where stuff actually gets done. We set the |\vgap| flag on while
4092% we do the short row. Then just expand the token list we built while
4093% scanning the preamble.
4094%
4095% Note that the flag is cleared at the end of the last column, to allow other
4096% funny things like |\noalign| and |\omit| before a new row is started.
4097%
4098% \begin{macrocode}
4099\def\vgap@do#1{%
4100 \ifnum0=`{}\fi%
4101 \global\tab@vgaptrue%
4102 \the\tab@shortline%
4103 \vrule\@height#1\@width\z@%
4104 \global\tab@vgapfalse
4105 \tab@addruleheight{#1}%
4106 \cr%
4107 \noalign{\nobreak}%
4108 \vgap@after%
4109}
4110% \end{macrocode}
4111%
4112% \end{macro}
4113%
4114% \subsubsection{Prettifying syntax}
4115%
4116% \begin{macro}{\hlx}
4117%
4118% This is like a poor cousin to the preamble parser. The whole loop is
4119% carefully written to take place \emph{only} in \TeX's mouth, so the
4120% alignment handling bits half way down the gullet don't see any of this.
4121%
4122% First, pass the string to another routine.
4123%
4124% \begin{macrocode}
7abe48b3 4125\def\hlx{\noalign\tab@ruleparams\hlx@prep}
86f6a31e 4126\def\hlx@prep#1{\hlx@loop#1\q@delim}
4127% \end{macrocode}
4128%
4129% Now peel off a token, and dispatch using |\csname|. We handle
4130% undefinedness of the command in a fairly messy way, although it probably
4131% works. Maybe.
4132%
4133% \begin{macrocode}
4134\def\hlx@loop#1{%
4135 \ifx#1\q@delim\else%
4136 \@ifundefined{hlx@cmd@\string#1}{%
4137 \expandafter\hlx@loop%
4138 }{%
4139 \csname hlx@cmd@\string#1\expandafter\endcsname%
4140 }%
4141 \fi%
4142}
4143% \end{macrocode}
4144%
4145% \end{macro}
4146%
4147% \begin{macro}{\hlxdef}
4148%
4149% New |\hlx| commands can be defined using |\hlxdef|. This is a simple
4150% abbreviation.
4151%
4152% \begin{macrocode}
4153\def\hlxdef#1{\@namedef{hlx@cmd@#1}}
4154% \end{macrocode}
4155%
4156% \end{macro}
4157%
4158% \begin{macro}{\hlx h}
4159%
4160% Handle an \lit{h} character. Just do an |\hline| and return to the loop.
4161% We look ahead to see if there's another \lit{h} coming up, and if so
4162% insert two |\hline| commands. This strange (and inefficient) behaviour
4163% keeps packages which redefine |\hline| happy.
4164%
4165% \begin{macrocode}
4166\hlxdef h#1{%
4167 \noalign{%
7abe48b3 4168 \ifx#1h\def\@tempa{\hline@prep\hline@prep\hlx@loop}%
4169 \else\def\@tempa{\hline@prep\hlx@loop#1}%
4170 \fi\expandafter
86f6a31e 4171 }%
4172 \@tempa%
4173}
4174% \end{macrocode}
4175%
4176% \end{macro}
4177%
4178% \begin{macro}{\hlx b}
4179%
4180% The \lit{b} character does a nifty backspace, for \package{longtable}'s
4181% benefit.
4182%
4183% \begin{macrocode}
4184\hlxdef b{\noalign{\kern-\arrayrulewidth}\hlx@loop}
4185% \end{macrocode}
4186%
4187% \end{macro}
4188%
4189% \begin{macro}{\hlx /}
4190%
4191% The `"/"' character allows a page break at the current position.
4192%
4193% \begin{macrocode}
7abe48b3 4194\hlxdef /{\noalign{\ifnum0=`}\fi\@testopt\hlx@cmd@break@i0}
4195\def\hlx@cmd@break@i[#1]{\ifnum0=`{\fi}\pagebreak[#1]\hlx@loop}
86f6a31e 4196% \end{macrocode}
4197%
4198% \end{macro}
4199%
4200% \begin{macro}{\hlx v}
7abe48b3 4201% \begin{macro}{\hlx z}
86f6a31e 4202%
7abe48b3 4203% Handle a \lit{v} or \lit{z} character. This is rather like the |\vgap|
4204% code above, although there are syntactic differences.
86f6a31e 4205%
4206% \begin{macrocode}
7abe48b3 4207\hlxdef v{\hlx@vgap\doublerulesep}
4208\hlxdef z{\hlx@vgap\tab@rulewidth}
4209\def\hlx@vgap#1{%
86f6a31e 4210 \noalign{\nobreak}%
4211 \omit%
4212 \iffalse{\fi\ifnum0=`}\fi%
4213 \global\let\vgap@after\hlx@loop%
7abe48b3 4214 \@ifnextchar[{\hlx@vgap@i{#1}}{\hlx@vgap@ii\vgap@simple{#1}}%
86f6a31e 4215}
7abe48b3 4216\def\hlx@vgap@i#1[#2]{%
4217 \ifx!#2!\def\@tempa{\hlx@vgap@ii\vgap@simple{#1}}%
4218 \else\def\@tempa{\hlx@vgap@ii{\vgap@spec{#2}}{#1}}\fi%
86f6a31e 4219 \@tempa%
4220}
7abe48b3 4221\def\hlx@vgap@ii#1#2{\@testopt{\hlx@vgap@iii{#1}}{#2}}
86f6a31e 4222\def\hlx@vgap@iii#1[#2]{#1{#2}}
4223% \end{macrocode}
4224%
4225% \end{macro}
7abe48b3 4226% \end{macro}
86f6a31e 4227%
4228% \begin{macro}{\hlx s}
4229%
4230% Allow the user to leave a small gap using the \lit{s} command.
4231%
4232% \begin{macrocode}
4233\hlxdef s{%
4234 \noalign{\ifnum0=`}\fi%
4235 \nobreak%
7abe48b3 4236 \@testopt\hlx@space@i\doublerulesep%
86f6a31e 4237}
4238\def\hlx@space@i[#1]{%
4239 \vskip#1%
4240 \tab@addruleheight{#1}%
4241 \ifnum0=`{\fi}%
4242 \hlx@loop%
4243}
4244% \end{macrocode}
4245%
4246% \end{macro}
4247%
4248% \begin{macro}{\hlx c}
4249%
7abe48b3 4250% We might as well allow a \lit{c} command to do a |\cline|. The fix to
4251% |\cline| permeates here.
86f6a31e 4252%
4253% \begin{macrocode}
7abe48b3 4254\hlxdef c#1{\cline@do{#1}\hlx@loop}
4255% \end{macrocode}
4256%
4257% \end{macro}
4258%
4259% \begin{macro}{\hlx ?}
4260%
4261% Do some arbitrary stuff which won't typeset. Put the stuff in a box which
4262% is discarded, just in case.
4263%
4264% \begin{macrocode}
4265\hlxdef ?#1{%
4266 \noalign{\setbox\z@\hbox{\color@begingroup#1\color@endgroup}}\hlx@loop%
4267}
4268% \end{macrocode}
4269%
4270% \end{macro}
4271%
4272% \begin{macro}{\hlx !}
4273%
4274% Change parameters in mid-flow.
4275%
4276% \begin{macrocode}
4277\hlxdef !#1{\noalign\tab@ruleparams\hlx@loop[{#1}]}
86f6a31e 4278% \end{macrocode}
4279%
4280% \end{macro}
4281%
4282% \begin{macro}{\hlx .}
4283%
4284% The \lit{.} character forces a start of the new column. There's a little
4285% problem here. Since the \lit{.} character starts the next column, we need
4286% to gobble any spaces following the |\hlx| command before the cell contents
4287% actually starts. Unfortunately, |\ignorespaces| will start the column for
4288% us, so we can't put it in always. We'll handle it here, then. We'll take
4289% the rest of the `preamble' string, and warn if it's not empty. Then we'll
4290% |\ignorespaces| -- this will start the column for us, so we don't need to
4291% |\relax| any more.
4292%
4293% \begin{macrocode}
4294\hlxdef .#1\q@delim{%
4295 \ifx @#1@\else%
4296 \PackageWarning{mdwtab}{%
4297 Ignoring \protect\hlx\space command characters following a
4298 `.'\MessageBreak command%
4299 }%
4300 \fi%
4301 \ignorespaces%
4302}
4303% \end{macrocode}
4304%
4305% \end{macro}
4306%
7abe48b3 4307% \begin{macro}{\hlx +}
4308% \begin{macro}{\nextrow}
4309%
4310% The \lit{+} subcommand just steps the table-row counter.
4311%
4312% \begin{macrocode}
4313\hlxdef +{\nextrow\hlx@loop}
4314\def\nextrow{\noalign{\ifnum0=`}\fi\@testopt\nextrow@i\@ne}
4315\def\nextrow@i[#1]{\global\advance\c@tabrow#1\ifnum0=`{\fi}}
4316% \end{macrocode}
4317%
4318% \end{macro}
4319% \end{macro}
4320%
86f6a31e 4321%
4322% \subsection{Starting new table rows}
4323%
4324% We take a break from careful mouthery at last, and start playing with
4325% newlines. The standard one allows pagebreaks in unboxed tables, which
4326% isn't really too desirable.
4327%
4328% Anyway, we'll try to make this macro rather more reusable than the standard
4329% one. Here goes.
4330%
4331% \begin{macro}{\@arraycr}
4332%
4333% We pass lots of information to a main parser macro, and expect it to cope.
4334%
4335% \begin{macrocode}
4336\def\@arraycr{\tab@arraycr{}}
4337\def\tab@arraycr#1{\tab@cr{\tab@tabcr{#1}}{}{}}
4338% \end{macrocode}
4339%
4340% Now to actually do the work. |\tab@cr| passes us the skip size, and the
4341% appropriate one of the two arguments given above (both of which are empty)
4342% depending on the presence of the $*$.
4343%
4344% \begin{macrocode}
4345\def\tab@tabcr#1#2{%
4346% \end{macrocode}
4347%
4348% If the total height I need to add between rows (from the optional argument
4349% and the `extrasep' parameter) is greater than zero, I'll handle this by
4350% extending the strut slightly. I'm not actually sure whether this is the
4351% right thing to do, to be honest, although it's easier than trying to
4352% to an automatic |\vgap|, because I need to know which columns to skip.
4353% If the space is less than zero, I'll just insert the vertical space with
4354% in a |\noalign|.
4355%
4356% First, to calculate how much space needs adding.
4357%
4358% \begin{macrocode}
4359 \setlength\dimen@{#2}%
4360 \advance\dimen@\tab@extrasep%
4361% \end{macrocode}
4362%
4363% If the height is greater than zero, I need to play with the strut. I must
4364% bear in mind that the current table cell (which I'm still in, remember)
4365% may be in vertical mode, and I may or may not be in a paragraph.
4366%
4367% If I am in vertical mode, I'll backpedal to the previous box and put the
4368% strut in an hbox superimposed on the previous baseline. Otherwise, I can
4369% just put the strut at the end of the text. (This works in either LR
4370% or paragraph mode as long as I'm not between paragraphs.) Again, Rowland's
4371% empty cell bug strikes. (See |\tab@epar| for details.)
4372%
4373% \begin{macrocode}
4374 \ifdim\dimen@>\z@%
4375 \ifvmode%
4376 \unskip\ifdim\prevdepth>-\@m\p@\kern-\prevdepth\fi%
4377 \nointerlineskip\expandafter\hbox%
4378 \else%
4379 \@maybe@unskip\expandafter\@firstofone%
4380 \fi%
4381 {\advance\dimen@\dp\@arstrutbox\vrule\@depth\dimen@\@width\z@}%
4382 \fi%
4383% \end{macrocode}
4384%
4385% This table cell works as a group (which is annoying here). I'll copy the
4386% interrow gap into a global register so that I can use it in the |\noalign|.
4387%
4388% \begin{macrocode}
4389 \global\dimen\@ne\dimen@%
4390 \cr%
4391 \noalign{%
4392 #1%
4393 \ifdim\dimen\@ne<\z@\vskip\dimen\@ne\relax\fi%
4394 }%
4395 \@gobble%
4396}
4397% \end{macrocode}
4398%
4399% \end{macro}
4400%
4401% \begin{macro}{\tab@setcr}
4402%
4403% To set the |\\| command correctly in each table cell, we make it a part of
4404% the preamble (in |\tab@midtext|) to call this routine. It's easy -- just
4405% saves the preamble from being huge.
4406%
4407% \begin{macrocode}
4408\def\tab@setcr{\let\\\tabularnewline}
4409% \end{macrocode}
4410%
4411% \end{macro}
4412%
4413% \begin{macro}{\tab@cr}
4414%
4415% Now we do the parsing work. This is fun. Note the revenge of the funny
4416% braces here. Nothing to worry about, honest. The tricky bit is to keep
4417% track of which arguments are which. (Thanks to David Carlisle for pointing
4418% out that I'd missed out the |\relax| here.)
4419%
4420% \begin{macrocode}
4421\def\tab@cr#1#2#3{%
4422 \relax%
4423 \iffalse{\fi\ifnum0=`}\fi%
4424 \@ifstar{\tab@cr@i{#1}{#3}}{\tab@cr@i{#1}{#2}}%
4425}
7abe48b3 4426\def\tab@cr@i#1#2{\@testopt{\tab@cr@ii{#1}{#2}}\z@}
4427\def\tab@cr@ii#1#2[#3]{\ifnum0=`{}\fi#1{#3}{#2}}
86f6a31e 4428% \end{macrocode}
4429%
4430% \end{macro}
4431%
4432%
4433% \subsection{Gratuitous grotesquery}
4434%
4435% So far we've had an easy-ish ride (or should that be \emph{queasy}?). Now
4436% for something unexplainably evil. We convince \LaTeX\ that it's loaded the
4437% \package{array} package, so that packages which need it think they've got
4438% it.
4439%
4440% The bogus date is the same as the date for the \package{array} package I've
4441% got here -- this will raise a warning if Frank updates his package which
4442% should filter back to me telling me that there's something I need to
4443% know about.
4444%
4445% The messing with |\xdef| and the funny parsing ought to insert the current
4446% \package{mdwtab} version and date into the fake \package{array} version
4447% string, giving a visible clue to the user that this isn't the real
4448% \package{array} package.
4449%
4450% \begin{macrocode}
4451\begingroup
4452\catcode`.=11
4453\def\@tempa#1 #2 #3\@@{#1 #2}
4454\xdef\ver@array.sty
4455 {1995/11/19 [mdwtab.sty \expandafter\@tempa\ver@mdwtab.sty\@@]}
4456\endgroup
4457% \end{macrocode}
4458%
4459%
4460% \subsection{Error messages}
4461%
4462% I've put all the error messages together, where I can find them, translate
4463% them or whatever.
4464%
4465% First, some token-space saving (which also saves my fingers):
4466%
4467% \begin{macrocode}
4468\def\tab@error{\PackageError{mdwtab}}
4469% \end{macrocode}
4470%
4471% Now do the error messages.
4472%
4473% \begin{macrocode}
4474\def\tab@err@misscol{%
4475 \tab@error{Missing column type}{%
4476 I'm lost. I was expecting something describing^^J%
4477 the type of the current column, but you seem to^^J%
4478 have missed it out. I've inserted a type `l'^^J%
4479 column here in the hope that this makes sense.%
4480 }%
4481}
4482% \end{macrocode}
4483%
4484% \begin{macrocode}
4485\def\tab@err@oddgroup{%
4486 \tab@error{Misplaced group in table preamble}{%
4487 I've found an open brace character in your preamble^^J%
4488 when I was expecting a specifier character. I'm^^J%
4489 going to gobble the whole group and carry on as if^^J%
4490 I'd never seen it.%
4491 }%
4492}
4493% \end{macrocode}
4494%
4495% \begin{macrocode}
4496\def\tab@err@undef#1{%
4497 \tab@error{Unknown `\tab@colset' preamble character `\string#1'}{%
4498 I don't understand what you meant by typing this^^J%
4499 character. Anyway, I'll ignore it this time around.^^J%
4500 Just don't you do it again.%
4501 }%
4502}
4503% \end{macrocode}
4504%
4505% \begin{macrocode}
4506\def\tab@err@unbrh{%
4507 \tab@error{Can't use unboxed tabular in LR mode}{%
4508 You've asked for a tabular or array environment with^^J%
4509 `L', `C' or `R' as the position specifier, but you're^^J%
4510 in LR (restricted horizontal) mode, so it won't work.^^J%
4511 I'll assume you really meant `c' and soldier on.%
4512 }%
4513}
4514% \end{macrocode}
4515%
4516% \begin{macrocode}
4517\def\tab@err@unbmm{%
4518 \tab@error{Can't use unboxed tabular in maths mode}{%
4519 You've asked for a tabular or array environment with^^J%
4520 `L', `C' or `R' as the position specifier, but you're^^J%
4521 in maths mode, so it won't work. I'll pretend that^^J%
4522 you really typed `c', and that this is all a bad dream.%
4523 }%
4524}
4525% \end{macrocode}
4526%
4527% \begin{macrocode}
4528\def\tab@err@unbext{%
4529 \tab@error{Can't extend unboxed tabulars}{%
4530 You're trying to use kludgy extensions (e.g.,^^J%
4531 `delarray') on an array or tabular with `L', `C'^^J%
4532 or `R' as the position specifier. I'll assume you^^J%
4533 subconsciously wanted a `c' type all along.%
4534 }%
4535}
4536% \end{macrocode}
4537%
4538% \begin{macrocode}
4539\def\tab@err@multi{%
4540 \tab@error{More than one column in a \protect\multicolumn}{%
4541 You've put more than one column into a \string\multicolumn^^J%
4542 descriptor. It won't work. I have no idea what^^J%
4543 will happen, although it won't be pleasant. Hold^^J%
4544 on tight now...%
4545 }%
4546}
4547% \end{macrocode}
4548%
4549% \begin{macrocode}
4550\def\tab@err@range{%
4551 \tab@error{Expected `,' or `<end>' in range list}{%
4552 I was expecting either the end of the range list,^^J%
4553 or a comma, followed by another range. I've^^J%
4554 inserted a comma to try and get me back on track.^^J%
4555 Good luck.%
4556 }%
4557}
4558% \end{macrocode}
4559%
7abe48b3 4560%
4561% \subsection{Loading the colour package}
4562%
4563% If requested, we load the \package{mtcolour} package here. This ensures
4564% that it can patch this code if it needs to.
4565%
4566% \begin{macrocode}
4567\iftab@colour
4568 \RequirePackage{mtcolour}
4569\fi
4570% \end{macrocode}
4571%
86f6a31e 4572% That's it. No more. Move along please.
4573%
4574% \begin{macrocode}
4575%</mdwtab>
4576% \end{macrocode}
4577%
4578%
4579%^^A-------------------------------------------------------------------------
7abe48b3 4580% \section{Implementation of \package{mtcolour}}
4581%
4582%
4583% This is in a separate package to avoid dragging in the \package{color}
4584% package if it's unwanted.
4585%
4586% I prefer English spellings. Here's a trivial redirection for Americans.
4587%
4588% \begin{macrocode}
4589%<*color>
4590\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{mtcolour}}
4591\ProcessOptions
4592\RequirePackage{mtcolour}
4593%</color>
4594% \end{macrocode}
4595%
4596% And now we can start the thing properly.
4597%
4598% \begin{macrocode}
4599%<*colour>
4600\RequirePackage{color}
4601% \end{macrocode}
4602%
4603%
4604% \subsection{Cell background colours}
4605%
4606% First, some simple preliminaries. The |\iftab@colour| switch is set if the
4607% current cell is meant to have a colour.
4608%
4609% \begin{macrocode}
4610\newif\iftab@colour
4611\tab@colourfalse
4612% \end{macrocode}
4613%
4614% We shall store the cell colour information in |\tab@cellcolour|, and the
4615% row colour information as |\tab@rowcolour|. Because of the structure of
4616% tables, we need to make global assignments; so we must copy the current
4617% value away at the start of a table and put the value back at the end. In
4618% order to transfer the overhang information reliably, we use a separate
4619% control sequence |\tab@colouroverhangs| for that -- otherwise |\color| can
4620% corrupt it.
4621%
4622% \begin{macrocode}
4623\tab@addhookbefore\tab@beginhook{%
4624 \let\tab@saverowcolour\tab@rowcolour%
4625 \let\tab@savecolouroverhangs\tab@colouroverhangs%
4626 \let\tab@savecellcolour\tab@cellcolour%
4627}
4628\tab@addhookafter\tab@endhook{%
4629 \global\let\tab@rowcolour\tab@saverowcolour%
4630 \global\let\tab@colouroverhangs\tab@savecolouroverhangs%
4631 \global\let\tab@cellcolour\tab@savecellcolour%
4632}
4633% \end{macrocode}
4634%
4635% Initially, there are no colours.
4636%
4637% \begin{macrocode}
4638\let\tab@rowcolour\@empty%
4639\let\tab@cellcolour\@empty%
4640\let\tab@colouroverhangs\@empty%
4641% \end{macrocode}
4642%
4643% \begin{macro}{\@snarfcolour}
4644%
4645% Reading a colour specification is something we'll need to do a few times,
4646% so an abstraction is useful. Its single argument is a continuation to
4647% which we pass a colour-spec acceptable to the |\color| command. (This is
4648% the same code as found in the \package{sverb} package. Remember to keep
4649% them in step.)
4650%
4651% \begin{macrocode}
4652\def\@snarfcolour#1{%
4653 \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
4654}
4655\def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
4656\def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
4657% \end{macrocode}
4658%
4659% \end{macro}
4660%
4661% \begin{macro}{\cellcolour}
4662%
4663% Setting a cell colour is a matter of stashing the right declarations in
4664% |\tab@cellcolour| and |\tab@colouroverhangs|. Note that the overhangs end
4665% up in |\dimen0| and |\dimen2|.
4666%
4667% \begin{macrocode}
4668\def\cellcolour{%
4669 \@ifstar{\tab@ccol@i{\let\tab@rowcolour\@empty}}{\tab@ccol@i{}}%
4670}
4671\def\tab@ccol@i#1{\@snarfcolour{\tab@ccol@ii{#1}}}
4672\def\tab@ccol@ii#1#2{\@testopt{\tab@ccol@iii{#2#1}}\z@}
4673\def\tab@ccol@iii#1[#2]{\@testopt{\tab@ccol@iv{#1}{#2}}{#2}}
4674\def\tab@ccol@iv#1#2[#3]{%
4675 \gdef\tab@cellcolour{\color#1\tab@colourtrue}%
4676 \gdef\tab@colouroverhangs{%
4677 \setlength\dimen@{#2}%
4678 \setlength{\dimen\tw@}{#3}%
4679 }%
4680}
4681% \end{macrocode}
4682%
4683% \end{macro}
4684%
4685% \begin{macro}{\rowcolour}
4686%
4687% Setting the global row colour is simpler, because we don't mess with
4688% overhangs.
4689%
4690% \begin{macrocode}
4691\def\rowcolour{\@snarfcolour\tab@setrowcolour}
4692\let\rowcolor\rowcolour
4693\def\tab@setrowcolour#1{%
4694 \gdef\tab@rowcolour{\color#1\tab@colourtrue}%
4695}
4696% \end{macrocode}
4697%
4698% \end{macro}
4699%
4700% \begin{macro}{\rowcolouroff}
4701%
4702% And turning the global colouring off is easy.
4703%
4704% \begin{macrocode}
4705\def\rowcolouroff{\global\let\tab@rowcolour\@empty}
4706\let\rowcoloroff\rowcolouroff
4707% \end{macrocode}
4708%
4709% \end{macro}
4710%
4711% \begin{macro}{\tab@colourleft}
4712%
4713% Now we start on the table-cell hooks. The left hook starts a box which
4714% will capture the cell's text and natural width. We add the hook to the
4715% rule list as well, so that we can colour the bits in |\vgap|s correctly.
4716%
4717% \begin{macrocode}
4718\tab@addhookbefore\tab@lefttexthook\tab@colourleft
4719\tab@addhookbefore\tab@leftruletexthook\tab@colourleft
4720\def\tab@colourleft{%
4721 \global\let\tab@cellcolour\@empty%
4722 \global\let\tab@colouroverhangs\@empty%
4723 \setbox\z@\hbox\bgroup\color@begingroup%
4724}
4725% \end{macrocode}
4726%
4727% \end{macro}
4728%
4729% \begin{macro}{\tab@colourright}
4730%
4731% The right hook will insert an appropriate rule behind the cell and
4732% retypeset the cell contents over the top. Note that the stretch in a table
4733% cell is exactly 1\,fil. Because we add (leaders) and subtract (negative
4734% |\hskip|) 1\,fil, we retain this stretch exactly. Don't bother unless
4735% there's actually some colouring.
4736%
4737% \begin{macrocode}
4738\tab@addhookafter\tab@righttexthook\tab@colourright
4739\tab@addhookafter\tab@rightruletexthook\tab@colourright
4740\def\tab@colourright{%
4741 \color@endgroup\egroup%
4742 \color@begingroup%
4743 \global\tab@colourfalse%
4744 \tab@cellcolour\tab@rowcolour%
4745 \dimen@\z@\dimen\tw@\z@\tab@colouroverhangs%
4746 \iftab@colour%
4747 \skip@\wd\z@\advance\skip@\z@\@plus1fil%
4748 \skip\tw@\skip@%
4749 \kern-\dimen@%
4750 \advance\skip\tw@\dimen@%
4751 \advance\skip\tw@\dimen\tw@%
4752 \leaders\vrule\hskip\skip\tw@%
4753 \kern-\dimen\tw@%
4754 \hskip-\skip@%
4755 \fi%
4756 \color@endgroup%
4757 \unhbox\z@%
4758}
4759% \end{macrocode}
4760%
4761% \end{macro}
4762%
4763%
4764% \subsection{Coloured rules}
4765%
4766% We hook ourselves onto the rule-parameters edifice. This is rather
4767% straightforward.
4768%
4769% \begin{macrocode}
4770\tab@addhookafter\tab@rp@inithook{%
4771 \let\tab@rulecolour\@empty%
4772 \let\tab@rulecolourmodel\@empty%
4773}
4774\mkdef{mdwtab:rule}{colour}{\tab@setrulecolour{#1}}
4775\mkdef{mdwtab:rule}{colourmodel}{\tab@setrulecolourmodel{#1}}
4776\mkdef{mdwtab:rule}{color}{\tab@setrulecolour{#1}}
4777\mkdef{mdwtab:rule}{colormodel}{\tab@setrulecolourmodel{#1}}
4778\mkdef{mdwtab:rule}{nocolour}*{\let\tab@rulecolour\@empty}
4779\mkdef{mdwtab:rule}{nocolor}*{\let\tab@rulecolour\@empty}
4780\mkdef{mdwtab:rule}{nocolourmodel}*{\let\tab@rulecolourmodel\@empty}
4781\mkdef{mdwtab:rule}{nocolormodel}*{\let\tab@rulecolourmodel\@empty}
4782\def\tab@setrulecolour#1{%
4783 \def\tab@rulecolour{\color\tab@rulecolourmodel{#1}}%
4784}
4785\def\tab@setrulecolourmodel#1{\def\tab@rulecolourmodel{[#1]}}
4786\tab@addhookafter\tab@rp@sethook{\tab@rulecolour}
4787% \end{macrocode}
4788%
4789%
4790% \subsection{Other stuff}
4791%
4792% \begin{macro}{\ifmod}
4793%
4794% \syntax{"\\ifmod{"$x$"}{"$m$"}{"y"}{"<yes>"}{"<no>"}"} -- if $x \bmod m =
4795% y$ then do \<yes>; otherwise do \<no>.
4796%
4797% \begin{macrocode}
4798\def\ifmod#1#2#3{%
4799 \begingroup%
4800 \@tempcnta#1%
4801 \@tempcntb#2%
4802 \count@\@tempcnta%
4803 \divide\count@\@tempcntb%
4804 \multiply\count@\@tempcntb%
4805 \advance\@tempcnta-\count@%
4806 \count@#3\relax%
4807 \ifnum\@tempcnta=\count@\endgroup\expandafter\@firstoftwo%
4808 \else\endgroup\expandafter\@secondoftwo\fi%
4809}
4810% \end{macrocode}
4811%
4812% \end{macro}
4813%
4814% Done.
4815%
4816% \begin{macrocode}
4817%</colour>
4818% \end{macrocode}
4819%
4820%^^A-------------------------------------------------------------------------
86f6a31e 4821% \section{Implementation of \package{mathenv}}
4822%
4823%
4824% This is in a separate package, mainly to avoid wasting people's memory.
4825%
4826% \begin{macrocode}
4827%<*mathenv>
4828% \end{macrocode}
4829%
4830%
4831% \subsection{Options handling}
4832%
4833% We need to be able to cope with \textsf{fleqn} and \textsf{leqno} options.
4834% This will adjust our magic modified \env{eqnarray} environment
4835% appropriately.
4836%
4837% \begin{macrocode}
4838\newif\if@fleqn
4839\newif\if@leqno
4840\DeclareOption{fleqn}{\@fleqntrue}
4841\DeclareOption{leqno}{\@leqnotrue}
4842\ProcessOptions
4843% \end{macrocode}
4844%
4845% We use the \package{mdwtab} package for all its nice table handling things.
4846% (Oh, and to inflict it on users who want to do nice equations and don't
4847% care about our tables.)
4848%
4849% \begin{macrocode}
4850\RequirePackage{mdwtab}
4851% \end{macrocode}
4852%
4853%
4854% \subsection{Some useful registers}
4855%
4856% The old \LaTeX\ version puts the equation numbers in by keeping a count of
4857% where it is in the alignment. Since I don't know how may columns there are
4858% going to be, I'll just use a switch in the preamble to tell me to stop
4859% tabbing.
4860%
4861% \begin{macrocode}
4862\newif\if@eqalast
4863% \end{macrocode}
4864%
4865% Now define some useful length parameters. First allocate them:
4866%
4867% \begin{macrocode}
4868\newskip\eqaopenskip
4869\newskip\eqacloseskip
4870\newskip\eqacolskip
4871\newskip\eqainskip
4872\newskip\splitleft
4873\newskip\splitright
4874% \end{macrocode}
4875%
4876% Now assign some default values. Users can play with these if they really
4877% want although I can't see the point myself.
4878%
4879% \begin{macrocode}
4880\AtBeginDocument{%
4881 \eqacloseskip\@centering%
4882 \eqacolskip1.5em\@plus\@m\p@
4883 \eqainskip\z@%
4884 \if@fleqn%
4885 \eqaopenskip\mathindent%
4886 \splitleft\mathindent\relax%
e8e9e5d8 4887 \splitright\mathindent\@minus\mathindent\relax%
86f6a31e 4888 \else%
4889 \eqaopenskip\@centering%
4890 \splitleft2.5em\@minus2.5em%
4891 \splitright\splitleft%
4892 \fi%
4893 \relax%
4894}
4895% \end{macrocode}
4896%
4897%
4898% \subsection{A little display handling}
4899%
4900% I'm probably going a little far here, and invading territory already
4901% claimed by the \package{amsmath} stuff (and done a good deal better than
4902% I can be bothered to do), but just for completeness, this is how we handle
4903% attempts to put displays inside other displays without screwing up the
4904% spacing.
4905%
4906% \begin{macro}{\dsp@startouter}
4907%
4908% This is how we start an outermost display. It's fairly easy really. We
4909% make |\dsp@start| start an inner display, and make |\dsp@end| close the
4910% outer display.
4911%
4912% \begin{macrocode}
4913\def\dsp@startouter{%
4914 \let\dsp@end\dsp@endouter%
4915 $$%
4916}
4917% \end{macrocode}
4918%
4919% \end{macro}
4920%
4921% \begin{macro}{\dsp@endouter}
4922%
4923% Ending the outer display is utterly trivial.
4924%
4925% \begin{macrocode}
4926\def\dsp@endouter{$$}
4927% \end{macrocode}
4928%
4929% \end{macro}
4930%
4931% \begin{macro}{\dsp@startinner}
4932%
4933% Starting inner displays is done in a vbox (actually I choose |\vbox| or
4934% |\vtop| depending on the setting of \textsf{leqno} to put the equation
4935% number the right way round).
4936%
4937% \begin{macrocode}
4938\def\dsp@startinner{%
4939 \let\dsp@end\dsp@endinner%
4940 \if@fleqn\kern-\mathindent\fi%
4941 \if@leqno\vtop\else\vtop\fi\bgroup%
4942}
4943% \end{macrocode}
4944%
4945% \end{macro}
4946%
4947% \begin{macro}{\dsp@endinner}
4948%
4949% Ending an inner display is also really easy.
4950%
4951% \begin{macrocode}
4952\def\dsp@endinner{\egroup}
4953% \end{macrocode}
4954%
4955% \end{macro}
4956%
4957% \begin{macro}{\dsp@start}
4958%
4959% This is what other bits of code uses to start displays. It's one of the
4960% start macros up above, and outer by default.
4961%
4962% \begin{macrocode}
4963\def\dsp@start{%
4964 \ifmmode%
4965 %\ifinner\mth@err@mdsp\fi%
4966 \expandafter\dsp@startinner%
4967 \else%
4968 \ifhmode\ifinner\mth@err@hdsp\fi\fi%
4969 \expandafter\dsp@startouter%
4970 \fi%
4971}
4972% \end{macrocode}
4973%
4974% \end{macro}
4975%
4976% \begin{macro}{\dsp@tabpause}
4977%
4978% This sets up the correct pre- and postambles for the |\tabpause| macro in
4979% maths displays. This is fairly simple stuff.
4980%
4981% \begin{macrocode}
4982\def\dsp@tabpause{%
4983 \def\tab@startpause%
4984 {\penalty\postdisplaypenalty\vskip\belowdisplayskip}%
4985 \def\tab@endpause%
4986 {\penalty\predisplaypenalty\vskip\abovedisplayskip}%
4987}
4988% \end{macrocode}
4989%
4990% \end{macro}
4991%
4992%
4993% \subsection{The \env{eqnarray} environment}
4994%
4995% We allow the user to play with the style if this is really wanted. I dunno
4996% why, really. Maybe someone wants very small alignments.
4997%
4998% \begin{macrocode}
4999\let\eqastyle\displaystyle
5000% \end{macrocode}
5001%
5002% \subsubsection{The main environments}
5003%
5004% \begin{environment}{eqnarray}
5005% \begin{environment}{eqnarray*}
5006%
5007% We define the toplevel commands here. They just add in default arguments
5008% and then call |\@eqnarray| with a preamble string. We handle equation
5009% numbers by setting up a default (|\eqa@defnumber|) which is put into
5010% the final column. At the beginning of each row, we globally |\let|
5011% |\eqa@number| equal to |\eqa@defnumber|. The |\eqnumber| macro just
5012% changes |\eqa@number| as required. Since |\eqa@number| is changed globally
5013% we must save it in this environment.
5014%
5015% First, we must sort out the optional arguments and things. This is really
5016% easy. The only difference between the starred and non-starred environments
5017% is the default definition of |\eqa@defnumber|.
5018%
5019% \begin{macrocode}
5020\def\eqnarray{%
5021 \eqnarray@i\eqa@eqcount%
5022}
5023\@namedef{eqnarray*}{\eqnarray@i{}}
7abe48b3 5024\def\eqnarray@i#1{\@testopt{\eqnarray@ii{#1}}{rcl}}
86f6a31e 5025% \end{macrocode}
5026%
5027% Right. Now for the real work. The first argument is the default numbering
5028% tokens; the second is the preamble string.
5029%
5030% \begin{macrocode}
5031\def\eqnarray@ii#1[#2]{%
5032% \end{macrocode}
5033%
5034% Set up the equation counter and labels correctly.
5035%
5036% \medskip\par\noindent|\begin{rant}|\par
5037% The hacking with |\@currentlabel| is here because (in the author's opinion)
5038% \LaTeX's |\refstepcounter| macro is broken. It's currently defined as
5039% \begin{listing}
5040%\def\refstepcounter#1{%
5041% \stepcounter{#1}%
5042% \protected@edef\@currentlabel%
5043% {\csname p@#1\endcsname\csname the#1\endcsname}%
5044%}
5045% \end{listing}
5046% which means that the current label gets `frozen' as soon as you do the
5047% counter step. By redefining the macro as
5048% \begin{listing}
5049%\def\refstepcounter#1{%
5050% \stepcounter{#1}%
5051% \edef\@currentlabel{%
5052% \expandafter\noexpand\csname p@#1\endcsname%
5053% \expandafter\noexpand\csname the#1\endcsname%
5054% }%
5055%}
5056% \end{listing}
5057% these sorts of problems would be avoided, without any loss of functionality
5058% or compatibility that I can see.
5059% \par\noindent|\end{rant}|\par
5060%
5061% \begin{macrocode}
5062 \stepcounter{equation}%
5063 \def\@currentlabel{\p@equation\theequation}%
5064% \end{macrocode}
5065%
5066% The next step is to set up the numbering. I must save the old numbering
5067% so I can restore it later (once in the alignment, I must assign these
5068% things globally).
5069%
5070% \begin{macrocode}
5071 \let\eqa@oldnumber\eqa@number%
5072 \def\eqa@defnumber{#1}%
5073 \global\let\eqa@number\eqa@defnumber%
5074% \end{macrocode}
5075%
5076% The |\if@eqalastfalse| switch is false everywhere except when we're in the
5077% final column.
5078%
5079% \begin{macrocode}
5080 \@eqalastfalse%
5081% \end{macrocode}
5082%
5083% Remove the |\mathsurround| kerning, since it will look very odd inside
5084% the display. We have our own spacing parameters for configuring these
5085% things, so |\mathsurround| is unnecessary.
5086%
5087% \begin{macrocode}
5088 \m@th%
5089% \end{macrocode}
5090%
5091% Time to parse the preamble string now. I must choose the correct column
5092% set, initialise the preamble parser and set up the various macros. The%
5093% extra `|@{\tabskip\eqacloseskip}|' item sets up the tabskip glue to centre
5094% the alignment properly.
5095%
5096% \begin{macrocode}
5097 \colset{eqnarray}%
5098 \tab@initread%
5099 \def\tab@tabtext{&\tabskip\z@skip}%
5100 \tab@preamble{\tabskip\z@skip}%
5101 \tab@readpreamble{#2@{\tabskip\eqacloseskip}}%
5102 \dsp@tabpause%
5103% \end{macrocode}
5104%
5105% Now for some final setting up. The column separation is set from the
5106% user's parameter, the |\everycr| tokens are cleared, and I set up the
5107% newline command appropriately.
5108%
5109% \begin{macrocode}
5110 \col@sep.5\eqainskip%
5111 \everycr{}%
5112 \let\\\@eqncr%
5113% \end{macrocode}
5114%
5115% Now start a maths display and do the alignment. Set up the left hand
5116% tabskip glue to centre the alignment, and do the actual alignment.
5117% The preamble used is mainly that generated from the user's string, although
5118% the stuff at the end is how we set up the equation number -- it repeats
5119% appropriately so we can always find it.
5120%
5121% \begin{macrocode}
5122 \dsp@start%
5123 \tabskip\eqaopenskip%
5124 \halign to\displaywidth\expandafter\bgroup%
5125 \the\tab@preamble%
5126 &&\eqa@lastcol\hb@xt@\z@{\hss##}\tabskip\z@\cr%
5127}
5128% \end{macrocode}
5129%
5130% Now for the end of the environment. This is really easy. Set the final
5131% equation number, close the |\halign|, tidy up the equation counter (it's
5132% been stepped once too many times) and close the display.
5133%
5134% \begin{macrocode}
5135\def\endeqnarray{%
5136 \eqa@eqnum%
5137 \egroup%
5138 \dsp@end%
5139 \global\let\eqa@number\eqa@oldnumber%
5140 \global\@ignoretrue%
5141 \global\advance\c@equation\m@ne%
5142}
5143\expandafter\let\csname endeqnarray*\endcsname\endeqnarray
5144% \end{macrocode}
5145%
5146% \end{environment}
5147% \end{environment}
5148%
e8e9e5d8 5149% Now we can define the column types.
86f6a31e 5150%
5151% \begin{macrocode}
5152\colpush{eqnarray}
5153% \end{macrocode}
5154%
5155% Note the positioning of ord atoms in the stuff below. This will space out
5156% relations and binops correctly when they occur at the edges of columns, and
5157% won't affect ord atoms at the edges, because ords pack closely.
5158%
5159% First the easy ones. Just stick |\hfil| in the right places and
5160% everything will be all right.
5161%
5162% \begin{macrocode}
5163\coldef r{\tabcoltype{\hfil$\eqastyle}{{}$}}
5164\coldef c{\tabcoltype{\hfil$\eqastyle{}}{{}$\hfil}}
5165\coldef l{\tabcoltype{$\eqastyle{}}{$\hfil}}
5166\coldef x{\tabcoltype{\if@fleqn\else\hfil\fi$\eqastyle}{$\hfil}}
5167% \end{macrocode}
5168%
5169% Now for the textual ones. This is also fairly easy.
5170%
5171% \begin{macrocode}
5172\collet T [tabular]T
5173% \end{macrocode}
5174%
5175% Sort of split types of equations. I mustn't use |\rlap| here, or
5176% everything goes wrong -- |\\| doesn't get noticed by \TeX\ in the same way
5177% as |\cr| does.
5178%
5179% \begin{macrocode}
5180\coldef L{\tabcoltype{\hb@xt@2em\bgroup$\eqastyle}{$\hss\egroup}}
5181% \end{macrocode}
5182%
5183% The \lit{:} column type is fairly simple.
5184%
5185% \begin{macrocode}
5186\coldef :{\tabspctype{\tabskip\eqacolskip}}
5187\coldef q{\tabspctype{\quad}}
5188% \end{macrocode}
5189%
5190% The other column types just insert given text in an appropriate way.
5191%
5192% \begin{macrocode}
5193\collet > [tabular]>
5194\collet < [tabular]<
5195\collet * [tabular]*
5196\collet @ [tabular]@
5197% \end{macrocode}
5198%
5199% Finally, the magical `|\magic|' column type, which sets the equation
5200% number. We set up the |\tabskip| glue properly, tab on, and set the flag
5201% which marks the final column. The |\eqa@lastcol| command is there to
5202% raise an error if the user tabs over to this column. I'll temporarily
5203% redefine it to |\@eqalasttrue| when I enter this column legitimately.
5204% The extra magical bits here will make the final column repeat, so that we
5205% can find it if necessary. Well is this column type named.
5206%
5207% That's it. We can return to normal now.
5208%
5209% \begin{macrocode}
5210\colpop
5211% \end{macrocode}
5212%
5213% \subsubsection{Newline codes}
5214%
5215% Newline sequences (|\\|) get turned into calls of |\@eqncr|. The job is
5216% fairly simple, really.
5217%
5218% \begin{macrocode}
5219\def\@eqncr{\tab@cr\eqacr@i\interdisplaylinepenalty\@M}%
5220\def\eqacr@i#1#2{%
5221 \eqa@eqnum%
5222 \noalign{\penalty#2\vskip\jot\vskip#1}%
5223}
5224% \end{macrocode}
5225%
5226% \subsubsection{Setting equation numbers}
5227%
5228% \begin{macro}{\eqa@eqpos}
5229%
5230% Before we start, we need to generalise the flush-left number handling bits.
5231% The macro |\eqa@eqpos| will put its argument in the right place.
5232%
5233% \begin{macrocode}
7ef5ba2c
MW
5234\def\eqa@eqpos#1{%
5235 \if@leqno%
86f6a31e 5236 \hb@xt@.01\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
7ef5ba2c
MW
5237 \else%
5238 \normalfont\normalcolor#1%
5239 \fi%
5240}
86f6a31e 5241% \end{macrocode}
5242%
5243% \end{macro}
5244%
5245% \begin{macro}{\eqa@eqnum}
5246%
5247% Here we typeset an equation number in roughly the right place. First I'll
5248% redefine |\eqa@lastcol| so that it tells me I'm in the right place, and
5249% start a loop to find that place.
5250%
5251% \begin{macrocode}
5252\def\eqa@eqnum{%
5253 \global\let\eqa@lastcol\@eqalasttrue%
5254 \eqa@eqnum@i%
5255}
5256% \end{macrocode}
5257%
5258% Now for the loop. The |\relax| here is absolutely vital -- it starts the
5259% table column, inserting useful tokens like `|\eqa@lastcol|' which tell
5260% me where I am in the alignment. Then, if I've reached the end, I can
5261% typeset the equation number; otherwise I go off into another macro and
5262% step on to the next column.
5263%
5264% \begin{macrocode}
5265\def\eqa@eqnum@i{%
5266 \relax%
5267 \if@eqalast%
5268 \expandafter\eqa@eqnum@ii%
5269 \else%
5270 \expandafter\eqa@eqnum@iii%
5271 \fi%
5272}
5273\def\eqa@eqnum@ii{%
5274 \eqa@eqpos\eqa@number%
5275 \global\let\eqa@number\eqa@defnumber%
5276 \global\let\eqa@lastcol\eqa@@lastcol%
5277 \cr%
5278}
5279\def\eqa@eqnum@iii{&\eqa@eqnum@i}
5280% \end{macrocode}
5281%
5282% \end{macro}
5283%
5284% \begin{macro}{\eqa@lastcol}
5285%
5286% This is used as a marker for the final column in an \env{eqnarray}
5287% environment. By default it informs the user that they've been very
5288% silly and swallows the contents of the column. I'll redefine it to
5289% something more useful at appropriate times, and then turn it back again.
5290%
5291% \begin{macrocode}
5292\def\eqa@@lastcol{\mth@err@number\setbox\z@}
5293\let\eqa@lastcol\eqa@@lastcol
5294% \end{macrocode}
5295%
5296% \end{macro}
5297%
5298% \subsubsection{Numbering control}
5299%
5300% \begin{macro}{\eqnumber}
5301%
5302% The |\eqnumber| command sets the equation number on the current equation.
5303% This is really easy, actually.
5304%
5305% \begin{macrocode}
5306\newcommand\eqnumber[1][\eqa@eqcount]{\gdef\eqa@number{#1}}
5307% \end{macrocode}
5308%
5309% \end{macro}
5310%
5311% \begin{macro}{\eqa@eqcount}
5312%
5313% This is how a standard equation number is set, stepping the counter and
5314% all. It's really easy and obvious.
5315%
5316% \begin{macrocode}
5317\def\eqa@eqcount{(\theequation)\global\advance\c@equation\@ne}
5318% \end{macrocode}
5319%
5320% \end{macro}
5321%
5322% \begin{macro}{\nonumber}
5323%
5324% The \LaTeX\ |\nonumber| command could be defined by saying
5325% \begin{listing}
5326%\renewcommand{\nonumber}{\eqnumber[]}
5327% \end{listing}
5328% but I'll be slightly more efficient and redefine |\eqa@number| directly.
5329%
5330% \begin{macrocode}
5331\def\nonumber{\global\let\eqa@number\@empty}
5332% \end{macrocode}
5333%
5334% \end{macro}
5335%
5336% \subsubsection{The \env{eqnalign} environment}
5337%
5338% As a sort of companion to \env{eqnarray}, here's an environment which does
5339% similar things inside a box, rather than taking up the whole display width.
5340% It uses the same column types that we've already created, so there should
5341% be no problems.
5342%
5343% \begin{environment}{eqnalign}
5344%
5345% First, sort out some simple things like optional arguments.
5346%
5347% \begin{macrocode}
7abe48b3 5348\def\eqnalign{\@testopt\eqnalign@i{rcl}}
5349\def\eqnalign@i[#1]{\@testopt{\eqnalign@ii{#1}}c}
86f6a31e 5350% \end{macrocode}
5351%
5352% Now we actually do the environment. This is fairly easy, actually.
5353%
5354% \begin{macrocode}
5355\def\eqnalign@ii#1[#2]{%
5356 \let\\\eqn@cr%
5357 \colset{eqnarray}%
5358 \tab@initread%
5359 \def\tab@tabtext{&\tabskip\z@skip}%
5360 \tabskip\z@skip%
5361 \col@sep.5\eqainskip%
5362 \tab@readpreamble{#1}%
5363 \everycr{}%
5364 \if#2t\vtop\else%
5365 \if#2b\vbox\else%
5366 \vcenter%
5367 \fi%
5368 \fi%
5369 \bgroup%
5370 \halign\expandafter\bgroup\the\tab@preamble\cr%
5371}
5372% \end{macrocode}
5373%
5374% Finishing the environment is even simpler.
5375%
5376% \begin{macrocode}
5377\def\endeqnalign{%
5378 \crcr%
5379 \egroup%
5380 \egroup%
5381}
5382% \end{macrocode}
5383%
5384% \end{environment}
5385%
5386% \begin{macro}{\eqn@cr}
5387%
5388% Newlines are really easy here.
5389%
5390% \begin{macrocode}
5391\def\eqn@cr{\tab@cr\eqn@cr@i{}{}}
5392\def\eqn@cr@i#1{\cr\noalign{\vskip\jot\vskip#1}\@gobble}
5393% \end{macrocode}
5394%
5395% \end{macro}
5396%
5397%
5398% \subsection{Simple multiline equations}
5399%
5400% As a sort of example and abbreviation, here's a multiline display
5401% environment which just centres everything.
5402%
5403% \begin{environment}{eqlines}
5404%
5405% We just get |\eqnarray| to do everything for us. This is really easy.
5406%
5407% \begin{macrocode}
5408\def\eqlines{\eqnarray[x]}
5409\let\endeqlines\endeqnarray
5410% \end{macrocode}
5411%
5412% \end{environment}
5413%
5414% \begin{environment}{eqlines*}
5415%
5416% There's a $*$ version which omits numbers. This is easy too. Lots of
5417% hacking with expansion here to try and reduce the number of tokens being
5418% used. Is it worth it?
5419%
5420% \begin{macrocode}
5421\expandafter\edef\csname eqlines*\endcsname{%
5422 \expandafter\noexpand\csname eqnarray*\endcsname[x]%
5423}
5424\expandafter\let\csname endeqlines*\expandafter\endcsname
5425 \csname endeqnarray*\endcsname
5426% \end{macrocode}
5427%
5428% \end{environment}
5429%
5430%
5431% \subsection{Split equations}
5432%
5433% Based on an idea from \textit{The \TeX book}, we provide some simple
5434% environments for doing split equations. There's plenty of scope for
5435% improvement here, though.
5436%
5437% \begin{environment}{spliteqn}
5438% \begin{environment}{spliteqn*}
5439%
5440% The only difference between these two is that the $*$-version doesn't put
5441% in an equation number by default (although this behaviour can be
5442% changed by |\eqnumber|).
5443%
5444% The fun here mainly concerns putting in the equation number at the right
5445% place -- for |leqno| users, we need to put the number on the first line;
5446% otherwise we put it on the last line.
5447%
5448% The way we handle this is to have two macros, |\\| (which clearly does
5449% all the user line breaks) and |\seq@lastcr| which is used at the end of
5450% the environment to wrap everything up. The |\seq@eqnocr| macro puts an
5451% equation number on the current line and then does a normal |\\|. It also
5452% resets |\\| and |\seq@lastcr| so that they don't try to put another
5453% equation number in. This must be done globally, although anyone who tries
5454% to nest maths displays will get what they deserve.
5455%
5456% For the non-$*$ environment, then, we need to step the equation counter,
5457% and set |\\| to |\seq@cr| or |\seq@eqnocr| as appropriate for the setting
5458% of the |leqno| flag -- |\seq@lastcr| always gets set to put an equation
5459% number in (because it will be reset if the number actually gets done
5460% earlier -- this catches stupid users trying to put a single row into
5461% a split environment).
5462%
5463% \begin{macrocode}
5464\def\spliteqn{%
5465 \let\eqa@oldnumber\eqa@number%
5466 \global\let\eqa@number\eqa@eqcount%
5467 \spliteqn@i%
5468}
5469% \end{macrocode}
5470%
5471% For the $*$ variant, we don't need to bother with equation numbering, so
5472% this is really easy.
5473%
5474% \begin{macrocode}
5475\@namedef{spliteqn*}{%
5476 \let\eqa@oldnumber\eqa@number%
5477 \gdef\eqa@number{}%
5478 \spliteqn@i%
5479}
5480% \end{macrocode}
5481%
5482% Ending the environments is easy. Most of the stuff here will be described
5483% later.
5484%
5485% \begin{macrocode}
5486\def\endspliteqn{%
5487 \hfilneg\seq@lastcr%
5488 \egroup%
5489 \dsp@end%
5490 \global\let\eqa@number\eqa@oldnumber%
5491 \global\advance\c@equation\m@ne%
b57a27e1 5492 \global\@ignoretrue%
86f6a31e 5493}
5494\expandafter\let\csname endspliteqn*\endcsname\endspliteqn
5495% \end{macrocode}
5496%
5497% \end{environment}
5498% \end{environment}
5499%
5500% \begin{macro}{\spliteqn@i}
5501%
5502% Here we handle the full display splits. Start a maths display, and make
5503% each row of the alignment take up the full display width.
5504%
5505% The macro |\seq@dosplit| does most of the real work for us -- setting up
5506% the alignment and so forth. The template column is interesting. There
5507% are two items glue on both sides of the actual text:
5508%
5509% \begin{itemize}
5510%
5511% \item Some glue which can shrink. This keeps the display from the edges
5512% of the page unless we get a really wide item.
5513%
5514% \item An |\hfil| to do the alignment. By default, this centres the
5515% equations. On the first line, however, we put a leading |\hfilneg|
5516% which cancels the first |\hfil|, making the first row left aligned.
5517% Similarly, at the end, we put an |\hfilneg| after the last equation
5518% to right align the last line.
5519%
5520% \end{itemize}
5521%
5522% We pass this information on as an argument. It's easy really.
5523%
5524% \begin{macrocode}
5525\def\spliteqn@i{%
5526% \end{macrocode}
5527%
5528% First, set up equation numbering properly. See my rant about
5529% |\refstepcounter| above.
5530%
5531% \begin{macrocode}
5532 \stepcounter{equation}%
5533 \def\@currentlabel{\p@equation\theequation}%
5534% \end{macrocode}
5535%
5536% Right; now to sort out the numbering and newline handling. If the number's
5537% meant to be on the first line (for \textsf{leqno} users), then it gets
5538% typeset on the first like; otherwise we just do a normal newline on
5539% all lines except the first. Once |\seq@eqnocr| has done its stuff, it
5540% redefines all the newline handling not to insert another number.
5541%
5542% \begin{macrocode}
5543 \if@leqno%
5544 \global\let\seq@docr\seq@eqnocr%
5545 \else%
5546 \global\let\seq@docr\seq@cr%
5547 \fi%
5548 \global\let\seq@lastcr\seq@eqnocr%
5549% \end{macrocode}
5550%
5551% For my next trick, I'll do some display handling -- start a (possibly
5552% nested) maths display, set up the |\tabpause| macro appropriately, and
5553% set the newline command to do the right thing.
5554%
5555% \begin{macrocode}
5556 \dsp@start%
5557 \dsp@tabpause%
5558 \def\\{\seq@docr}%
5559% \end{macrocode}
5560%
5561% Finally, call another macro to do the remaining bits of setting up.
5562%
5563% \begin{macrocode}
5564 \seq@dosplit%
5565 {\hb@xt@\displaywidth{%
5566 \hskip\splitleft\hfil$\displaystyle##$%
5567 \hfil\hskip\splitright}}%
5568 {\hfilneg}%
5569}
5570% \end{macrocode}
5571%
5572% \end{macro}
5573%
5574% \begin{environment}{subsplit}
5575%
5576% For doing splits in the middle of equations, we provide a similar
5577% environment. Here, we make |\\| just start a new line. We also use
5578% a |\vcenter| rather than a full maths display. The glue items are also
5579% a bit different: we use plain double-quads on each side of the item, and
5580% we need to remove them by hand at the extremities of the environment.
5581%
5582% \begin{macrocode}
c728af0b
MW
5583\def\subsplit{\@ifnextchar[\subsplit@i{\subsplit@i[c]}}
5584\def\subsplit@i[#1]{%
5585 \let\@tempa\vcenter%
5586 \if#1t\let\@tempa\vtop\fi%
5587 \if#1b\let\@tempa\vbox\fi%
86f6a31e 5588 \let\\\seq@cr%
c728af0b 5589 \@tempa\bgroup%
86f6a31e 5590 \seq@dosplit{\hfil\qquad$##$\qquad\hfil}{\hfilneg\hskip-2em}%
5591}
5592% \end{macrocode}
5593%
5594% Ending the environment is fairly easy. We remove the final glue item,
5595% and close the alignment and the vbox.
5596%
5597% \begin{macrocode}
5598\def\endsubsplit{%
5599 \hfilneg\hskip-2em\cr%
5600 \egroup\egroup%
5601}
5602% \end{macrocode}
5603%
5604% \end{environment}
5605%
5606% \begin{macro}{\seq@dosplit}
5607%
5608% Here we do most of the real work. Actually, since the preamble is passed
5609% in as an argument, most of the work is already done. The only thing to
5610% really note is the template for subsequent columns. To stop users putting
5611% in extra columns (which is where we put the equation number) we raise an
5612% error and discard the input in a scratch box register. This template is
5613% repeated infinitely so as to allow us to put the equation number in nicely.
5614% However, the final negative glue item won't work properly, so the equation
5615% will look awful.
5616%
5617% \begin{macrocode}
5618\def\seq@dosplit#1#2{%
5619 \halign\bgroup%
5620 #1&&\mth@err@number\setbox\z@\hbox{##}\cr%
5621 #2\relax%
5622}
5623% \end{macrocode}
5624%
5625% \end{macro}
5626%
5627% \begin{macro}{\seq@eqnocr}
5628%
5629% Here's how we set equation numbers. Since the column provided raises
5630% errors as soon as a token finds its way into it, we start with a |&\omit|.
5631% Then we just put the equation number in a zero-width box. Finally, we
5632% reset the newline commands to avoid putting in more than one equation
5633% number, and do normal newline things.
5634%
5635% \begin{macrocode}
5636\def\seq@eqnocr{%
5637 &\omit%
5638 \hb@xt@\z@{\hss\eqa@eqpos\eqa@number}%
5639 \global\let\seq@docr\seq@cr%
5640 \global\let\seq@lastcr\seq@cr%
5641 \seq@cr%
5642}
5643% \end{macrocode}
5644%
5645% \end{macro}
5646%
5647% \begin{macro}{\seq@cr}
5648%
5649% Newlines are very easy. We add a |\jot| of extra space, since this is
5650% a nice thing to do.
5651%
5652% \begin{macrocode}
5653\def\seq@cr{\tab@cr\seq@cr@i\interdisplaylinepenalty\@M}
5654\def\seq@cr@i#1#2{\cr\noalign{\penalty#2\vskip\jot\vskip#1}}
5655% \end{macrocode}
5656%
5657% \end{macro}
5658%
5659%
5660% \subsection{Matrix handling}
5661%
5662% There's been a complete and total overhaul of the spacing calculations
5663% for matrices here. The vertical spacing now bears an uncanny similarity
5664% to the rules \TeX\ uses to space out |\atop|-like fractions, the difference
5665% being that you can have more than one column in a matrix. This has the
5666% interesting side-effect that we get an \package{amsmath}-style
5667% sub/superscript environment almost free of charge with the matrix handling
5668% (it just ends up being a script-size single-column matrix).
5669%
5670% What is rather gratifying is that our \env{matrix} environment looks
5671% rather nicer than \package{amsmath}'s (which is based directly on
5672% \env{array}, giving it nasty restrictions on the numbers of columns and
5673% so on); in particular, the version here gives the `correct' result for
5674% Knuth's exercise~18.42 (which states categorically that a |\smallskip|
5675% should be placed between the rows of the big matrix).
5676%
5677% The reason the interrow space doesn't come out in the AMS version is
5678% that \env{array} inserts extra vertical space by extending the depth of
5679% the final row using a strut: the big matrix already extends deeper than
5680% this, so the strut doesn't make any difference. If the space was added
5681% by |\hlx{s[\smallskipamount]}| instead of the |\\| command, things would
5682% be different.
5683%
5684% \begin{figure}
5685%
5686% ^^A This is essentially what amsmath (version 1.2b) does. The real
5687% ^^A implementation requires a counter MaxMatrixCols, and has fewer braces:
5688% ^^A that's all the difference. Oh, and I turn off \arrayextrasep here,
5689% ^^A since amsmath doesn't expect it to be there (accurate emulation, see?)
5690% ^^A and I've used \hspace instead of \hskip since everything else is
5691% ^^A `proper' LaTeX stuff.
5692%
5693% \newenvironment{ams-pmatrix}{^^A
5694% \setlength{\arrayextrasep}{0pt}^^A
5695% \left(^^A
5696% \hspace{-\arraycolsep}^^A
5697% \begin{array}{*{10}{c}}^^A
5698% }{^^A
5699% \end{array}^^A
5700% \hspace{-\arraycolsep}^^A
5701% \right)^^A
5702% }
5703%
5704% \begin{demo}{Exercise 18.42 from \emph{The \TeX book}}
5705%\newcommand{\domatrix}[1]{
5706% \def\mat##1
5707% {\begin{#1}##1\end{#1}}
5708% \[ \begin{#1}
5709% \mat{a & b \\ c & d} &
5710% \mat{e & f \\ g & h}
5711% \\[\smallskipamount]
5712% 0 &
5713% \mat{i & j \\ k & l}
5714% \end{#1}
5715% \]
5716%}
5717%\domatrix{pmatrix}
5718%\domatrix{ams-pmatrix}
5719% \end{demo}
5720%
5721% \end{figure}
5722%
5723% \begin{environment}{genmatrix}
5724%
5725% The first job is to store my maths style and font away, because I'll be
5726% needing it lots later.
5727%
5728% \begin{macrocode}
5729\def\genmatrix#1#2#3#4#5{%
5730 \let\mat@style#1%
5731 \ifx#2\scriptstyle%
5732 \let\mat@font\scriptfont%
5733 \else\ifx#2\scriptscriptstyle%
5734 \let\mat@font\scriptscriptfont%
5735 \else%
5736 \let\mat@font\textfont%
5737 \fi\fi%
5738% \end{macrocode}
5739%
5740% Now to cope with inserted text. This is easy.
5741%
5742% \begin{macrocode}
5743 \ifx\mat@style\scriptstyle%
5744 \let\mat@textsize\scriptsize%
5745 \else\ifx\mat@style\scriptscriptstyle%
5746 \let\mat@textsize\scriptscriptsize%
5747 \else%
5748 \let\mat@textsize\relax%
5749 \fi\fi%
5750% \end{macrocode}
5751%
5752% Now for some fun. I'll remember how to start and end the matrix in a
5753% couple of macros |\mat@left| and |\mat@right|. I haven't yet worked out
5754% exactly what needs to be in |\mat@right| yet, though, so I'll build that
5755% up in a scratch token list while I'm making my mind up.
5756%
5757% Initially, I want to open a group (to trap the style changes), set the
5758% maths style (to get the right spacing), insert the left delimiter, insert
5759% some spacing around the matrix, and start a centred box. The ending just
5760% closes all the groups and delimiters I opened.
5761%
5762% \begin{macrocode}
5763 \def\mat@left{\bgroup\mat@style\left#4#3\vcenter\bgroup}%
5764 \toks@{\egroup#3\right#5\egroup}%
5765% \end{macrocode}
5766%
5767% Now comes a slightly trickier bit. If the maths style is script or
5768% scriptscript, then I need to raise the box by a little bit to make it look
5769% really good. The right amount is somewhere around \smallf 3/4\,pt, I
5770% think, so that's what I'll use.
5771%
5772% \begin{macrocode}
5773 \@tempswatrue%
5774 \ifx\mat@style\displaystyle\else\ifx\mat@style\textstyle\else%
5775 \@tempswafalse%
5776 \setbox\z@\hbox\bgroup$%
5777 \toks@\expandafter{\the\toks@$\m@th\egroup\raise.75\p@\box\z@}%
5778 \fi\fi%
5779% \end{macrocode}
5780%
5781% If I'm not in maths mode right now, then I should enter maths mode, and
5782% remember to leave it later.
5783%
5784% \begin{macrocode}
5785 \if@tempswa\ifmmode\else%
5786 $\m@th%
5787 \toks@\expandafter{\the\toks@$}%
5788 \fi\fi%
5789% \end{macrocode}
5790%
5791% Now I've sorted out how to end the environment properly, so I can set up
5792% the macro, using |\edef|.
5793%
5794% \begin{macrocode}
5795 \edef\mat@right{\the\toks@}%
5796% \end{macrocode}
5797%
5798% Now see if there's an optional argument. If not, create lots of centred
5799% columns.
5800%
5801% \begin{macrocode}
7abe48b3 5802 \@testopt\genmatrix@i{[c}%
86f6a31e 5803}
5804% \end{macrocode}
5805%
5806% Now to sort out everything else.
5807%
5808% \begin{macrocode}
5809\def\genmatrix@i[#1]{%
5810% \end{macrocode}
5811%
5812% Some initial setting up: choose the correct column set, and set up some
5813% variables for reading the preamble.
5814%
5815% \begin{macrocode}
5816 \colset{matrix}%
5817 \tab@initread%
5818% \end{macrocode}
5819%
5820% Now comes some of the tricky stuff. The space between columns should be
5821% 12\,mu (by trial and error). We put the space in a box so we can measure
5822% it in the correct mathstyle.
5823%
5824% \begin{macrocode}
5825 \setbox\z@\hbox{$\mat@style\mskip12mu$}%
5826 \edef\tab@tabtext{&\kern\the\wd\z@}%
5827 \tab@readpreamble{#1}%
5828% \end{macrocode}
5829%
5830% Now we need to decide how to space out the rows. The code here is based
5831% on the information in appendix~G of \emph{The \TeX book}: I think it'd be
5832% nice if my matrices were spaced out in the same way as normal fractions
5833% (particularly |\choose|y things). The standard |\baselineskip| and
5834% |\lineskip| parameters come in really handy here.
5835%
5836% The parameters vary according to the size of the text, so I need to see
5837% if we have scriptsize or less, or not. The tricky |\if| sorts this out.
5838%
5839% \begin{macrocode}
5840 \if1\ifx\mat@style\scriptstyle1\else%
5841 \ifx\mat@style\scriptscriptstyle1\else0\fi\fi%
5842 \baselineskip\fontdimen10\mat@font\tw@%
5843 \advance\baselineskip\fontdimen12\mat@font\tw@%
5844 \lineskip\thr@@\fontdimen8\mat@font\thr@@%
5845 \else%
5846 \baselineskip\fontdimen8\mat@font\tw@%
5847 \advance\baselineskip\fontdimen11\mat@font\tw@%
5848 \lineskip7\fontdimen8\mat@font\thr@@%
5849 \fi%
5850 \lineskiplimit\lineskip%
5851% \end{macrocode}
5852%
5853% Now actually set up for the alignment. Assign |\\| to the correct value.
5854% Set up the |\tabskip|. Do the appropriate |\mat@left| thing set up above.
5855% And then start the alignment.
5856%
5857% \begin{macrocode}
5858 \let\\\mat@cr%
5859 \tabskip\z@skip%
5860 \col@sep\z@%
5861 \mat@left%
5862 \halign\expandafter\bgroup\the\tab@preamble\tabskip\z@skip\cr%
5863% \end{macrocode}
5864%
5865% Now for a little hack to make the spacing consistent between matrices of
5866% the same height. This comes directly from \PlainTeX. This appears to
5867% make the spacing \emph{exactly} the same as the \TeX\ primitives, oddly
5868% enough.
5869%
5870% \begin{macrocode}
5871 \ifx\mat@font\textfont%
5872 \omit$\mat@style\mathstrut$\cr\noalign{\kern-\baselineskip}%
5873 \fi%
5874}
5875% \end{macrocode}
5876%
5877% Finishing the environment is really easy. We do the spacing hack again
5878% at the bottom, close the alignment and then tidy whatever we started in
5879% |\mat@left|.
5880%
5881% \begin{macrocode}
5882\def\endgenmatrix{%
5883 \crcr%
5884 \ifx\mat@font\textfont%
5885 \omit$\mat@style\mathstrut$\cr\noalign{\kern-\baselineskip}%
5886 \fi%
5887 \egroup%
5888 \mat@right%
5889}
5890% \end{macrocode}
5891%
5892% \end{environment}
5893%
5894% \begin{macro}{\mat@cr}
5895%
5896% Newlines are really easy. The $*$-form means nothing here, so we ignore
5897% it.
5898%
5899% \begin{macrocode}
5900\def\mat@cr{\tab@cr\mat@cr@i{}{}}
5901\def\mat@cr@i#1{\cr\noalign{\vskip#1}\@gobble}
5902% \end{macrocode}
5903%
5904% \end{macro}
5905%
5906% \begin{macro}{\newmatrix}
5907%
5908% This is how we define new matrix environments. It's simple fun with
5909% |\csname| and |\expandafter|.
5910%
5911% \begin{macrocode}
5912\def\newmatrix#1#2{%
5913 \@namedef{#1}{\genmatrix#2}%
5914 \expandafter\let\csname end#1\endcsname\endgenmatrix%
5915}
5916% \end{macrocode}
5917%
5918% \end{macro}
5919%
5920% \begin{environment}{matrix}
5921% \begin{environment}{pmatrix}
5922% \begin{environment}{dmatrix}
5923% \begin{environment}{smatrix}
5924% \begin{environment}{spmatrix}
5925% \begin{environment}{sdmatrix}
5926% \begin{environment}{smatrix*}
5927% \begin{environment}{spmatrix*}
5928% \begin{environment}{sdmatrix*}
5929%
5930% Now we define all the other environments we promised. This is easy.
5931%
5932% \begin{macrocode}
5933\newmatrix{matrix}{{\textstyle}{\textstyle}{\,}{.}{.}}
5934\newmatrix{pmatrix}{{\textstyle}{\textstyle}{\,}{(}{)}}
5935\newmatrix{dmatrix}{{\textstyle}{\textstyle}{\,}}
5936\newmatrix{smatrix}{{\scriptstyle}{\scriptstyle}{}{.}{.}}
5937\newmatrix{spmatrix}{{\scriptstyle}{\scriptstyle}{}{(}{)}}
5938\newmatrix{sdmatrix}{{\scriptstyle}{\scriptstyle}{}}
5939\newmatrix{smatrix*}{{\scriptstyle}{\textstyle}{}{.}{.}}
5940\newmatrix{spmatrix*}{{\scriptstyle}{\textstyle}{}{(}{)}}
5941\newmatrix{sdmatrix*}{{\scriptstyle}{\textstyle}{}}
5942% \end{macrocode}
5943%
5944% \end{environment}
5945% \end{environment}
5946% \end{environment}
5947% \end{environment}
5948% \end{environment}
5949% \end{environment}
5950% \end{environment}
5951% \end{environment}
5952% \end{environment}
5953%
5954% \begin{environment}{script}
5955%
5956% Now for superscripts and subscripts. This is fairly easy, because I
5957% took so much care over the matrix handling.
5958%
5959% \begin{macrocode}
5960\def\script{%
5961 \let\mat@style\scriptstyle%
5962 \def\mat@left{\vcenter\bgroup}%
5963 \def\mat@right{\egroup}%
5964 \let\mat@font\scriptfont%
5965 \let\mat@textsize\scriptsize%
7abe48b3 5966 \@testopt\genmatrix@i c%
86f6a31e 5967}
5968\let\endscript\endgenmatrix
5969% \end{macrocode}
5970%
5971% \end{environment}
5972%
5973% Now define the column types.
5974%
5975% \begin{macrocode}
5976\colpush{matrix}
5977\coldef l{\tabcoltype{\kern\z@$\mat@style}{\m@th$\hfil}}
5978\coldef c{\tabcoltype{\hfil$\mat@style}{\m@th$\hfil}}
5979\coldef r{\tabcoltype{\hfil$\mat@style}{\m@th$}}
5980\coldef T#1{\tab@aligncol{#1}{\begingroup\mat@textsize}{\endgroup}}
5981\collet > [tabular]>
5982\collet < [tabular]<
5983\collet * [tabular]*
5984\collet @ [tabular]@
5985% \end{macrocode}
5986%
5987% The repeating type is more awkward. Things will go wrong if this is
5988% given before the first column, so we must do a whole repeat by hand. We
5989% can tell if we haven't contributed a column yet, since |\tab@column| will
5990% be zero. Otherwise, we fiddle the parser state to start a new column, and
5991% insert the |&| character to make \TeX\ repeat the preamble.
5992%
5993% \begin{macrocode}
5994\coldef {[}{%
5995 \@firstoftwo{%
5996 \ifnum\tab@columns=\z@%
5997 \def\@tempa##1\q@delim{%
5998 \tab@mkpreamble##1[##1\q@delim%
5999 }%
6000 \expandafter\@tempa%
6001 \else%
6002 \tab@setstate\tab@prestate%
6003 \tab@append\tab@preamble{&}%
6004 \expandafter\tab@mkpreamble%
6005 \fi%
6006 }%
6007}
6008% \end{macrocode}
6009%
6010% We're done defining columns now.
6011%
6012% \begin{macrocode}
6013\colpop
6014% \end{macrocode}
6015%
6016%
6017% \subsection{Dots\dots}
6018%
6019% Nothing whatsoever to do with alignments, although vertical and diagonal
6020% dots in small matrices look really silly. The following hacky definitions
6021% work rather better.
6022%
6023% \begin{macro}{\mdw@dots}
6024%
6025% First of all, here's some definitions common to both of the dots macros.
6026% The macro takes as an argument the actual code to draw the dots, passing
6027% it the scaled size of a point in the scratch register |\dimen@|; the
6028% register |\box 0| is set to contain a dot of the appropriate size.
6029%
6030% \begin{macrocode}
6031\def\mdw@dots#1{\ensuremath{\mathpalette\mdw@dots@i{#1}}}
6032\def\mdw@dots@i#1#2{%
6033 \setbox\z@\hbox{$#1\mskip1.8mu$}%
6034 \dimen@\wd\z@%
6035 \setbox\z@\hbox{$#1.$}%
6036 #2%
6037}
6038% \end{macrocode}
6039%
6040% \end{macro}
6041%
6042% \begin{macro}{\vdots}
6043%
6044% I'll start with the easy one. This is a simple translation of the original
6045% implementation.
6046%
6047% \begin{macrocode}
6048\def\vdots{%
6049 \mdw@dots{\vbox{%
6050 \baselineskip4\dimen@%
6051 \lineskiplimit\z@%
6052 \kern6\dimen@%
6053 \copy\z@\copy\z@\box\z@%
6054 }}%
6055}
6056% \end{macrocode}
6057%
6058% \end{macro}
6059%
6060% \begin{macro}{\ddots}
6061%
6062% And I'll end with the other easy one\dots
6063%
6064% \begin{macrocode}
6065\def\ddots{%
6066 \mdw@dots{\mathinner{%
6067 \mkern1mu%
6068 \raise7\dimen@\vbox{\kern7\dimen@\copy\z@}%
6069 \mkern2mu%
6070 \raise4\dimen@\copy\z@%
6071 \mkern2mu%
6072 \raise\dimen@\box\z@%
6073 \mkern1mu%
6074 }}%
6075}
6076% \end{macrocode}
6077%
6078% \end{macro}
6079%
6080%
6081% \subsection{Lucky dip}
6082%
6083% Time to round off with some trivial environments, just to show how easy
6084% this stuff is.
6085%
6086% \begin{environment}{cases}
6087% \begin{environment}{smcases}
6088%
6089% These are totally and utterly trivial.
6090%
6091% \begin{macrocode}
6092\def\cases{\left\{\,\array{@{}lTl@{}}}
6093\def\endcases{\endarray\,\right.}
6094\def\smcases{\left\{\smarray{@{}lTl@{}}}
6095\def\endsmcases{\endsmarray\,\right.}
6096% \end{macrocode}
6097%
6098% \end{environment}
6099% \end{environment}
6100%
6101% \subsection{Error messages}
6102%
6103% Some token saving:
6104%
6105% \begin{macrocode}
6106\def\mth@error{\PackageError{mathenv}}
6107% \end{macrocode}
6108%
6109% Now for the error messages.
6110%
6111% \begin{macrocode}
6112\def\mth@err@number{%
6113 \mth@error{Too many `&' characters found}{%
6114 You've put too many `&' characters in an alignment^^J%
6115 environment (like `eqnarray' or `spliteqn') and wandered^^J%
6116 into trouble. I've gobbled the contents of that column^^J%
6117 and hopefully I can recover fairly easily.%
6118 }%
6119}
6120% \end{macrocode}
6121%
6122% \begin{macrocode}
6123\def\mth@err@mdsp{%
6124 \mth@error{Can't do displays in nondisplay maths mode}{%
6125 You're trying to start a display environment, but you're^^J%
6126 in nondisplay maths mode. The display will appear but^^J%
6127 don't blame me when it looks horrible.%
6128 }%
6129}
6130% \end{macrocode}
6131%
6132% \begin{macrocode}
6133\def\mth@err@hdsp{%
6134 \mth@error{Can't do displays in LR mode}{%
6135 You're trying to start a display environment, but you're^^J%
6136 in LR (restricted horizontal) mode. Everything will go^^J%
6137 totally wrong, so your best bet is to type `X', fix the^^J%
6138 mistake and start again.%
6139 }%
6140}
6141% \end{macrocode}
6142%
6143% \vskip\parskip\vbox{ ^^A The best way I could find of keeping this lot
6144% ^^A together, I'm afraid.
6145% That's all there is. Byebye.
6146%
6147% \begin{macrocode}
6148%</mathenv>
6149% \end{macrocode}
6150% \nopagebreak
6151%
6152% \hfill Mark Wooding, \today
6153% }
6154%
6155% \Finale
6156%
6157\endinput