From 7abe48b330ad6415f41b6b0e119645d578d0ebbe Mon Sep 17 00:00:00 2001 From: mdw Date: Fri, 5 Sep 2003 16:15:03 +0000 Subject: [PATCH] Colour support! Better rule attribute handling. Lots of new hooks. --- mdwtab.dtx | 938 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 792 insertions(+), 146 deletions(-) diff --git a/mdwtab.dtx b/mdwtab.dtx index 86afbdc..1da6f98 100644 --- a/mdwtab.dtx +++ b/mdwtab.dtx @@ -1,6 +1,6 @@ % \begin{meta-comment} % -% $Id: mdwtab.dtx,v 1.1 2002/02/03 20:49:03 mdw Exp $ +% $Id: mdwtab.dtx,v 1.2 2003/09/05 16:15:03 mdw Exp $ % % Another rewrite of the tabular environment, and maths alignments % @@ -9,6 +9,9 @@ %----- Revision history ----------------------------------------------------- % % $Log: mdwtab.dtx,v $ +% Revision 1.2 2003/09/05 16:15:03 mdw +% Colour support! Better rule attribute handling. Lots of new hooks. +% % Revision 1.1 2002/02/03 20:49:03 mdw % Checkin for new build system. % @@ -51,13 +54,19 @@ % \begin{meta-comment} %<+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{3371} %% \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 @@ -80,6 +89,7 @@ %<*driver> \input{mdwtools} \describespackage{mdwtab} +\describespackage{mtcolour} \describespackage{mathenv} \addcontents{lot}{\listoftables} \mdwdoc @@ -234,6 +244,10 @@ % 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 @@ -306,7 +320,7 @@ % % ::= \[[ "@" "{" "}" \]] % -% ::= \[[ ">" "{" "}" \]] +% ::= \[[ \[ "?" \] ">" "{" "}" \]] % % ::= \[[ % \begin{stack} @@ -316,7 +330,7 @@ % \end{stack} % \]] % -% ::= \[[ "<" "{" "}" \]] +% ::= \[[ \[ "?" \] "<" "{" "}" \]] % % ::= \[[ \( "|" \\ "!" "{" "}" \) \]] % @@ -364,9 +378,9 @@ % \bf Name & \bf Meaning \\ \hlx{vhv.} % "|" & Inserts a vertical rule between % columns. \\ \hlx{.} -% "$*[""]" & Inserts a vertical rule of given +% "$*[""]" & Inserts a vertical rule of given % width between columns; "*" selects -% "\arraythickrulewidth". \\ \hlx{.} +% "\arraythickrulewidth".* \\ \hlx{.} % "!{""}" & Inserts \ between columns, % treating it as a vertical rule. \\ \hlx{vhv.} % "@{""}" & Inserts \ instead of the @@ -374,7 +388,11 @@ % ">{""}" & Inserts \ just before the % actual column entry. \\ \hlx{.} % "<{""}" & Inserts \ just after the -% actual column entry. \\ \hlx{vhv.} +% actual column entry. \\ \hlx{.} +% "?<{""}" & Inserts \ before the column +% entry \emph{and} the rules list.* \\ \hlx{.} +% "?>{""}" & Inserts \ after the column +% entry \emph{and} the rules list.* \\ \hlx{vhv.} % "*{""}{""}" & Inserts \ % copies of the \ into the % preamble. \\ \hlx{vhs} @@ -408,13 +426,11 @@ % 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} @@ -438,7 +454,7 @@ % 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. % @@ -454,23 +470,19 @@ % \begin{grammar} % ::= \[[ % "\\cline" -% \[ "*" \\ \tok{"[""]"} \] +% \[ "*" \] \\ \[ "[" "]" \] % "{" \< \[ "-" \] \\ "," \> "}" % \]] % \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} @@ -482,6 +494,15 @@ % \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 @@ -530,16 +551,20 @@ % % ::= \[[ % "\\hlx" -% \[ "*" \\ \tok{"[""]"} \] +% \[ "*" \] \[ "[" "]" \] % "{" % \begin{rep} % \begin{stack} % "h" \\ % \tok{"v[""][""]"} \\ +% \tok{"z[""][""]"} \\ % \tok{"s[""]"} \\ % \tok{"c{""}"} \\ % "b" \\ % \tok{"/[""]"} \\ +% \tok{"!{""}"} \\ +% \tok{"?{""}"} \\ +% \tok{"+[""]"} \\ % "." % \end{stack} % \end{rep} @@ -547,9 +572,10 @@ % \]] % % \end{grammar} -% The |*| or optional \ 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 \ 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: @@ -564,6 +590,11 @@ % \ is omitted, the value of |\doublerulesep| is used. % This usually looks right. % +% \item [\lit*{z[}\\lit*{][}\\lit*{]}] Like \lit{v}, +% except that the default gap is the current rule width (set by the +% \) rather than |\doublerulesep|. This is a good thing +% to insert before a |\cline| row. +% % \item [\lit*{s[}\\lit*{]}] Leaves a vertical gap with the % given size. If you omit the \ then |\doublerulesep| is % used. This is usually right. @@ -580,6 +611,15 @@ % except that the default is 0, which just permits a break without % forcing it. % +% \item [\lit*{!\char`\{}\\lit*{\char`\}}] Change the rule +% parameters to be used for subsequent subcommands. +% +% \item [\lit*{?\char`\{}\\lit*{\char`\}}] Do \, which can be +% any commands which \emph{don't} typeset anything. +% +% \item [\lit*{+[\]}] Add \ (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 @@ -685,6 +725,38 @@ % 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} +% \renewcommand\makelabel[1]{\kern\labelsep\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=\] Make the rules exactly \ wide. +% \item[\] The same as \texttt{width=\}, 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{""}"} then the +% \ 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 @@ -999,6 +1071,159 @@ % to see how all this gets put into practice. % % +% \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. +% +% \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} +% ::= \[[ +% \( "\\cellcolour" \\ "\\cellcolor" \) +% \[ "*" \] +% \[ "[" "]" \] +% "{" "}" +% \[ "[" "]" +% \[ "[" "]" \] \] +% \]] +% \end{grammar} +% +% The \lit{*} makes |\cellcolour| override an extant |\rowcolour| command +% (see below). The \ and \ are as for the |\color| +% command. The \ is how much the colour band should stick out +% to the left of the cell; and similarly for the \. If you +% don't give a \ 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} +% ::= \[[ +% \( "\\rowcolour" \\ "\\rowcolor" \) +% \[ "[" "]" \] +% "{" "}" +% \]] +% \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$"}{""}{""}"} is the same as +% saying \ if $x \bmod m = y$, and \ 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" "=" }. You can also say \syntax{"colourmodel" +% "=" } 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 \env{mathenv} package alignment environments} % % The \env{mathenv} package provides several environments for aligning @@ -1138,7 +1363,7 @@ % \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} @@ -1609,11 +1834,14 @@ % 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 @@ -1660,6 +1888,7 @@ \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 @@ -1682,6 +1911,17 @@ % \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} @@ -1784,6 +2024,13 @@ \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. % @@ -1794,7 +2041,8 @@ \the\expandafter\tab@pretext% \the\expandafter\tab@userpretext% \the\expandafter\toks@% - \the\tab@posttext% + \the\expandafter\tab@posttext% + \tab@righttext% }% % \end{macrocode} % @@ -1877,7 +2125,11 @@ \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} @@ -2145,10 +2397,33 @@ % \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. @@ -2157,15 +2432,11 @@ \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{}% @@ -2184,6 +2455,7 @@ \tab@initruletrue% \tab@firstcoltrue% } + % \end{macrocode} % % \end{macro} @@ -2196,9 +2468,13 @@ % % \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} @@ -2305,7 +2581,7 @@ % 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{% @@ -2322,17 +2598,13 @@ % 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% @@ -2352,7 +2624,7 @@ % 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{% @@ -2388,6 +2660,14 @@ % 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} @@ -2401,7 +2681,7 @@ % % \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} % @@ -2415,7 +2695,7 @@ \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} @@ -2423,14 +2703,9 @@ % 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} % @@ -2459,6 +2734,12 @@ % \begin{macrocode} \coldef >#1{\tabuserpretype{#1}} \coldef <#1{\tabuserposttype{#1}} +\coldef ?#1#2{% + \ifx>#1\expandafter\tabuserpretype% + \else\expandafter\tabusrposttype\fi% + {#2}% + \tab@append\tab@shortline{#2}% +} % \end{macrocode} % % The strange column type. @@ -2538,8 +2819,8 @@ % 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% @@ -2605,7 +2886,6 @@ } % \end{macrocode} % -% % \subsection{Debugging} % % This macro just parses a preamble and displays it on the terminal. It @@ -2664,9 +2944,9 @@ % % \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} @@ -2691,7 +2971,11 @@ \crcr% \egroup% \tab@right% + \endgroup% \tab@restorehlstate% + \global\c@tabrow\count@% + \def\@currentlabel{\p@tabrow\thetabrow}% + \tab@endhook% } % \end{macrocode} % @@ -2707,7 +2991,7 @@ \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% @@ -2812,15 +3096,36 @@ % 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} % @@ -2839,10 +3144,14 @@ % 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} % @@ -2855,6 +3164,10 @@ % \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}% @@ -3191,6 +3504,7 @@ \everypar{}% \lineskip\normallineskip% \let\\\@normalcr% + \color@begingroup% \tab@startpause% \vskip-\parskip% \parshape\@ne\@totalleftmargin\linewidth% @@ -3200,6 +3514,7 @@ \def\tabpause@i{% \nobreak% \tab@endpause% + \color@endgroup% \ifnum0=`{\fi}% } % \end{macrocode} @@ -3223,8 +3538,7 @@ \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}% @@ -3385,25 +3699,69 @@ % 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} @@ -3418,7 +3776,7 @@ % 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% @@ -3458,9 +3816,11 @@ % % \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} @@ -3477,17 +3837,19 @@ % % \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} % @@ -3503,7 +3865,12 @@ % 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: @@ -3538,24 +3905,23 @@ % |\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}% @@ -3565,7 +3931,7 @@ % \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} @@ -3602,7 +3968,10 @@ % 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} % @@ -3772,7 +4141,7 @@ % 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} % @@ -3815,12 +4184,9 @@ % \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% } @@ -3844,43 +4210,39 @@ % 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} % @@ -3890,7 +4252,7 @@ \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% @@ -3904,10 +4266,34 @@ % % \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} @@ -3937,6 +4323,20 @@ % % \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} % @@ -4042,13 +4442,8 @@ \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} @@ -4181,6 +4576,18 @@ } % \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} @@ -4189,6 +4596,247 @@ % % %^^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} +% +% \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"}{""}{""}"} -- if $x \bmod m = +% y$ then do \; otherwise do \. +% +% \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} +% +% \end{macrocode} +% +%^^A------------------------------------------------------------------------- % \section{Implementation of \package{mathenv}} % % @@ -4392,7 +5040,7 @@ \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 @@ -4716,10 +5364,8 @@ % 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. @@ -5167,7 +5813,7 @@ % columns. % % \begin{macrocode} - \@ifnextchar[\genmatrix@i{\genmatrix@i[[c]}% + \@testopt\genmatrix@i{[c}% } % \end{macrocode} % @@ -5331,7 +5977,7 @@ \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} -- 2.11.0