mdwtab.dtx: Fix nested `*' column-type to work correctly.
[mdwtools] / mdwtab.dtx
index b972848..03e7866 100644 (file)
@@ -44,7 +44,7 @@
 %<+color>                [2003/08/24 1.10 Fix for people who can't spell]
 % \end{meta-comment}
 %
-% \CheckSum{3402}
+% \CheckSum{3421}
 %% \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
 %                 actual column entry.                  \\ \hlx{.}
 % "<{"<text>"}" & Inserts \<text> just after the
 %                 actual column entry.                  \\ \hlx{.}
-% "?<{"<text>"}" & Inserts \<text> before the column
+% "?>{"<text>"}" & Inserts \<text> before the column
 %                 entry \emph{and} the rules list.*     \\ \hlx{.}
-% "?>{"<text>"}" & Inserts \<text> after the column
+% "?<{"<text>"}" & Inserts \<text> after the column
 %                 entry \emph{and} the rules list.*     \\ \hlx{vhv.}
 % "*{"<count>"}{"<chars>"}" & Inserts \<count>
 %                 copies of the \<chars> into the
 % |\arrayrulewidth|.  However, there's an optional argument which can contain
 % one of:
 %
-% \begin{description}
-% \renewcommand\makelabel[1]{\kern\labelsep\ttfamily#1}
+% \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.
 \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}
 %
   \extrarowheight\z@%
   \col@sep\smarraycolsep%
   \let\tab@extrasep\smarrayextrasep%
-  \def\tab@bmaths{$\color@begingroup\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%
 %
 % \begin{macro}{\ifmod}
 %
-% \syntax{"\\ifmod{"$x$"}{"$m$"}{"y"}{"<yes>"}{"<no>"}"} -- if $x \bmod m =
+% \syntax{"\\ifmod{"$x$"}{"$m$"}{"$y$"}{"<yes>"}{"<no>"}"} -- if $x \bmod m =
 % y$ then do \<yes>; otherwise do \<no>.
 %
 %    \begin{macrocode}