% \begin{meta-comment}
%
-% $Id: mdwtab.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $
+% $Id: mdwtab.dtx,v 1.3 2003/11/10 14:43:48 mdw Exp $
%
% Another rewrite of the tabular environment, and maths alignments
%
% (c) 1996 Mark Wooding
%
-%----- Revision history -----------------------------------------------------
-%
-% $Log: mdwtab.dtx,v $
-% Revision 1.1 2002/02/03 20:49:03 mdw
-% Checkin for new build system.
-%
-% Revision 1.8 1996/12/09 23:20:42 mdw
-% (\tab@setstrut): Fixed so that it uses \dimen@ii for the strut depth,
-% as advertised.
-%
-% Revision 1.7 1996/11/29 21:59:16 mdw
-% Fixed a little formatting mistake in a syntax diagram, and switched over
-% to the new syntax diagram commands on the grounds that they're slightly
-% less messy. Maybe.
-%
-% Revision 1.6 1996/11/19 20:54:33 mdw
-% Entered into RCS
-%
-%
% \end{meta-comment}
%
% \begin{meta-comment} <general public licence>
% \begin{meta-comment} <Package preambles>
%<+mdwtab>\NeedsTeXFormat{LaTeX2e}
%<+mdwtab>\ProvidesPackage{mdwtab}
-%<+mdwtab> [1998/04/28 1.9 Table typesetting with style]
+%<+mdwtab> [2003/08/24 1.10 Table typesetting with style]
%<+mathenv>\NeedsTeXFormat{LaTeX2e}
%<+mathenv>\ProvidesPackage{mathenv}
-%<+mathenv> [1998/04/28 1.9 Various maths environments]
+%<+mathenv> [2003/08/24 1.10 Various maths environments]
+%<+colour>\NeedsTeXFormat{LaTeX2e}
+%<+colour>\ProvidesPackage{mtcolour}
+%<+colour> [2003/08/24 1.10 Colour support for mdwtab]
+%<+color>\NeedsTeXFormat{LaTeX2e}
+%<+color>\ProvidesPackage{mtcolor}
+%<+color> [2003/08/24 1.10 Fix for people who can't spell]
% \end{meta-comment}
%
-% \CheckSum{2876}
+% \CheckSum{3424}
%% \CharacterTable
%% {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
%% 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
%<*driver>
\input{mdwtools}
\describespackage{mdwtab}
+\describespackage{mtcolour}
\describespackage{mathenv}
\addcontents{lot}{\listoftables}
\mdwdoc
% action), and preambles like this will result in an error (and
% probably a rather confusing one).
%
+% \item David Carlisle's \package{colortbl} package entirely fails to work
+% with \package{mdwtab}. However, we now have colour support of our
+% own which is at times similar in style.
+%
% \end{itemize}
%
% There are also several incompatibilities between \package{mdwtab} and
%
% \begin{grammar}
%
-% <tabular-env> ::= \[[
+% <tabular-env> ::= \[[
% "\\begin"
% \begin{stack}
% "{tabular}" \\ "{tabular*}" "{" <length> "}" \\
%
% <position-arg> ::= (see below)
%
-% <preamble> ::= \[[
+% <preamble> ::= \[[
% <first-column>
% \[ \< <column> \> \]
% \]]
%
% <first-column> ::= \[[ \[ <rule> \] <column> \]]
%
-% <column> ::= \[[
+% <column> ::= \[[
% \[ <spacing> \] \[ \< <user-pre-text> \> \] <column-type>
% \[ \< <user-post-text> \> \] \[ <spacing> \] \[ <rule> \]
% \]]
%
-% <spacing> ::= \[[ "@" "{" <text> "}" \]]
+% <spacing> ::= \[[ "@" "{" <text> "}" \]]
%
-% <user-pre-text> ::= \[[ ">" "{" <text> "}" \]]
+% <user-pre-text> ::= \[[ \[ "?" \] ">" "{" <text> "}" \]]
%
-% <column-type> ::= \[[
+% <column-type> ::= \[[
% \begin{stack}
% \[ "T" \\ "M" \] \( "l" \\ "c" \\ "r" \) \\
% \( "p" \\ "m" \\ "b" \) "{" <length> "}" \\
% \end{stack}
% \]]
%
-% <user-post-text> ::= \[[ "<" "{" <text> "}" \]]
+% <user-post-text> ::= \[[ \[ "?" \] "<" "{" <text> "}" \]]
%
-% <rule> ::= \[[ \( "|" \\ "!" "{" <text> "}" \) \]]
+% <rule> ::= \[[ \( "|" \\ "!" "{" <text> "}" \) \]]
%
% \end{grammar}
%
% The actual column types are shown in table~\ref{tbl:columns}.
%
% \begin{table}
-% \begin{tabular}[C]{| >{\synshorts} c | m{3in} |} \hlx{hv[1]}
-%
-% \multicolumn{2}{|c|}{\bf Column types} \\ \hlx{v[1]hv}
-% \bf Name & \bf Meaning \\ \hlx{vhv.}
-% "l" & Left aligned text (\env{tabular}) or
-% equation (\env{array}). \\ \hlx{.}
-% "c" & Centred text (\env{tabular}) or
-% equation (\env{array}). \\ \hlx{.}
-% "r" & Right aligned text (\env{tabular}) or
-% equation (\env{array}). \\ \hlx{vhv.}
+% \begin{tabular}[C]{| >{\synshorts} c | m{3in} |} \hlx{hv[1]}
+%
+% \multicolumn{2}{|c|}{\bf Column types} \\ \hlx{v[1]hv}
+% \bf Name & \bf Meaning \\ \hlx{vhv.}
+% "l" & Left aligned text (\env{tabular}) or
+% equation (\env{array}). \\ \hlx{.}
+% "c" & Centred text (\env{tabular}) or
+% equation (\env{array}). \\ \hlx{.}
+% "r" & Right aligned text (\env{tabular}) or
+% equation (\env{array}). \\ \hlx{vhv.}
% "Ml", "Mc" and "Mr" & Left, centre and right aligned
-% equations.* \\ \hlx{.}
+% equations.* \\ \hlx{.}
% "Tl", "Tc" and "Tr" & Left, centre and right aligned
-% text.* \\ \hlx{vhv.}
+% text.* \\ \hlx{vhv.}
% "p{"<width>"}" & Top aligned paragraph with the given
-% width. \\ \hlx{.}
+% width. \\ \hlx{.}
% "m{"<width>"}" & Vertically centred paragraph with
-% the given width. \\ \hlx{.}
+% the given width. \\ \hlx{.}
% "b{"<width>"}" & Bottom aligned paragraph with the
-% given width. \\ \hlx{vhv.}
+% given width. \\ \hlx{vhv.}
% "#{"<pre>"}{"<post>"}" & User defined column type:
-% \<pre> is inserted before the
-% cell entry, \<post> is inserted
-% afterwards.* \\ \hlx{vhhv[1]}
-%
-% \multicolumn{2}{|c|}{\bf Other modifier characters} \\ \hlx{v[1]hv}
-% \bf Name & \bf Meaning \\ \hlx{vhv.}
-% "|" & Inserts a vertical rule between
-% columns. \\ \hlx{.}
-% "$*["<width>"]" & Inserts a vertical rule of given
+% \<pre> is inserted before the
+% cell entry, \<post> is inserted
+% afterwards.* \\ \hlx{vhhv[1]}
+%
+% \multicolumn{2}{|c|}{\bf Other modifier characters} \\ \hlx{v[1]hv}
+% \bf Name & \bf Meaning \\ \hlx{vhv.}
+% "|" & Inserts a vertical rule between
+% columns. \\ \hlx{.}
+% "$*["<params>"]" & Inserts a vertical rule of given
% width between columns; "*" selects
-% "\arraythickrulewidth". \\ \hlx{.}
-% "!{"<text>"}" & Inserts \<text> between columns,
-% treating it as a vertical rule. \\ \hlx{vhv.}
-% "@{"<text>"}" & Inserts \<text> instead of the
-% usual intercolumn space. \\ \hlx{vhv.}
-% ">{"<text>"}" & Inserts \<text> just before the
-% actual column entry. \\ \hlx{.}
-% "<{"<text>"}" & Inserts \<text> just after the
-% actual column entry. \\ \hlx{vhv.}
+% "\arraythickrulewidth".* \\ \hlx{.}
+% "!{"<text>"}" & Inserts \<text> between columns,
+% treating it as a vertical rule. \\ \hlx{vhv.}
+% "@{"<text>"}" & Inserts \<text> instead of the
+% usual intercolumn space. \\ \hlx{vhv.}
+% ">{"<text>"}" & Inserts \<text> just before the
+% actual column entry. \\ \hlx{.}
+% "<{"<text>"}" & Inserts \<text> just after the
+% actual column entry. \\ \hlx{.}
+% "?>{"<text>"}" & Inserts \<text> before the column
+% entry \emph{and} the rules list.* \\ \hlx{.}
+% "?<{"<text>"}" & Inserts \<text> after the column
+% entry \emph{and} the rules list.* \\ \hlx{.}
+% "'{"<text>"}" & Inserts \<text> into the rules list
+% only.* \\ \hlx{vhv.}
% "*{"<count>"}{"<chars>"}" & Inserts \<count>
-% copies of the \<chars> into the
-% preamble. \\ \hlx{vhs}
+% copies of the \<chars> into the
+% preamble. \\ \hlx{vhs}
%
% \multicolumn{2}{@{}l}{* This column type is a new feature}
% \end{tabular}
% concerned -- they'll work inside |\tabpause| without any problems.
%
% \DescribeMacro{\vline}
-% \DescribeMacro{\vline*}
% The |\vline| command draws a vertical rule the height of the current table
% cell (unless the current cell is being typeset in paragraph mode -- it
% only works in the simple LR-mode table cells, or in \lit{@} or \lit{!}
-% modifiers). It's now been given an optional argument which gives the
-% width of the rule to draw. The |*|-version uses the |\arraythickrulewidth|
-% thickness rather than the default.
+% modifiers). It's now been given an optional argument which describes
+% parameters for the line. See section~\ref{sec:ruleparams}.
%
% { \let\tabstyle=\relax
% \begin{demo}{An example of \cmd\vline}
% There's a nasty use of \env{smallmatrix} in the |testmath.tex| file which
% comes with the \package{amslatex} distribution. It's actually there to
% simulate a `smallcases' environment, which the \package{mathenv} package
-% includes, based around \env{smarray}.}
+% includes, based around \env{smarray}.} ^^A
% being implemented by totally unsuitable commands. Someone may find it
% handy.
%
% separated list of column numbers and ranges:
%
% \begin{grammar}
-% <cline-cmd> ::= \[[
+% <cline-cmd> ::= \[[
% "\\cline"
-% \[ "*" \\ \tok{"["<width>"]"} \]
+% \[ "*" \] \\ \[ "[" <rule-params> "]" \]
% "{" \< <number> \[ "-" <number> \] \\ "," \> "}"
% \]]
% \end{grammar}
%
-% The thickness of the rules may be modified. The default is given by the
-% |\arrayrulewidth| length parameter. The |\cline*| command uses the
-% |\arraythickrulewidth| parameter instead. If neither of these does what
-% you want, then you can give a length yourself as an optional argument.
-% This feature is also available in the |\hline| and |\hlx| commands, and
-% (for vertical rules) in the |$| column type.\footnote{I couldn't use the
-% \texttt{\char`\|} type, because that would break old documents which
-% expect \texttt{\char`\| *\char`\{...\char`\}} to work properly.}
+% The rules printed by |\cline| and |\hline| can be modified by rule
+% parameters: see section~\ref{sec:ruleparams}.
%
-% The positioning of the horizontal lines has also been improved a bit, so
-% that they meet up with the vertical lines properly. Displays like the one
-% in the example below don't look good unless this has been done properly.
+% Note that |\cline| rules are rather bodgy. Other rules now have
+% \emph{thickness}, but |\cline|s don't. Instead, they backspace over
+% previous stuff. If you don't like that, insert an appropriate gap, using
+% |\vgap|. The \lit{z} rune in |\hlx| is perfect for this kind of thing --
+% precede your \lit{c} lines by \lit{z} lines for best results.
%
% {\let\tabstyle\relax
% \begin{demo}[w]{A \cs{cline} example}
% \end{demo}
% }
%
+% \subsection{Other stuff}
+%
+% \DescribeMacro\nextrow
+% The \env{tabular} and \env{array} environments maintain a counter
+% \textsf{tabrow}. The counter is reset to zero at the start of each table.
+% It is stepped by one by default; you can provide an optional argument which
+% is the amount to add.
+%
+%
% \subsection{Spacing control}
%
% One of the most irritating things about \LaTeX's tables is that there isn't
%
% \begin{grammar}
%
-% <vgap-cmd> ::= \[[
+% <vgap-cmd> ::= \[[
% "\\vgap" \[ "[" <which-cols> "]" \] "{" <length> "}"
% \]]
%
-% <which-cols> ::= \[[ \< <number> \[ "-" <number> \] \\ "," \> \]]
+% <which-cols> ::= \[[ \< <number> \[ "-" <number> \] \\ "," \> \]]
%
% \end{grammar}
%
% The syntax is simple:
% \begin{grammar}
%
-% <hlx-cmd> ::= \[[
+% <hlx-cmd> ::= \[[
% "\\hlx"
-% \[ "*" \\ \tok{"["<width>"]"} \]
+% \[ "*" \] \[ "[" <rule-params> "]" \]
% "{"
% \begin{rep}
% \begin{stack}
% "h" \\
% \tok{"v["<which-cols>"]["<length>"]"} \\
+% \tok{"z["<which-cols>"]["<length>"]"} \\
% \tok{"s["<length>"]"} \\
% \tok{"c{"<which-cols>"}"} \\
% "b" \\
% \tok{"/["<number>"]"} \\
+% \tok{"!{"<rule-params>"}"} \\
+% \tok{"?{"<stuff>"}"} \\
+% \tok{"+["<step>"]"} \\
% "."
% \end{stack}
% \end{rep}
% \]]
%
% \end{grammar}
-% The |*| or optional \<width> specify the width of horizontal rules to be
-% drawn, as for |\hline| and |\cline|. (Note that you can't pass a |*| or
-% optional argument to the |h| or |c| subcommands.)
+% The |*| or optional \<rule-params> give rule-drawing parameters for the |h|
+% and |c| subcommands. (Note that you can't pass a |*| or an optional
+% parameters argument to the |h| or |c| subcommands directly.) See
+% section~\ref{sec:ruleparams}.
%
% The argument works a bit like a table preamble, really. Each letter is a
% command. The following are supported:
% \<length> is omitted, the value of |\doublerulesep| is used.
% This usually looks right.
%
+% \item [\lit*{z[}\<which-cols>\lit*{][}\<length>\lit*{]}] Like \lit{v},
+% except that the default gap is the current rule width (set by the
+% \<rule-params>) rather than |\doublerulesep|. This is a good thing
+% to insert before a |\cline| row.
+%
% \item [\lit*{s[}\<length>\lit*{]}] Leaves a vertical gap with the
% given size. If you omit the \<length> then |\doublerulesep| is
% used. This is usually right.
% except that the default is 0, which just permits a break without
% forcing it.
%
+% \item [\lit*{!\char`\{}\<rule-params>\lit*{\char`\}}] Change the rule
+% parameters to be used for subsequent subcommands.
+%
+% \item [\lit*{?\char`\{}\<stuff>\lit*{\char`\}}] Do \<stuff>, which can be
+% any commands which \emph{don't} typeset anything.
+%
+% \item [\lit*{+[\<step>]}] Add \<step> (default is 1) to the value of the
+% \textsf{tabrow} counter.
+%
% \item [\lit*{.}] (That's a dot) Starts the next row of the table. No
% more characters may follow the dot, and no |\hline|, |\hlx|, |\vgap|
% or |\multicolumn| commands may be used after it. You don't have to
% then you get an extra thick rule at the bottom of the page. This is a bit
% of a problem, because if the rule isn't there in the footer and you get
% a break between two rows \emph{without} a rule between them, then the page
-% looks very odd.
+% looks very odd.
%
% If you want to do ruled longtables, I'd recommend that you proceed as
% follows:
% it gets the positioning right all by itself. You've never had it so good.
%
%
+% \subsection{Rule parameters}
+% \label{sec:ruleparams}
+%
+% The rule-drawing commands |\hline|, |\vline|, |\cline| and |\hlx|, and the
+% |$| column type (which is otherwise a synonym for "|") accept \emph{rule
+% parameters}. If the command is followed by a |*|, then the rules are a bit
+% thicker than usual -- they use |\arraythickrulewidth| rather than
+% |\arrayrulewidth|. However, there's an optional argument which can contain
+% one of:
+%
+% \begin{description} \setdescriptionlabel{\ttfamily#1}
+% \item[thin] Use |\arrayrulewidth| as the line width. This is the default.
+% \item[thick] Use |\arraythickrulewidth| as the line width. This is the
+% same as giving a |*| after the command.
+% \item[width=\<length>] Make the rules exactly \<length> wide.
+% \item[\<length>] The same as \texttt{width=\<length>}, for compatibility.
+% \end{description}
+%
+% More of these keywords will be added later if past experience is anything
+% to go by. Note that the individual |\hlx| subcommands \emph{don't} take
+% rule parameters, but see the |!| subcommand for updating the current
+% parameters.
+%
+% \DescribeMacro\tabsetruleparams
+% If you say \syntax{"\\tabsetruleparams{"<rule-params>"}"} then the
+% \<rule-params> will be prepended to any parameters provided to specific
+% rule-drawing commands (including the \lit{\char`\|} preamble command). For
+% example, |\tabsetruleparams{thick}| makes all rules thick. This is a local
+% declaration.
+%
+%
% \subsection{User serviceable parts}
%
% There are a lot of parameters which you can modify in order to make arrays
% and tables look nicer. They are all listed in table~\ref{tbl:config}.
%
% \begin{table}
-% \begin{tabular}[C]{| l | m{3in} |} \hlx{hv}
-% \bf Parameter & \bf Meaning \\ \hlx{vhv}
-% |\tabstyle| & A command executed at the beginning of
-% a \env{tabular} or \env{tabular$*$}
-% environment. By default does nothing.
-% Change using |\renewcommand|. \\ \hlx{vhv}
-% |\extrarowheight| & A length added to the height of every
-% row, used to stop table rules
-% overprinting ascenders. Default 0\,pt.
-% Usage is deprecated now: use |\hlx|
-% instead. \\ \hlx{vhv}
-% |\tabextrasep| & Extra space added between rows in a
-% \env{tabular} or \env{tabular$*$}
-% environment (added \emph{before} any
-% following |\hline|). Default 0\,pt. \\
-% |\arrayextrasep| & Analogous to |\tabextrasep|, but for
-% \env{array} environments. Default
-% 1\,jot (3\,pt). \\
-% |\smarrayextrasep| & Analogous to |\tabextrasep|, but for
-% \env{smarray} environments. Default
-% 1\,pt. \\ \hlx{vhv}
-% |\tabcolsep| & Space added by default on each side of
-% a table cell (unless suppressed by an
-% \lit{@}-expression) in \env{tabular}
-% environments. Default is defined by
-% your document class. \\
-% |\arraycolsep| & Analogous to |\tabcolsep|, but for
-% \env{array} environments. Default is
-% defined by your document class. \\
-% |\smarraycolsep| & Analogous to |\tabcolsep|, but for
-% \env{smarray} environments. Default
-% is 3\,pt. \\ \hlx{vhv}
-% |\arrayrulewidth| & The width of horizontal and vertical
-% rules in tables. \\
-% |\arraythickrulewidth|& The width of starred rules in tables. \\
-% |\doublerulesep| & Space added between two adjacent
-% vertical or horizontal rules. Also
-% used by |\hlx{v}|. \\ \hlx{vhv}
-% |\arraystretch| & Command containing a factor to
-% multiply the default row height.
-% Default is defined by your document
-% class (usually 1). \\ \hlx{vh}
+% \begin{tabular}[C]{| l | m{3in} |} \hlx{hv}
+% \bf Parameter & \bf Meaning \\ \hlx{vhv}
+% |\tabstyle| & A command executed at the beginning of
+% a \env{tabular} or \env{tabular$*$}
+% environment. By default does nothing.
+% Change using |\renewcommand|. \\ \hlx{vhv}
+% |\extrarowheight| & A length added to the height of every
+% row, used to stop table rules
+% overprinting ascenders. Default 0\,pt.
+% Usage is deprecated now: use |\hlx|
+% instead. \\ \hlx{vhv}
+% |\tabextrasep| & Extra space added between rows in a
+% \env{tabular} or \env{tabular$*$}
+% environment (added \emph{before} any
+% following |\hline|). Default 0\,pt. \\
+% |\arrayextrasep| & Analogous to |\tabextrasep|, but for
+% \env{array} environments. Default
+% 1\,jot (3\,pt). \\
+% |\smarrayextrasep| & Analogous to |\tabextrasep|, but for
+% \env{smarray} environments. Default
+% 1\,pt. \\ \hlx{vhv}
+% |\tabcolsep| & Space added by default on each side of
+% a table cell (unless suppressed by an
+% \lit{@}-expression) in \env{tabular}
+% environments. Default is defined by
+% your document class. \\
+% |\arraycolsep| & Analogous to |\tabcolsep|, but for
+% \env{array} environments. Default is
+% defined by your document class. \\
+% |\smarraycolsep| & Analogous to |\tabcolsep|, but for
+% \env{smarray} environments. Default
+% is 3\,pt. \\ \hlx{vhv}
+% |\arrayrulewidth| & The width of horizontal and vertical
+% rules in tables. \\
+% |\arraythickrulewidth|& The width of starred rules in tables. \\
+% |\doublerulesep| & Space added between two adjacent
+% vertical or horizontal rules. Also
+% used by |\hlx{v}|. \\ \hlx{vhv}
+% |\arraystretch| & Command containing a factor to
+% multiply the default row height.
+% Default is defined by your document
+% class (usually 1). \\ \hlx{vh}
% \end{tabular}
%
% \caption{Parameters for configuring table environments}
% This implementation allows you to define lots of different sets of columns.
% You can change the current set using the |\colset| declaration:
% \begin{grammar}
-% <colset-cmd> ::= \[[ "\\colset" "{" <set-name> "}" \]]
+% <colset-cmd> ::= \[[ "\\colset" "{" <set-name> "}" \]]
% \end{grammar}
% This leaves a problem, though: at any particular moment, the current
% column set could be anything, since other macros and packages can change
% previous current column set.
%
% \begin{grammar}
-% <colpush-cmd> ::= \[[ "\\colpush" "{" <set-name> "}" \]]
-% <colpop-cmd> ::= \[[ "\\colpop" \]]
+% <colpush-cmd> ::= \[[ "\\colpush" "{" <set-name> "}" \]]
+% <colpop-cmd> ::= \[[ "\\colpop" \]]
% \end{grammar}
%
% The macros which manipulate the column set stack work \emph{locally}.
% something lower-level.
%
% \begin{grammar}
-% <coldef-cmd> ::= \[[
+% <coldef-cmd> ::= \[[
% "\\coldef"
% \[ "[" <set-name> "]" \]
% <col-name> <arg-template> "{" <replacement-text> "}"
% Note that if you do gobble the |\tab@mkpream|, it's your responsibility to
% insert another one at the very end of your macro's expansion (so that
% further preamble characters can be read).
-%
+%
% The replacement text is inserted directly. It's normal to insert preamble
% elements here. There are several to choose from:
%
%
% \begin{grammar}
%
-% <collet-cmd> ::= \[[
+% <collet-cmd> ::= \[[
% \[ "[" <set-name> "]" \] <col-name> \[ "=" \] \[ "[" <set-name> "]" \]
% <col-name>
% \]]
% using the |\tab@cr| command:
%
% \begin{grammar}
-% <tabcr-cmd> ::= \[[
+% <tabcr-cmd> ::= \[[
% "\\tab@cr" <command> "{" <non-star-text> "}" "{" <star-text> "}"
% \]]
% \end{grammar}
% to see how all this gets put into practice.
%
%
-% \subsection{The \env{mathenv} package alignment environments}
+% \subsection{Colour support}
+%
+% I've now added colour support to \package{mdwtab}. That is, you can play
+% with the colours of table cell backgrounds, rules and text. The support
+% isn't there by default: you have to either give the \textsf{colour} option
+% when you load \package{mdwtab}, or include the \package{mtcolour} package
+% yourself. It's very new, and might break. It's probably not as good as
+% \package{colortbl}. I prefer English spellings for the commands and
+% declarations: to reduce confusion, I've provided synonyms with fewer `u's.
+% If only American package authors were so thoughtful. The examples in this
+% part of the documentation may not display correctly in some DVI viewers:
+% for best results, run |dvips| and view the PostScript using (say)
+% GhostScript.
%
-% The \env{mathenv} package provides several environments for aligning
+% \subsubsection{New commands and features}
+%
+% \DescribeMacro\cellcolour
+% The |\cellcolour| command changes the background colour for the current
+% cell. You can use it directly in a table cell, or in the table preamble.
+% It doesn't matter whereabouts in the table cell it goes. Note that
+% unlike the \package{colortbl}, the |\cellcolour| command works on the
+% \emph{entire} contents of the cell, including the |\tabcolsep| space and
+% the rules, if any. That means that it's robust even if there are |@{...}|
+% preamble commands present.
+%
+% The actual syntax is like this:
+%
+% \begin{grammar}
+% <cell-colour-cmd> ::= \[[
+% \( "\\cellcolour" \\ "\\cellcolor" \)
+% \[ "*" \]
+% \[ "[" <colour-model> "]" \]
+% "{" <colour> "}"
+% \[ "[" <left-overhang> "]"
+% \[ "[" <right-overhang> "]" \] \]
+% \]]
+% \end{grammar}
+%
+% The \lit{*} makes |\cellcolour| override an extant |\rowcolour| command
+% (see below). The \<colour-model> and \<colour> are as for the |\color|
+% command. The \<left-overhang> is how much the colour band should stick out
+% to the left of the cell; and similarly for the \<right-overhang>. If you
+% don't give a \<right-overhang> then the same value is used for both; if you
+% give neither then there's no overhang. The reason you might want overhang
+% is to deal with |\extracolsep| glue. I shouldn't worry about it if I were
+% you.
+%
+% It's very useful to use |\cellcolour| in a preamble, in particular, in the
+% |?>| preamble command (which was added specifically). (If you use only |>|
+% then |\vgap| leaves very odd-looking gaps in the table.)
+%
+% { \let\tabstyle=\relax
+% \begin{demo}{A coloured table}
+%\newcolumntype{\c}[2]{%
+% >{\color{#1}}%
+% ?>{\cellcolour{#2}}%
+%}
+%\begin{tabular}
+% {|\c{cyan}{red}c|
+% \c{magenta}{green}c|
+% \c{yellow}{blue}c|}
+% \hlx{hv}
+% One &Two &Three \\ \hlx{vhv}
+% Four &Five &Six \\ \hlx{vhv}
+% Seven&Eight&Nine \\ \hlx{vh}
+%\end{tabular}
+% \end{demo}
+% }
+%
+% Obviously, judicious use of |\newcolumntype| would abbreviate the above
+% considerably.
+%
+% \DescribeMacro\rowcolour
+% \DescribeMacro\rowcolouroff
+% The |\rowcolour| command changes the background colour in the same way as
+% |\cellcolour|; however, its effect takes precedence over |\cellcolour| (but
+% not |\cellcolour*|) if both are active, and isn't automatically turned off
+% at the start of the next cell. To actually turn it off again, say
+% |\rowcolouroff|.
+%
+% \begin{grammar}
+% <row-colour-cmd> ::= \[[
+% \( "\\rowcolour" \\ "\\rowcolor" \)
+% \[ "[" <colour-model> "]" \]
+% "{" <colour> "}"
+% \]]
+% \end{grammar}
+%
+% Note that you don't get to specify overhang parameters here. The ones from
+% the |\cellcolour| declaration are used, unless there isn't one in which
+% case there aren't any.
+%
+% \DescribeMacro\ifmod
+% A common thing to do is colour alternate rows of the table differently.
+% This is a bit tricker for \package{mdwtab} than it would be for, say,
+% \package{array}, since it's hard to spot where the `rows' actually change.
+% The solution is to use the \textsf{tabrow} counter, and |\ifmod|. Saying
+% say \syntax{"\\ifmod{"$x$"}{"$m$"}{"$y$"}{"<yes>"}{"<no>"}"} is the same as
+% saying \<yes> if $x \bmod m = y$, and \<no> otherwise. This is typically
+% used as follows.
+%
+% % { \let\tabstyle=\relax
+% \begin{demo}{Alternating row colours}
+%\begin{tabular}
+% {|?>{\ifmod
+% {\value{tabrow}}{2}{1}
+% {\rowcolour{white}}
+% {\rowcolour[gray]{0.9}}}
+% c|c|}
+% \hlx{h+v}
+% One & Two \\ \hlx{vh+v}
+% Three & Four \\ \hlx{vh+v}
+% Five & Six \\ \hlx{vh+v}
+% Seven & Eight \\ \hlx{vh+v}
+% Nine & Ten \\ \hlx{vh+}
+%\end{tabular}
+% \end{demo}
+% }
+%
+% There are new rule parameters for colours. You get a colourful rule if you
+% say \syntax{"colour" "=" <colour>}. You can also say \syntax{"colourmodel"
+% "=" <colour-model>} to choose unnamed colours.
+%
+% When I've thought of what other things need doing, I'll do some of them.
+% The kit I've provided \emph{can} do most interesting things, but it might
+% require a certain level of hacking. Ask me if you want something and it's
+% not obvious how to do it.
+%
+% \subsubsection{Dirty tricks}
+%
+% The colour support interacts with |\vgap| very badly. The preamble rune
+% |?>{\cellcolour{...}}| works well if you want to colour a column, and
+% |\rowcolour| works either in the preamble or as
+% |\hlx{?{\rowcolour{...}}}|. But what if you want to just colour one table
+% cell? You can, as suggested above, just say |\cellcolour{...}| in the
+% table text, but that leaves really nasty-looking gaps above and below if
+% there are adjacent |\vgap| rows.
+%
+% This is what |\hlx{?{...}}| was invented for. Here's a demo.
+%
+% \begin{demo}[w]{Colouring just one cell}
+%\let\hack=\relax
+%\begin{tabular}[C]{|c|?>{\hack}c|} \hlx{hv}
+%Uncoloured & cells here \\ \hlx{vhv}
+%And some & more \\
+% \hlx{vh?{\gdef\hack{\cellcolour{red}}}v}
+%Yet more & This one's red! \\
+% \hlx{vh?{\global\let\hack=\relax}v}
+%And more & uncoloured cells \\ \hlx{vh}
+%\end{tabular}
+% \end{demo}
+%
+%
+% \subsection{The \package{mathenv} package alignment environments}
+%
+% The \package{mathenv} package provides several environments for aligning
% equations in various ways. They're mainly provided as a demonstration of
% the table handling macros in \package{mdwtab}, so don't expect great
% things. If you want truly beautiful mathematics, use
% \[ "[" \< <eqa-column> \> "]" \]
% \]]
%
-% <eqa-column> ::= \[[
+% <eqa-column> ::= \[[
% \[ "q" \\ ":" \]
% \[ \< ">" "{" <pre-text> "}" \> \]
% \begin{stack}
% table~\ref{tbl:eqnarray}.
%
% \begin{table}
-% \begin{tabular}[C]{| >{\synshorts} c | m{3in} |} \hlx{hv[1]}
-%
-% \multicolumn{2}{|c|}{\bf Column types} \\ \hlx{v[1]hv}
-% \bf Name & \bf Meaning \\ \hlx{vhv.}
-% "l" & Left aligned piece of equation. \\ \hlx{.}
-% "c" & Centred piece of equation. \\ \hlx{.}
-% "x" & Centred or flush-left whole equation
-% (depending on \textsf{fleqn} option). \\ \hlx{.}
-% "r" & Right aligned piece of equation. \\ \hlx{vhv.}
-% "L" & Left aligned piece of equation whose
-% width is considered to be 2\,em. \\ \hlx{vhv.}
+% \begin{tabular}[C]{| >{\synshorts} c | m{3in} |} \hlx{hv[1]}
+%
+% \multicolumn{2}{|c|}{\bf Column types} \\ \hlx{v[1]hv}
+% \bf Name & \bf Meaning \\ \hlx{vhv.}
+% "l" & Left aligned piece of equation. \\ \hlx{.}
+% "c" & Centred piece of equation. \\ \hlx{.}
+% "x" & Centred or flush-left whole equation
+% (depending on \textsf{fleqn} option). \\ \hlx{.}
+% "r" & Right aligned piece of equation. \\ \hlx{vhv.}
+% "L" & Left aligned piece of equation whose
+% width is considered to be 2\,em. \\ \hlx{vhv.}
% "Tl", "Tc" and "Tr" & Left, centre and right aligned
-% text. \\ \hlx{vhhv[1]}
-%
-% \multicolumn{2}{|c|}{\bf Other modifier characters} \\ \hlx{v[1]hv}
-% \bf Name & \bf Meaning \\ \hlx{vhv.}
-% ":" & Leaves a big gap between equations.
-% By default, the `chunks' separated by
-% \lit{:}s are equally spaced on the
-% line. \\ \hlx{.}
-% "q" & Inserts 1\,em of space \\ \hlx{vhv.}
-% ">{"<text>"}" & Inserts \<text> just before the
-% actual column entry. \\ \hlx{.}
-% "<{"<text>"}" & Inserts \<text> just after the
-% actual column entry. \\ \hlx{vhv.}
+% text. \\ \hlx{vhhv[1]}
+%
+% \multicolumn{2}{|c|}{\bf Other modifier characters} \\ \hlx{v[1]hv}
+% \bf Name & \bf Meaning \\ \hlx{vhv.}
+% ":" & Leaves a big gap between equations.
+% By default, the `chunks' separated by
+% \lit{:}s are equally spaced on the
+% line. \\ \hlx{.}
+% "q" & Inserts 1\,em of space \\ \hlx{vhv.}
+% ">{"<text>"}" & Inserts \<text> just before the
+% actual column entry. \\ \hlx{.}
+% "<{"<text>"}" & Inserts \<text> just after the
+% actual column entry. \\ \hlx{vhv.}
% "*{"<count>"}{"<chars>"}" & Inserts \<count>
-% copies of the \<chars> into the
-% preamble. \\ \hlx{vh}
+% copies of the \<chars> into the
+% preamble. \\ \hlx{vh}
% \end{tabular}
%
% \caption{\package{eqnarray} column types and modifiers}
%
% \begin{demo}[w]{Lots of equations}
%\begin{eqnarray}[rl:rl:lq]
-% V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
+% V_i &= v_i - q_i v_j, & X_i &= x_i - q_i x_j, &
% U_i = u_i, \qquad \mbox{for $i \ne j$} \\
% V_j &= v_j, & X_j &= x_j &
% U_j u_j + \sum_{i \ne j} q_i u_i. \label{eq:A}
% \begin{demo}{Splitting example}
%\begin{eqnarray*}[Ll]
% w+x+y+z = \\
-% & a+b+c+d+e+ \\
+% & a+b+c+d+e+{} \\
% & f+g+h+i+j
%\end{eqnarray*}
% \end{demo}
% you like them. These are all shown in table~\ref{tbl:eqnparms}.
%
% \begin{table}
-% \begin{tabular}[C]{| l | p{3in} |} \hlx{hv}
-% \bf Parameter & \bf Use \\ \hlx{vhv}
-% |\eqaopenskip| & Length put on the left of an
-% \env{eqnarray} environment. By
-% default, this is |\@centering| (to
-% centre the alignment) or |\mathindent|
-% (to left align) depending on whether
-% you're using the \textsf{fleqn}
-% document class option. \\
-% |\eqacloseskip| & Length put on the right of an
-% \env{eqnarray} environment. By
-% default, this is |\@centering|, to
-% align the environment correctly. \\ \hlx{vhv}
-% |\eqacolskip| & Space added by the \lit{:} column
-% modifier. This should be a rubber
-% length, although it only stretches in
-% \env{eqnarray}, not in \env{eqnalign}.
-% The default value is 1\smallf1/2\,em
-% with 1000\,pt of stretch. \\
-% |\eqainskip| & Space added at each side of a normal
-% column. By default this is 0\,pt. \\ \hlx{vhv}
-% |\eqastyle| & The maths style used in the alignment.
-% By default, this is |\textstyle|,
-% and you probably won't want to change
-% it. \\ \hlx{vh}
+% \begin{tabular}[C]{| l | p{3in} |} \hlx{hv}
+% \bf Parameter & \bf Use \\ \hlx{vhv}
+% |\eqaopenskip| & Length put on the left of an
+% \env{eqnarray} environment. By
+% default, this is |\@centering| (to
+% centre the alignment) or |\mathindent|
+% (to left align) depending on whether
+% you're using the \textsf{fleqn}
+% document class option. \\
+% |\eqacloseskip| & Length put on the right of an
+% \env{eqnarray} environment. By
+% default, this is |\@centering|, to
+% align the environment correctly. \\ \hlx{vhv}
+% |\eqacolskip| & Space added by the \lit{:} column
+% modifier. This should be a rubber
+% length, although it only stretches in
+% \env{eqnarray}, not in \env{eqnalign}.
+% The default value is 1\smallf1/2\,em
+% with 1000\,pt of stretch. \\
+% |\eqainskip| & Space added at each side of a normal
+% column. By default this is 0\,pt. \\ \hlx{vhv}
+% |\eqastyle| & The maths style used in the alignment.
+% By default, this is |\textstyle|,
+% and you probably won't want to change
+% it. \\ \hlx{vh}
% \end{tabular}
%
% \caption{Parameters for the \env{eqnarray} and \env{eqnalign} environments}
%
% \begin{grammar}
%
-% <matrix-env> ::= \[[ <begin-matrix> <contents> <end-matrix> \]]
+% <matrix-env> ::= \[[ <begin-matrix> <contents> <end-matrix> \]]
%
% <begin-matrix> ::= \[[ "\\begin{matrix}" \[ "[" <matrix-cols> "]" \] \]]
%
-% <matrix-cols> ::= \[[
+% <matrix-cols> ::= \[[
% \< \[ "[" \] \[ "T" \] \( "l" \\ "c" \\ "r" \) \>
% \]]
%
-% <end-matrix> ::= \[[ "\\end{stack}" \]]
+% <end-matrix> ::= \[[ "\\end{stack}" \]]
%
% \end{grammar}
%
% variable.
% \item [\cs{tab@columns}] contains the number of the current column.
% \item [\cs{tab@hlstate}] contains the state required for hline management.
+% \item [\textsf{tabrow}] contains the row number in the table. It's a
+% proper \LaTeX\ counter.
% \end{description}
%
% \begin{macrocode}
\newcount\tab@state
\newcount\tab@columns
+\newcounter{tabrow}
% \end{macrocode}
%
% We need \emph{lots} of token registers. Fortunately, most of them are only
\newif\iftab@initrule
\newif\iftab@rule
\newif\iftab@vgap
+\newif\iftab@colour
% \end{macrocode}
%
% Now assign some default values to new dimen parameters. These definitions
% \end{macrocode}
%
%
+% \subsection{Options processing}
+%
+% Notice options, load package.
+%
+% \begin{macrocode}
+\DeclareOption{colour}{\tab@colourtrue}
+\DeclareOption{color}{\tab@colourtrue}
+\ProcessOptions
+\RequirePackage{mdwkey}
+% \end{macrocode}
+%
% \subsection{Some little details}
%
% \begin{macro}{\@maybe@unskip}
%
%
% \subsection{Parser states}
-%
+%
% Now we start on the parser. It's really simple, deep down. We progress
% from state to state, extracting tokens from the preamble and building
% command names from them. Each command calls one of the element-building
% routines, which works out which state it should be in. We go through each
% of the states in between (see later) doing default things for the ones we
% missed out.
-%
+%
% Anyway, here's some symbolic names for the states. It makes my life
% easier.
%
\fi%
% \end{macrocode}
%
+% Now dump in the |\tab@lefttext| material.
+%
+% \begin{macrocode}
+ \expandafter\tab@append\expandafter\tab@preamble%
+ \expandafter{\tab@lefttext}%
+% \end{macrocode}
+%
% Now we spill the token registers into the main list in a funny order (which
% is why we're doing it in this strange way in the first place.
%
\the\expandafter\tab@pretext%
\the\expandafter\tab@userpretext%
\the\expandafter\toks@%
- \the\tab@posttext%
+ \the\expandafter\tab@posttext%
+ \tab@righttext%
}%
% \end{macrocode}
%
% {\bf while} $\it tab\_state \ne s$ {\bf do} \\
% \qq $\mathit{tab\_state = tab\_state}+1$; \\
% \qq {\bf if} $\it tab\_state = tab\_limitState$ {\bf then}
-% $\it tab\_state=tab\_loopState$; \\
+% $\it tab\_state=tab\_loopState$; \\
% \qq {\bf if} $\it tab\_state = tab\_preSpcState$ {\bf then} \\
% \qq \qq {\bf if} $\it tab\_initRule$ {\bf then} \\
% \qq \qq \qq $\it tab\_initRule = {\bf false}$; \\
% \qq \qq {\bf end\,if}; \\
% \qq {\bf end\,if}; \\
% \qq {\bf if} $\it tab\_state \ne s$ {\bf then}
-% $\it do\_default(tab\_state)$; \\
+% $\it do\_default(tab\_state)$; \\
% {\bf end\,while};
% \end{quote}
%
\else%
\tab@looped%
\tab@commit%
+ \expandafter\tab@append\expandafter\tab@shortline%
+ \expandafter{\tab@rightruletext}%
\tab@append\tab@shortline{&\omit}%
+ \expandafter\tab@append\expandafter\tab@shortline%
+ \expandafter{\tab@leftruletext}%
\fi%
\fi%
% \end{macrocode}
% \begin{macro}{\tab@initread}
%
% This macro sets up lots of variables to their normal states prior to
-% parsing a preamble. Some things may need changing, but not many.
+% parsing a preamble. Some things may need changing, but not many. This
+% version just sets the major hooks, and then does a subread. The midtext
+% macro contains what to put in the very middle of each template --
+% |\multicolumn| will insert its argument here.
%
% \begin{macrocode}
\def\tab@initread{%
+ \def\tab@lefttext{}%
+ \def\tab@leftruletext{}%
+ \def\tab@righttext{}%
+ \def\tab@rightruletext{}%
+ \def\tab@tabtext{&}%
+ \def\tab@midtext{\ignorespaces####\@maybe@unskip}%
+ \tab@initsubread%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tab@initsubread}
+%
+% This is where most of the activity is. We don't replace the left and right
+% texts, so that we effectively inherit them rfrom the enclosing
+% environment.
+%
+% \begin{macrocode}
+\def\tab@initsubread{%
% \end{macrocode}
%
% First, reset the parser state to the start state.
\global\tab@state\tab@startstate%
% \end{macrocode}
%
-% We clear the token lists to sensible values, mostly. The midtext macro
-% contains what to put in the very middle of each template -- |\multicolumn|
-% will insert its argument here.
+% We clear the token lists to sensible values, mostly.
%
% \begin{macrocode}
\tab@preamble{}%
\tab@shortline{}%
- \def\tab@tabtext{&}%
- \def\tab@midtext{\ignorespaces####\@maybe@unskip}%
\tab@pretext{}%
\tab@userpretext{}%
\tab@posttext{}%
\tab@initruletrue%
\tab@firstcoltrue%
}
+
% \end{macrocode}
%
% \end{macro}
%
% \begin{macrocode}
\def\tab@readpreamble#1{%
+ \expandafter\tab@append\expandafter\tab@shortline%
+ \expandafter{\tab@leftruletext}%
\tab@doreadpream{#1}%
\iftab@initrule\global\tab@state\tab@prespcstate\fi%
\tab@setstate\tab@rulestate%
+ \expandafter\tab@append\expandafter\tab@shortline%
+ \expandafter{\tab@rightruletext}%
\tab@commit%
}
% \end{macrocode}
% to make everything work right, but it's simple really.
%
% \begin{macrocode}
-\def\coldef{\@ifnextchar[\coldef@i{\coldef@i[\tab@colset]}}
+\def\coldef{\@testopt\coldef@i\tab@colset}
\def\coldef@i[#1]#2#3#{\coldef@ii[#1]{#2}{#3}}
\def\coldef@ii[#1]#2#3#4{%
\expandafter\def\csname#1!col.\string#2\endcsname#3{%
% to do it.
%
% \begin{macrocode}
-\def\collet{\@ifnextchar[\collet@i{\collet@i[\tab@colset]}}
+\def\collet{\@testopt\collet@i\tab@colset}
\def\collet@i[#1]#2{%
\@ifnextchar=%
{\collet@ii[#1]{#2}}%
{\collet@ii[#1]{#2}=}%
}
-\def\collet@ii[#1]#2={%
- \@ifnextchar[%
- {\collet@iii[#1]{#2}}%
- {\collet@iii[#1]{#2}[\tab@colset]}%
-}
+\def\collet@ii[#1]#2={\@testopt{\collet@iii[#1]{#2}}\tab@colset}
\def\collet@iii[#1]#2[#3]#4{%
\expandafter\let\csname#1!col.\string#2\expandafter\endcsname%
\csname#3!col.\string#4\endcsname%
% that \package{array} works.
%
% \begin{macrocode}
-\def\newcolumntype#1{\@ifnextchar[{\nct@i{#1}}{\nct@i#1[0]}}
+\def\newcolumntype#1{\@testopt{\nct@i{#1}}0}
\def\nct@i#1[#2]{\@ifnextchar[{\nct@ii{#1}[#2]}{\nct@iii{#1}{[#2]}}}
\def\nct@ii#1[#2][#3]{\nct@iii{#1}{[#2][#3]}}
\def\nct@iii#1#2#3{%
% First, make sure we're setting up the right columns. This also sets the
% default for the user. Other packages must not use the |\colset| command
% for defining columns -- they should use the stack operations defined above.
+% For colour support, we ensure that the total stretch in a table cell is
+% 1\,fil.
+%
+% \begin{macrocode}
+\def\tab@halfhfil{\hskip\z@\@plus.5fil\relax}
+% \end{macrocode}
+%
+% And now on with the show.
%
% \begin{macrocode}
\colset{tabular}
%
% \begin{macrocode}
\coldef l{\tabcoltype{\kern\z@\tab@bgroup}{\tab@egroup\hfil}}
-\coldef c{\tabcoltype{\hfil\tab@bgroup}{\tab@egroup\hfil}}
+\coldef c{\tabcoltype{\tab@halfhfil\tab@bgroup}{\tab@egroup\tab@halfhfil}}
\coldef r{\tabcoltype{\hfil\tab@bgroup}{\tab@egroup}}
% \end{macrocode}
%
\coldef M#1{\tab@aligncol{#1}{\tab@bmaths}{\tab@emaths}}
\def\tab@aligncol#1#2#3{%
\if#1l\tabcoltype{\kern\z@#2}{#3\hfil}\fi%
- \if#1c\tabcoltype{\hfil#2}{#3\hfil}\fi%
+ \if#1c\tabcoltype{\tab@halfhfil#2}{#3\tab@halfhfil}\fi%
\if#1r\tabcoltype{\hfil#2}{#3}\fi%
}
% \end{macrocode}
% Now for the default rules.
%
% \begin{macrocode}
-\coldef ${\expandafter\tab@rulewd\expandafter\tab@vrule\@gobble}
-\def\tab@vrule{%
- \expandafter\tabruletype\expandafter{%
- \expandafter\vrule\expandafter\@width\the\tab@rulewidth%
- }%
- \tab@mkpreamble%
-}
-\coldef |{\tabruletype{\vrule\@width\arrayrulewidth}}
+\coldef ${\@firstoftwo{\tab@withrp\tab@vrule}}
+\coldef |{\@firstoftwo{\tab@withrp\tab@vrule[]}}
+\def\tab@vrule#1{\tabruletype{#1\vrule\@width\dimen@}\tab@mkpreamble}
\coldef !#1{\tabruletype{#1}}
% \end{macrocode}
%
% \begin{macrocode}
\coldef >#1{\tabuserpretype{#1}}
\coldef <#1{\tabuserposttype{#1}}
+\coldef ?#1#2{%
+ \ifx>#1\expandafter\tabuserpretype%
+ \else\expandafter\tabuserposttype\fi%
+ {#2}%
+ \tab@append\tab@shortline{#2}%
+}
+\coldef '#1{%
+ \tab@append\tab@shortline{#1}%
+}
% \end{macrocode}
%
% The strange column type.
\coldef ##1#2{\tabcoltype{#1}{#2}}
% \end{macrocode}
%
-% And \lit{*}, which repeats a preamble spec. This is really easy, and not
-% at all like the original one.
+% And \lit{*}, which repeats a preamble spec. The tricky part is ensuring
+% that nested \lit{*} specs work correctly: we must save the loop counter, in
+% |\count 0|, obviously, but \emph{also} the |\iterate| macro built which
+% |\loop| modifies internally. Usually you'd use grouping to fix this, but
+% if we introduce a group level then we won't update the preamble registers
+% correctly. Instead, queue up tokens to restore the values in \TeX's input
+% list.
%
% \begin{macrocode}
\coldef *#1#2{%
- \count@#1%
- \loop\ifnum\count@>0\relax%
- \tab@doreadpream{#2}%
- \advance\count@\m@ne%
- \repeat%
+ \toks\tw@\expandafter{\iterate}%
+ \toks@{%
+ \count@#1%
+ \loop\ifnum\count@>0\relax%
+ \tab@doreadpream{#2}%
+ \advance\count@\m@ne%
+ \repeat%
+ }%
+ \edef\@tempa{%
+ \the\toks@%
+ \def\noexpand\iterate{\the\toks\tw@}%
+ \count@\the\count@%
+ }%
+ \@tempa%
}
% \end{macrocode}
%
% appropriate depth. Since this will lie on the previous baseline, it won't
% alter the effective height of the box. There's a snag here. |\prevdepth|
% may be wrong for example if the last thing inserted was a rule, or the
-% box is just empty. Check for this specially. (Thanks to Rowland for
-% spotting this.)
+% box is just empty. Check for this specially. (Thanks to Rowland McDonnell
+% for spotting this.)
%
% \begin{macrocode}
\ifdim\prevdepth>-\@m\p@\ifdim\prevdepth<\dp\@arstrutbox%
\tab@initread%
\def\tab@multicol{\@arstrut}%
\tab@preamble{\tab@multicol}%
- \def\tab@midtext{\ignorespaces\@sharp\@sharp\@maybe@unskip}%
+ \let\tab@lefttext\tab@lefttexthook%
+ \let\tab@righttext\tab@righttexthook%
+ \let\tab@leftruletext\tab@leftruletexthook%
+ \let\tab@rightruletext\tab@rightruletexthook%
+ \def\tab@midtext{\tab@setcr\ignorespaces\@sharp\@sharp\@maybe@unskip}%
\tab@readpreamble{#1}%
\gdef\@preamble{\the\tab@preamble}%
\let\tab@bgroup\begingroup%
}
% \end{macrocode}
%
-%
% \subsection{Debugging}
%
% This macro just parses a preamble and displays it on the terminal. It
%
% \begin{macrocode}
\def\tab@btext{\begingroup}
-\def\tab@bmaths{$}
+\def\tab@bmaths{\color@begingroup$}
\def\tab@etext{\endgroup}
-\def\tab@emaths{\m@th$}
+\def\tab@emaths{\m@th$\color@endgroup}
% \end{macrocode}
%
% \end{macro}
\crcr%
\egroup%
\tab@right%
+ \endgroup%
\tab@restorehlstate%
+ \global\c@tabrow\count@%
+ \def\@currentlabel{\p@tabrow\thetabrow}%
+ \tab@endhook%
}
% \end{macrocode}
%
\extrarowheight\z@%
\col@sep\smarraycolsep%
\let\tab@extrasep\smarrayextrasep%
- \def\tab@bmaths{$\scriptstyle}%
+ \def\tab@bmaths{\color@begingroup$\scriptstyle}%
\def\tab@btext{\begingroup\scriptsize}%
\setbox\z@\hbox{\scriptsize\strut}%
\dimen@\ht\z@\dimen@ii\dp\z@\tab@setstrut%
% The following bits are mainly for other packages to hook themselves onto.
%
% \begin{macrocode}
-\let\@arrayleft\relax%
-\let\@arrayright\relax%
+\let\@arrayleft\relax
+\let\@arrayright\relax
+\let\tab@beginhook\@empty
+\let\tab@lefttexthook\@empty
+\let\tab@righttexthook\@empty
+\let\tab@leftruletexthook\@empty
+\let\tab@rightruletexthook\@empty
+\let\tab@endhook\@empty
% \end{macrocode}
%
+% For setting these hooks, we provide some handy commands.
+%
+% \begin{macrocode}
+\def\tab@addhookbefore#1#2{%
+ \toks@{#2}\toks@\expandafter{\the\expandafter\toks@#1}%
+ \edef#1{\the\toks@}%
+}
+\def\tab@addhookafter#1#2{%
+ \toks@\expandafter{#1#2}%
+ \edef#1{\the\toks@}%
+}
+% \end{macrocode}
+%
+% And now we get on with the real thing.
+%
% \begin{macrocode}
\def\@tabarray{%
\let\@arrayleft\relax%
\let\@arrayright\relax%
- \@ifnextchar[\@array{\@array[c]}%
+ \@testopt\@array c%
}
% \end{macrocode}
%
% control sequence to avoid wasting any more count registers.
%
% \begin{macrocode}
+ \tab@beginhook%
+ \count@\c@tabrow%
+ \global\c@tabrow\z@%
\edef\tab@restorehlstate{%
\global\tab@endheight\the\tab@endheight%
\gdef\noexpand\tab@hlstate{\tab@hlstate}%
}%
+ \begingroup%
\def\tab@hlstate{n}%
% \end{macrocode}
%
% \begin{macrocode}
\colset{tabular}%
\tab@initread%
+ \let\tab@lefttext\tab@lefttexthook%
+ \let\tab@righttext\tab@righttexthook%
+ \let\tab@leftruletext\tab@leftruletexthook%
+ \let\tab@rightruletext\tab@rightruletexthook%
\def\tab@midtext{\tab@setcr\ignorespaces####\@maybe@unskip}%
\def\tab@multicol{\@arstrut\tab@startrow}%
\tab@preamble{\tab@multicol\tabskip\z@skip}%
\everypar{}%
\lineskip\normallineskip%
\let\\\@normalcr%
+ \color@begingroup%
\tab@startpause%
\vskip-\parskip%
\parshape\@ne\@totalleftmargin\linewidth%
\def\tabpause@i{%
\nobreak%
\tab@endpause%
+ \color@endgroup%
\ifnum0=`{\fi}%
}
% \end{macrocode}
\multispan{#1}%
\begingroup%
\tab@multicol%
- \tab@initread%
- \tab@preamble{}%
+ \tab@initsubread%
\long\def\tab@midtext{#3}%
\let\tab@looped\tab@err@multi%
\tab@readpreamble{#2}%
% This is where all the gubbins for |\vgap| and friends is kept, lest it
% contaminate fairly clean bits of code found elsewhere.
%
-% \subsubsection{Common parsing for vertical rule width twiddling}
+% \subsubsection{Common parsing for rule parameters twiddling}
+%
+% \begin{macro}{\tab@ruleparams}
%
-% \begin{macro}{\tab@rulewd}
+% Given a macro name, make a (global) macro |\tab@ruledecls|, which sets
+% |\dimen0| to be the chosen rule thickness, and sets up colours and whatnot,
+% and then and calls the macro. We parse a `|*|' to mean
+% |\arraythickrulewidth|, an optional argument which should be something
+% |\setlength| can understand, or nothing, which gives the default
+% |\arrayrulewidth|.
%
-% Given a macro name, set |\tab@rulewidth| to be the chosen rule thickness
-% and call the macro. We parse a `|*|' to mean |\arraythickrulewidth|, an
-% optional argument which should be something |\setlength| can understand, or
-% nothing, which gives the default |\arrayrulewidth|.
+% To make this properly hookable, we need to make a list of properties and
+% gather them together.
%
% \begin{macrocode}
-\def\tab@rulewd#1{%
- {\ifnum0=`}\fi\@ifstar{\tab@rulewd@star{#1}}{\tab@rulewd@what{#1}}%
+\let\tab@rp@inithook\@empty
+\let\tab@rp@sethook\@empty
+\let\tab@rp@donehook\@empty
+\let\tab@rp@default\@empty
+\def\tab@ruleparams#1{%
+ {\ifnum0=`}\fi%
+ \tab@rp@inithook%
+ \def\tab@rp@next{\ifnum0=`{\fi}#1}%
+ \expandafter\tab@rp@keys\expandafter{\tab@rp@default}%
+ \@ifstar\tab@rp@star\tab@rp@what%
}
-\def\tab@rulewd@what#1{%
- \@ifnextchar[{\tab@rulewd@opt{#1}}{\tab@rulewd@done\arrayrulewidth#1}%
+\def\tab@rp@star{\dimen@\arraythickrulewidth\tab@rp@what}
+\def\tab@rp@what{\@ifnextchar[\tab@rp@opt\tab@rp@done}
+\def\tab@rp@opt[#1]{\tab@rp@keys{#1}\tab@rp@done}
+\def\tab@rp@keys{\mkparse{mdwtab:rule}}
+\def\tab@rp@done{%
+ \protected@xdef\tab@rp@{\tab@rp@sethook}%
+ \tab@rp@donehook%
+ \tab@rp@next%
}
-\def\tab@rulewd@star#1{\tab@rulewd@done\arraythickrulewidth#1}
-\def\tab@rulewd@opt#1[#2]{\setlength\dimen@{#2}\tab@rulewd@done\dimen@#1}
-\def\tab@rulewd@done#1{\global\tab@rulewidth#1\ifnum0=`{\fi}}
+\def\tab@withrp#1{\tab@ruleparams{\tab@withrp@i{#1}}}
+\def\tab@withrp@i#1{%
+ \toks@{#1}%
+ \toks@\expandafter{\the\expandafter\toks@\expandafter{\tab@rp@}}%
+ \the\toks@%
+}
+% \end{macrocode}
+%
+% And now to define the width parameters.
+%
+% \begin{macrocode}
+\tab@addhookafter\tab@rp@inithook{\dimen@\arrayrulewidth}
+\tab@addhookafter\tab@rp@sethook{\dimen@\the\dimen@}
+\tab@addhookafter\tab@rp@donehook{\global\tab@rulewidth\dimen@}
+\mkdef{mdwtab:rule}{width}{\setlength\dimen@{#1}}
+\mkdef{mdwtab:rule}{thin}*{\dimen@\arrayrulewidth}
+\mkdef{mdwtab:rule}{thick}*{\dimen@\arraythickrulewidth}
+\mkdef*{mdwtab:rule}*{\setlength\dimen@{#1}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tabsetruleparams}
+%
+% And the user default-parameter list.
+%
+% \begin{macrocode}
+\def\tabsetruleparams{\def\tab@rp@default}
% \end{macrocode}
%
% \end{macro}
% vertical space.
%
% \begin{macrocode}
-\def\hline{\noalign\tab@rulewd\hline@prep}
+\def\hline{\noalign\tab@ruleparams\hline@prep}
\def\hline@prep{%
\tab@dohline%
\noalign{\ifnum0=`}\fi%
%
% \begin{macro}{\tab@dohline}
%
-% This is where hlines actually get drawn.
+% This is where hlines actually get drawn.
% Drawing lines is more awkward than it used to be, particularly in unboxed
% tables. It used to be a case simply of saying |\noalign{\hrule}|.
% However, since unboxed tables are actually much wider than they look, this
%
% \begin{macrocode}
\def\tab@dohline{%
- \multispan{\tab@columns}%
- \leaders\hrule\@height\tab@rulewidth\hfil%
- \tab@addruleheight\arrayrulewidth%
+ \multispan\tab@columns%
+ \color@begingroup%
+ \tab@rp@\leaders\hrule\@height\dimen@\hfil%
+ \tab@addruleheight\dimen@%
+ \color@endgroup%
\cr%
}
% \end{macrocode}
%
% \begin{macro}{\vline}
%
-% Now uses the general |\tab@rulewd| parser.
+% Now uses the general |\tab@ruleparams| parser. We save and restore the
+% global |\tab@rulewidth| parameter here.
%
% \begin{macrocode}
\def\vline{%
\begingroup%
- \dimen@\tab@rulewidth%
- \tab@rulewd{%
- \vrule\@width\tab@rulewidth%
- \global\tab@rulewidth\dimen@%
- \endgroup%
- }%
+ \@tempdima\tab@rulewidth\let\safe@\tab@rp@%
+ \tab@ruleparams\tab@vline%
+}
+\def\tab@vline{%
+ \tab@rp@\vrule\@width\dimen@%
+ \global\tab@rulewidth\@tempdima\global\let\tab@rp@\safe@%
+ \endgroup%
}
% \end{macrocode}
%
% Not a single line of code written yet, and we already have a dilemma on
% our hands. Multiple consecutive |\cline| commands are meant to draw
% on the same vertical bit of table. But horizontal lines are meant to have
-% thickness now. Oh, well [sigh], we'll skip back on it after all.
+% thickness now. Worse, if the lines have real thickness then we leave gaps
+% in the vertical rules which aren't covered by our line. But if we
+% backspace over the line, then we overwrite it with coloured blobs.
+%
+% We give up on doing the job properly -- that's just doomed. Backspace over
+% the previous row, and provide a hack for doing the spacing right elsewhere.
%
% Now the problem remains how best to do the job. The way I see it, there
% are three possibilities:
% |\tab@state|.
%
% \begin{macrocode}
-\def\cline{\noalign\tab@rulewd\cline@prep}
-\def\cline@prep#1{%
- \noalign{\kern-.5\tab@rulewidth\tab@penalty}%
- \omit%
- \global\tab@state\@ne%
- \ranges\cline@i{#1}%
- \cr%
- \noalign{\kern-.5\tab@rulewidth\tab@penalty}%
-}
+\def\cline{\noalign\tab@ruleparams\cline@do}
% \end{macrocode}
%
% Now for the tricky bit. When we're given a range, we look to see if the
% first number is less than |\tab@state|. If so, we quickly close the
% current row, kern backwards and start again with an |\omit| and reset
-% |\tab@state| to 1, and try again.
+% |\tab@state| to 1, and try again. This is hardly perfect, but gets the job
+% done in many cases. Correct |\vgap| insertion fixes the remaining bugs.
%
% \begin{macrocode}
-\def\cline@i#1#2{%
+\def\cline@do#1{%
+ \noalign{\kern-\tab@rulewidth}%
+ \omit%
+ \global\tab@state\@ne%
+ \ranges\cline@do@i{#1}\cr%
+}
+\def\cline@do@i#1#2{%
\ifnum#1<\tab@state\relax%
\tab@@cr%
\noalign{\kern-\tab@rulewidth\tab@penalty}%
% \end{macrocode}
%
% We are now either at or in front of the column position required. If
-% we're too far back, we must |\hfil&\omit| our way over to the correct%
+% we're too far back, we must |\hfil&\omit| our way over to the correct
% column.
%
% \begin{macrocode}
% we start putting in |\hfil| glue when we step onto the next cell.
%
% \begin{macrocode}
+ \color@begingroup%
+ \tab@rp@%
\leaders\hrule\@height\tab@rulewidth\hfill%
+ \color@endgroup%
}
% \end{macrocode}
%
% Computer Programming} use the little `stub lines' to show where
% data items cross byte boundaries:
%
-% ^^A This actually looks terrifyingly similar to the original.
-% ^^A The leading @{} is there to stop the table looking off-centre,
-% ^^A because there's no left hand rule telling you where the table
-% ^^A starts, like there is on the right, just the \tabcolsep glue.
+% ^^A This actually looks terrifyingly similar to the original.
+% ^^A The leading @{} is there to stop the table looking off-centre,
+% ^^A because there's no left hand rule telling you where the table
+% ^^A starts, like there is on the right, just the \tabcolsep glue.
%
-% \begingroup
-% \newcommand{\wide}[2]{\multicolumn{#1}{c|}{\ttfamily #2}}
-% \begin{tabular}[C]{@{} r @{\qquad} | Mc | *{5}{c|}} \hlx{c{2-7} v}
-% empty & - & 1 & 0 & 0 & 0 & 0 \\ \hlx{v c{2-7} v}
-% occupied & + & \wide{2}{LINK} & \wide{3}{KEY} \\ \hlx{v c{2-7}}
-% \end{tabular}
-% \endgroup
+% \begingroup
+% \newcommand{\wide}[2]{\multicolumn{#1}{c|}{\ttfamily #2}}
+% \begin{tabular}[C]{@{} r @{\qquad} | Mc | *{5}{c|}} \hlx{c{2-7} v}
+% empty & - & 1 & 0 & 0 & 0 & 0 \\ \hlx{v c{2-7} v}
+% occupied & + & \wide{2}{LINK} & \wide{3}{KEY} \\ \hlx{v c{2-7}}
+% \end{tabular}
+% \endgroup
%
% \end{itemize}
%
% First, pass the string to another routine.
%
% \begin{macrocode}
-\def\hlx{\noalign\tab@rulewd\hlx@prep}
+\def\hlx{\noalign\tab@ruleparams\hlx@prep}
\def\hlx@prep#1{\hlx@loop#1\q@delim}
% \end{macrocode}
%
% \begin{macrocode}
\hlxdef h#1{%
\noalign{%
- \ifx#1h%
- \def\@tempa{\hline@prep\hline@prep\hlx@loop}%
- \else%
- \def\@tempa{\hline@prep\hlx@loop#1}%
- \fi%
- \expandafter
+ \ifx#1h\def\@tempa{\hline@prep\hline@prep\hlx@loop}%
+ \else\def\@tempa{\hline@prep\hlx@loop#1}%
+ \fi\expandafter
}%
\@tempa%
}
% The `"/"' character allows a page break at the current position.
%
% \begin{macrocode}
-\hlxdef /{%
- \noalign{\ifnum0=`}\fi%
- \@ifnextchar[\hlx@cmd@break@i{\hlx@cmd@break@i[0]}%
-}
-\def\hlx@cmd@break@i[#1]{\ifnum0=`{\fi}\pagebreak[0]\hlx@loop}
+\hlxdef /{\noalign{\ifnum0=`}\fi\@testopt\hlx@cmd@break@i0}
+\def\hlx@cmd@break@i[#1]{\ifnum0=`{\fi}\pagebreak[#1]\hlx@loop}
% \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\hlx v}
+% \begin{macro}{\hlx z}
%
-% Handle a \lit{v} character. This is rather like the |\vgap| code above,
-% although there are syntactic differences.
+% Handle a \lit{v} or \lit{z} character. This is rather like the |\vgap|
+% code above, although there are syntactic differences.
%
% \begin{macrocode}
-\hlxdef v{%
+\hlxdef v{\hlx@vgap\doublerulesep}
+\hlxdef z{\hlx@vgap\tab@rulewidth}
+\def\hlx@vgap#1{%
\noalign{\nobreak}%
\omit%
\iffalse{\fi\ifnum0=`}\fi%
\global\let\vgap@after\hlx@loop%
- \@ifnextchar[\hlx@vgap@i{\hlx@vgap@ii\vgap@simple}%
+ \@ifnextchar[{\hlx@vgap@i{#1}}{\hlx@vgap@ii\vgap@simple{#1}}%
}
-\def\hlx@vgap@i[#1]{%
- \ifx!#1!%
- \def\@tempa{\hlx@vgap@ii\vgap@simple}%
- \else%
- \def\@tempa{\hlx@vgap@ii{\vgap@spec{#1}}}%
- \fi%
+\def\hlx@vgap@i#1[#2]{%
+ \ifx!#2!\def\@tempa{\hlx@vgap@ii\vgap@simple{#1}}%
+ \else\def\@tempa{\hlx@vgap@ii{\vgap@spec{#2}}{#1}}\fi%
\@tempa%
}
-\def\hlx@vgap@ii#1{%
- \@ifnextchar[{\hlx@vgap@iii{#1}}{\hlx@vgap@iii{#1}[\doublerulesep]}%
-}
+\def\hlx@vgap@ii#1#2{\@testopt{\hlx@vgap@iii{#1}}{#2}}
\def\hlx@vgap@iii#1[#2]{#1{#2}}
% \end{macrocode}
%
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\hlx s}
%
\hlxdef s{%
\noalign{\ifnum0=`}\fi%
\nobreak%
- \@ifnextchar[\hlx@space@i{\hlx@space@i[\doublerulesep]}%
+ \@testopt\hlx@space@i\doublerulesep%
}
\def\hlx@space@i[#1]{%
\vskip#1%
%
% \begin{macro}{\hlx c}
%
-% We might as well allow a \lit{c} command to do a |\cline|.
+% We might as well allow a \lit{c} command to do a |\cline|. The fix to
+% |\cline| permeates here.
%
% \begin{macrocode}
-\hlxdef c#1{\cline@prep{#1}\hlx@loop}
+\hlxdef c#1{\cline@do{#1}\hlx@loop}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\hlx ?}
+%
+% Do some arbitrary stuff which won't typeset. Put the stuff in a box which
+% is discarded, just in case.
+%
+% \begin{macrocode}
+\hlxdef ?#1{%
+ \noalign{\setbox\z@\hbox{\color@begingroup#1\color@endgroup}}\hlx@loop%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\hlx !}
+%
+% Change parameters in mid-flow.
+%
+% \begin{macrocode}
+\hlxdef !#1{\noalign\tab@ruleparams\hlx@loop[{#1}]}
% \end{macrocode}
%
% \end{macro}
%
% \end{macro}
%
+% \begin{macro}{\hlx +}
+% \begin{macro}{\nextrow}
+%
+% The \lit{+} subcommand just steps the table-row counter.
+%
+% \begin{macrocode}
+\hlxdef +{\nextrow\hlx@loop}
+\def\nextrow{\noalign{\ifnum0=`}\fi\@testopt\nextrow@i\@ne}
+\def\nextrow@i[#1]{\global\advance\c@tabrow#1\ifnum0=`{\fi}}
+% \end{macrocode}
+%
+% \end{macro}
+% \end{macro}
+%
%
% \subsection{Starting new table rows}
%
\iffalse{\fi\ifnum0=`}\fi%
\@ifstar{\tab@cr@i{#1}{#3}}{\tab@cr@i{#1}{#2}}%
}
-\def\tab@cr@i#1#2{%
- \@ifnextchar[{\tab@cr@ii{#1}{#2}}{\tab@cr@ii{#1}{#2}[\z@]}%
-}
-\def\tab@cr@ii#1#2[#3]{%
- \ifnum0=`{}\fi%
- #1{#3}{#2}%
-}
+\def\tab@cr@i#1#2{\@testopt{\tab@cr@ii{#1}{#2}}\z@}
+\def\tab@cr@ii#1#2[#3]{\ifnum0=`{}\fi#1{#3}{#2}}
% \end{macrocode}
%
% \end{macro}
}
% \end{macrocode}
%
+%
+% \subsection{Loading the colour package}
+%
+% If requested, we load the \package{mtcolour} package here. This ensures
+% that it can patch this code if it needs to.
+%
+% \begin{macrocode}
+\iftab@colour
+ \RequirePackage{mtcolour}
+\fi
+% \end{macrocode}
+%
% That's it. No more. Move along please.
%
% \begin{macrocode}
%
%
%^^A-------------------------------------------------------------------------
+% \section{Implementation of \package{mtcolour}}
+%
+%
+% This is in a separate package to avoid dragging in the \package{color}
+% package if it's unwanted.
+%
+% I prefer English spellings. Here's a trivial redirection for Americans.
+%
+% \begin{macrocode}
+%<*color>
+\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{mtcolour}}
+\ProcessOptions
+\RequirePackage{mtcolour}
+%</color>
+% \end{macrocode}
+%
+% And now we can start the thing properly.
+%
+% \begin{macrocode}
+%<*colour>
+\RequirePackage{color}
+% \end{macrocode}
+%
+%
+% \subsection{Cell background colours}
+%
+% First, some simple preliminaries. The |\iftab@colour| switch is set if the
+% current cell is meant to have a colour.
+%
+% \begin{macrocode}
+\newif\iftab@colour
+\tab@colourfalse
+% \end{macrocode}
+%
+% We shall store the cell colour information in |\tab@cellcolour|, and the
+% row colour information as |\tab@rowcolour|. Because of the structure of
+% tables, we need to make global assignments; so we must copy the current
+% value away at the start of a table and put the value back at the end. In
+% order to transfer the overhang information reliably, we use a separate
+% control sequence |\tab@colouroverhangs| for that -- otherwise |\color| can
+% corrupt it.
+%
+% \begin{macrocode}
+\tab@addhookbefore\tab@beginhook{%
+ \let\tab@saverowcolour\tab@rowcolour%
+ \let\tab@savecolouroverhangs\tab@colouroverhangs%
+ \let\tab@savecellcolour\tab@cellcolour%
+}
+\tab@addhookafter\tab@endhook{%
+ \global\let\tab@rowcolour\tab@saverowcolour%
+ \global\let\tab@colouroverhangs\tab@savecolouroverhangs%
+ \global\let\tab@cellcolour\tab@savecellcolour%
+}
+% \end{macrocode}
+%
+% Initially, there are no colours.
+%
+% \begin{macrocode}
+\let\tab@rowcolour\@empty%
+\let\tab@cellcolour\@empty%
+\let\tab@colouroverhangs\@empty%
+% \end{macrocode}
+%
+% \begin{macro}{\@snarfcolour}
+%
+% Reading a colour specification is something we'll need to do a few times,
+% so an abstraction is useful. Its single argument is a continuation to
+% which we pass a colour-spec acceptable to the |\color| command. (This is
+% the same code as found in the \package{sverb} package. Remember to keep
+% them in step.)
+%
+% \begin{macrocode}
+\def\@snarfcolour#1{%
+ \@ifnextchar[{\@snarfcolour@i{#1}}{\@snarfcolour@ii{#1}{}}%
+}
+\def\@snarfcolour@i#1[#2]{\@snarfcolour@ii{#1}{[#2]}}
+\def\@snarfcolour@ii#1#2#3{#1{#2{#3}}}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\cellcolour}
+%
+% Setting a cell colour is a matter of stashing the right declarations in
+% |\tab@cellcolour| and |\tab@colouroverhangs|. Note that the overhangs end
+% up in |\dimen0| and |\dimen2|.
+%
+% \begin{macrocode}
+\def\cellcolour{%
+ \@ifstar{\tab@ccol@i{\let\tab@rowcolour\@empty}}{\tab@ccol@i{}}%
+}
+\def\tab@ccol@i#1{\@snarfcolour{\tab@ccol@ii{#1}}}
+\def\tab@ccol@ii#1#2{\@testopt{\tab@ccol@iii{#2#1}}\z@}
+\def\tab@ccol@iii#1[#2]{\@testopt{\tab@ccol@iv{#1}{#2}}{#2}}
+\def\tab@ccol@iv#1#2[#3]{%
+ \gdef\tab@cellcolour{\color#1\tab@colourtrue}%
+ \gdef\tab@colouroverhangs{%
+ \setlength\dimen@{#2}%
+ \setlength{\dimen\tw@}{#3}%
+ }%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\rowcolour}
+%
+% Setting the global row colour is simpler, because we don't mess with
+% overhangs.
+%
+% \begin{macrocode}
+\def\rowcolour{\@snarfcolour\tab@setrowcolour}
+\let\rowcolor\rowcolour
+\def\tab@setrowcolour#1{%
+ \gdef\tab@rowcolour{\color#1\tab@colourtrue}%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\rowcolouroff}
+%
+% And turning the global colouring off is easy.
+%
+% \begin{macrocode}
+\def\rowcolouroff{\global\let\tab@rowcolour\@empty}
+\let\rowcoloroff\rowcolouroff
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tab@colourleft}
+%
+% Now we start on the table-cell hooks. The left hook starts a box which
+% will capture the cell's text and natural width. We add the hook to the
+% rule list as well, so that we can colour the bits in |\vgap|s correctly.
+%
+% \begin{macrocode}
+\tab@addhookbefore\tab@lefttexthook\tab@colourleft
+\tab@addhookbefore\tab@leftruletexthook\tab@colourleft
+\def\tab@colourleft{%
+ \global\let\tab@cellcolour\@empty%
+ \global\let\tab@colouroverhangs\@empty%
+ \setbox\z@\hbox\bgroup\color@begingroup%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% \begin{macro}{\tab@colourright}
+%
+% The right hook will insert an appropriate rule behind the cell and
+% retypeset the cell contents over the top. Note that the stretch in a table
+% cell is exactly 1\,fil. Because we add (leaders) and subtract (negative
+% |\hskip|) 1\,fil, we retain this stretch exactly. Don't bother unless
+% there's actually some colouring.
+%
+% \begin{macrocode}
+\tab@addhookafter\tab@righttexthook\tab@colourright
+\tab@addhookafter\tab@rightruletexthook\tab@colourright
+\def\tab@colourright{%
+ \color@endgroup\egroup%
+ \color@begingroup%
+ \global\tab@colourfalse%
+ \tab@cellcolour\tab@rowcolour%
+ \dimen@\z@\dimen\tw@\z@\tab@colouroverhangs%
+ \iftab@colour%
+ \skip@\wd\z@\advance\skip@\z@\@plus1fil%
+ \skip\tw@\skip@%
+ \kern-\dimen@%
+ \advance\skip\tw@\dimen@%
+ \advance\skip\tw@\dimen\tw@%
+ \leaders\vrule\hskip\skip\tw@%
+ \kern-\dimen\tw@%
+ \hskip-\skip@%
+ \fi%
+ \color@endgroup%
+ \unhbox\z@%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \subsection{Coloured rules}
+%
+% We hook ourselves onto the rule-parameters edifice. This is rather
+% straightforward.
+%
+% \begin{macrocode}
+\tab@addhookafter\tab@rp@inithook{%
+ \let\tab@rulecolour\@empty%
+ \let\tab@rulecolourmodel\@empty%
+}
+\mkdef{mdwtab:rule}{colour}{\tab@setrulecolour{#1}}
+\mkdef{mdwtab:rule}{colourmodel}{\tab@setrulecolourmodel{#1}}
+\mkdef{mdwtab:rule}{color}{\tab@setrulecolour{#1}}
+\mkdef{mdwtab:rule}{colormodel}{\tab@setrulecolourmodel{#1}}
+\mkdef{mdwtab:rule}{nocolour}*{\let\tab@rulecolour\@empty}
+\mkdef{mdwtab:rule}{nocolor}*{\let\tab@rulecolour\@empty}
+\mkdef{mdwtab:rule}{nocolourmodel}*{\let\tab@rulecolourmodel\@empty}
+\mkdef{mdwtab:rule}{nocolormodel}*{\let\tab@rulecolourmodel\@empty}
+\def\tab@setrulecolour#1{%
+ \def\tab@rulecolour{\color\tab@rulecolourmodel{#1}}%
+}
+\def\tab@setrulecolourmodel#1{\def\tab@rulecolourmodel{[#1]}}
+\tab@addhookafter\tab@rp@sethook{\tab@rulecolour}
+% \end{macrocode}
+%
+%
+% \subsection{Other stuff}
+%
+% \begin{macro}{\ifmod}
+%
+% \syntax{"\\ifmod{"$x$"}{"$m$"}{"$y$"}{"<yes>"}{"<no>"}"} -- if $x \bmod m =
+% y$ then do \<yes>; otherwise do \<no>.
+%
+% \begin{macrocode}
+\def\ifmod#1#2#3{%
+ \begingroup%
+ \@tempcnta#1%
+ \@tempcntb#2%
+ \count@\@tempcnta%
+ \divide\count@\@tempcntb%
+ \multiply\count@\@tempcntb%
+ \advance\@tempcnta-\count@%
+ \count@#3\relax%
+ \ifnum\@tempcnta=\count@\endgroup\expandafter\@firstoftwo%
+ \else\endgroup\expandafter\@secondoftwo\fi%
+}
+% \end{macrocode}
+%
+% \end{macro}
+%
+% Done.
+%
+% \begin{macrocode}
+%</colour>
+% \end{macrocode}
+%
+%^^A-------------------------------------------------------------------------
% \section{Implementation of \package{mathenv}}
%
%
\if@fleqn%
\eqaopenskip\mathindent%
\splitleft\mathindent\relax%
- \splitright\mathindent\@minus\mathindent\relax%
+ \splitright\mathindent\@minus\mathindent\relax%
\else%
\eqaopenskip\@centering%
\splitleft2.5em\@minus2.5em%
\eqnarray@i\eqa@eqcount%
}
\@namedef{eqnarray*}{\eqnarray@i{}}
-\def\eqnarray@i#1{\@ifnextchar[{\eqnarray@ii{#1}}{\eqnarray@ii{#1}[rcl]}}
+\def\eqnarray@i#1{\@testopt{\eqnarray@ii{#1}}{rcl}}
% \end{macrocode}
%
% Right. Now for the real work. The first argument is the default numbering
% \end{environment}
% \end{environment}
%
-% Now we can define the column types.
+% Now we can define the column types.
%
% \begin{macrocode}
\colpush{eqnarray}
% The macro |\eqa@eqpos| will put its argument in the right place.
%
% \begin{macrocode}
-\if@leqno
- \def\eqa@eqpos#1{%
+\def\eqa@eqpos#1{%
+ \if@leqno%
\hb@xt@.01\p@{}\rlap{\normalfont\normalcolor\hskip-\displaywidth#1}%
- }
-\else
- \def\eqa@eqpos#1{\normalfont\normalcolor#1}
-\fi
+ \else%
+ \normalfont\normalcolor#1%
+ \fi%
+}
% \end{macrocode}
%
% \end{macro}
% First, sort out some simple things like optional arguments.
%
% \begin{macrocode}
-\def\eqnalign{\@ifnextchar[\eqnalign@i{\eqnalign@i[rcl]}}
-\def\eqnalign@i[#1]{%
- \@ifnextchar[{\eqnalign@ii{#1}}{\eqnalign@ii{#1}[c]}%
-}
+\def\eqnalign{\@testopt\eqnalign@i{rcl}}
+\def\eqnalign@i[#1]{\@testopt{\eqnalign@ii{#1}}c}
% \end{macrocode}
%
% Now we actually do the environment. This is fairly easy, actually.
\dsp@end%
\global\let\eqa@number\eqa@oldnumber%
\global\advance\c@equation\m@ne%
+ \global\@ignoretrue%
}
\expandafter\let\csname endspliteqn*\endcsname\endspliteqn
% \end{macrocode}
% we need to remove them by hand at the extremities of the environment.
%
% \begin{macrocode}
-\def\subsplit{%
+\def\subsplit{\@ifnextchar[\subsplit@i{\subsplit@i[c]}}
+\def\subsplit@i[#1]{%
+ \let\@tempa\vcenter%
+ \if#1t\let\@tempa\vtop\fi%
+ \if#1b\let\@tempa\vbox\fi%
\let\\\seq@cr%
- \vcenter\bgroup%
+ \@tempa\bgroup%
\seq@dosplit{\hfil\qquad$##$\qquad\hfil}{\hfilneg\hskip-2em}%
}
% \end{macrocode}
% columns.
%
% \begin{macrocode}
- \@ifnextchar[\genmatrix@i{\genmatrix@i[[c]}%
+ \@testopt\genmatrix@i{[c}%
}
% \end{macrocode}
%
\def\mat@right{\egroup}%
\let\mat@font\scriptfont%
\let\mat@textsize\scriptsize%
- \@ifnextchar[\genmatrix@i{\genmatrix@i[c]}%
+ \@testopt\genmatrix@i c%
}
\let\endscript\endgenmatrix
% \end{macrocode}