Copy table row n times
The main problem is that \foreach
works in a group, but it's not only that.
The simplest thing to do is to first build the table in a macro and then expand it:
\documentclass{article}
\usepackage{tikz}
\newcommand{\test}[1]{%
\def\temp{}%
\foreach \i in {1,...,#1}
{%
\expandafter\gdef\expandafter\temp\expandafter{\temp t1 & t2 \\}%
}%
\temp}
\begin{document}
\begin{tabular}{cc}
\test{3}
\end{tabular}
\end{document}
The \temp
macro is initialized to empty and then augmented at each cycle; at the end it's expanded. The \gdef
is necessary because of the implicit groups around the cycles.
With \test{3}
what happens is essentially
\def\temp{}%
{\expandafter\gdef\expandafter\temp\expandafter{\temp t1 & t2 \\}}%
{\expandafter\gdef\expandafter\temp\expandafter{\temp t1 & t2 \\}}%
{\expandafter\gdef\expandafter\temp\expandafter{\temp t1 & t2 \\}}%
\temp
and everything takes place when TeX is still looking for the material in the first cell of the first row. The first line states that \temp
expands to nothing; then the second line is executed: each \expandafter
expands the second token after it; for the first two it's another \expandafter
so we arrive at \temp
. Hence the second line is equivalent to saying
{\gdef\temp{t1 & t2 \\}}
but when the same operation is performed in the third line the effect is
{\gdef\temp{t1 & t2 \\t1 & t2 \\}}
and at the fourth line it becomes
{\gdef\temp{t1 & t2 \\t1 & t2 \\t1 & t2 \\}}
The supplementary braces represent the implicit group that \foreach
puts around the cycles. Thus \gdef
is necessary because otherwise the redefinition of \temp
would disappear at group end.
The presence of &
tokens is not a problem, because TeX scans it between braces, so they aren't used for marking the end of a cell. This is an issue that, sometimes, bites someone.
At the end, \temp
will produce the tokens
t1 & t2 \\t1 & t2 \\t1 & t2 \\
that will be seen properly by TeX for building the table.
A less readable definition, but which does exactly the same, would be
\makeatletter
\newcommand{\test}[1]{%
\let\@temp\@empty
\foreach \i in {1,...,#1}
{%
\g@addto@macro\@temp{t1 & t2 \\}%
}%
\@temp}
\makeatother
The compulsory LaTeX3 version:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\repeatrow}{mm}
{
\azet_repeat_row:nn { #1 } { #2 }
}
\tl_new:N \l_azet_rows_tl
\cs_new_protected:Npn \azet_repeat_row:nn #1 #2
{
\tl_clear:N \l_azet_rows_tl
\prg_replicate:nn { #1 } { \tl_put_right:Nn \l_azet_rows_tl { #2 \\ } }
\tl_use:N \l_azet_rows_tl
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{cc}
\repeatrow{3}{t1 & t2}
\end{tabular}
\end{document}
The working is very similar to the "classical" solution, but it uses \prg_replicate:nn
instead of \foreach
. The command is
\prg_replicate:nn { <integer expression> } { <code> }
and it evaluates the <integer expression>
(so one might also call \repeatrow{3*5}{...}
); then it repeats the <code>
in the second argument as many times as specified in the first one.
This command is preceded by the analog of \def\temp{}
: the token list variable \l_azet_rows_tl
is cleared and the <code>
is just "append the second argument to \azet_repeat_row:nn
(which in turn is the "internal" version of \repeatrow
). Then the contents of the token list variable is delivered for use (the analog of saying \temp
in the first solution).
You don't really need a for-each macro for this, you just need to take care that your loop counter and the groups from the table cells interact correctly.
The following produces the three row table without any large (or small) package overhead.
\documentclass{article}
\newcommand{\test}[1]{%
t1 & t2 \\
\ifnum#1>1
\expandafter\test\expandafter{\numexpr#1-1\expandafter\relax\expandafter}\fi
}
\begin{document}
\begin{tabular}{cc}
\test{3}
\end{tabular}
\end{document}
Here is an alternative using Latex 3,
\documentclass[letterpaper]{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \Copy \prg_replicate:nn
\ExplSyntaxOff
\begin{document}
\begin{tabular}{cc}
\Copy{4}{t1 & t2 \\}
\end{tabular}
\end{document}