I did two things. I prefixed \multicolumn
with \noexpand
, so that the \multicolumn
token was not expanded by \eaddtabtoks
. Then, and I am not 100% sure why this was necessary, but I concluded it was the safest way, I performed the complete tabular
in the closing end of the environment.
My hypothesis as to why this is necessary is that, as originally proposed, Cell(1,1) has a lot of non-printing calculations followed by a \multicolumn
. The way I have recast it, all those non-printing calculations occur before the tabular
starts. I am guessing that \multicolumn
must appear as the first token of a cell, which otherwise gets hosed by all the preliminary calculations (Note: the calculations of which I speak are the figuring out which tokens to add to \@tabtoks
and the creation of \@tabtoks
). I think this theory can be proven by trying with my working solution, to change the definition of \myrow
by adding a seemingly innocuous \relax
before the \multicolumn
token. It breaks in exactly the same way, which seems to indicate that \multicolumn
cannot be preceded by non-printing calculations.
Also, I discovered that you needed a %
at the end of the \multicolumn
line.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{booktabs}
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand\eaddtabtoks[1]{\edef\mytmp{#1}\expandafter\addtabtoks\expandafter{\mytmp}}
\newcommand*\resettabtoks{\global\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\newcommand{\topic}[2]{%
\eaddtabtoks{Col 1 & Col 2 & Col 3 & #1 & #2}%
\addtabtoks{\\}%
\ignorespaces
}
\newcommand{\myline}{%
\addtabtoks{\toprule}%
}
\newcommand{\myrow}[1]{%
\eaddtabtoks{\noexpand\multicolumn{5}{c}{#1}}%
\addtabtoks{\\}%
\ignorespaces
}
\newenvironment{mytabular}{%
\resettabtoks
\noindent
}{%
\begin{tabular}{llrrl}
\printtabtoks
\end{tabular}
}
\makeatother
\begin{document}
\begin{mytabular}
\myrow{all five}
\myline
\topic{1.1}{LaTeX}
\topic{1.2}{causes}
\topic{1.3}{me}
\topic{1.4}{lots}
\topic{1.5}{of}
\topic{1.6}{frustration}
\end{mytabular}
\end{document}

As a follow up, Note that both invocations of \eaddtabtoks
(appearing in the definitions of \topic
and \myrow
) can be changed to [the non-expanding] \addtabtoks
(if you eliminate the \noexpand
that I inserted). That is because #1
and #2
are already inserted as the actual argument tokens. There may be other reasons (not shown in the MWE) why you would prefer to expand or not expand the arguments to \topic
and \myrow
, but in general, I think not expanding them in advance is safer.
Here's an example that breaks the \eaddtabtoks
version, but works with the \addtabtoks
version:
\newcounter{step}
\begin{mytabular}
\myrow{all five}
\myline
\topic{1.\thestep}{LaTeX\stepcounter{step}}
\topic{1.\thestep}{causes\stepcounter{step}}
\topic{1.\thestep}{me\stepcounter{step}}
\topic{1.\thestep}{lots\stepcounter{step}}
\topic{1.\thestep}{of\stepcounter{step}}
\topic{1.\thestep}{frustration\stepcounter{step}}
\end{mytabular}