5

In the following scheme, why do I have to hide & in a macro (\samp) before it works?

\documentclass{article}
\usepackage{catoptions}
\makeatletter
\cptnewcounts{rowcnt,colcnt,maxrow,maxcol}
\def\docols{%
  \global\advance\colcnt\@ne
  \the\numexpr\rowcnt*\colcnt\relax
  \ifnum\colcnt=\maxcol\stopcol\fi
  \samp\docols
}
\def\stopcol#1\docols{\fi}
\def\samp{&}
\def\dorows{%
  \global\advance\rowcnt\@ne
  \global\colcnt\z@
  \docols
  \ifnum\rowcnt=\maxrow\stoprow\fi
  \scr\dorows
}
\def\stoprow#1\dorows{\fi\crcr}
\def\scr{\cr}
\makeatother

\begin{document}
\maxrow4 \maxcol3
$$\vbox{\halign{&\ \hfil#\hfil\strut\cr\dorows}}$$
\end{document}
7

The \dorows expansion is performed all in one swoop, generating the table body, and only then TeX will start to expand it looking for & and \cr tokens, if you hide them in macros. Otherwise TeX will see & and stop the column, inserting the u and v part, typesetting it and storing it away. So the dreaded \endtemplate token will find its way in the argument of \stopcol.

If instead you put & and \cr into macros, these won't be expanded until \dorows has finished its work and the table will be safely built.

Notice that \cr is not outer: the problem is exactly the same as with \stopcol, but with \stoprow.

You can see this by changing your input as follows:

\documentclass{article}
\usepackage{catoptions}
\makeatletter
\cptnewcounts{rowcnt,colcnt,maxrow,maxcol}
\newtoks\ahmed
\def\docols{%
  \global\advance\colcnt\@ne
  \global\ahmed=\expandafter{\the\expandafter\ahmed\the\numexpr\rowcnt*\colcnt\relax}%
  \ifnum\colcnt=\maxcol\stopcol\fi
  \global\ahmed=\expandafter{\the\ahmed\samp}\docols
}
\def\stopcol#1\docols{\fi}
\def\samp{&}
\def\dorows{%
  \global\advance\rowcnt\@ne
  \global\colcnt\z@
  \docols
  \ifnum\rowcnt=\maxrow\stoprow\fi
  \global\ahmed=\expandafter{\the\ahmed\scr}\dorows
}
\def\stoprow#1\dorows{\fi\global\ahmed=\expandafter{\the\ahmed\crcr}}
\def\scr{\cr}
\makeatother

\begin{document}
\maxrow4 \maxcol3
$$\vbox{\halign{&\ \hfil#\hfil\strut\cr\dorows\showthe\ahmed\the\ahmed}}$$
\end{document}

The \show command will output

> 1&2&3\cr 2&4&6\cr 3&6&9\cr 4&8&12\crcr .
l.27 ... \hfil#\hfil\strut\cr\dorows\showthe\ahmed
                                                  \the\ahmed}}$$

With this approach you can use & and \cr, because they would be protected by the braces of the token register assignment.

  • But the above result of \show\ahmed indicates that $$\vbox{&...\dorows\the\ahmed}}$$ can't be a solution. It will inherit only the last (max.) values of the counters. I think you need to remove \the\ahmed after \showthe\ahmed, to indicate that you mean $$\vbox{&...\dorows\showthe\ahmed}}$$ only as an illustration. – Ahmed Musa Jun 2 '12 at 21:02
  • @AhmedMusa You are right, I forgot an \expandafter. Fixed. – egreg Jun 2 '12 at 21:07
  • Then you need to also replace the outcome of \showthe\ahmed. – Ahmed Musa Jun 2 '12 at 21:14
  • @AhmedMusa I don't understand: the \showthe\ahmed shows the contents of the register, while \the\ahmed delivers it to the \halign for printing. – egreg Jun 2 '12 at 21:18
  • I have added something to the original question. – Ahmed Musa Jun 2 '12 at 23:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.