Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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}
share|improve this question
add comment

1 Answer 1

up vote 6 down vote accepted

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.

share|improve this answer
    
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
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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