Is it possible to define a command, which repeats the following command n-times? Call it for example \Repeat, then
\Repeat[4] \command{...}
should be equivalent to
\command{...} \command{...} \command{...} \command{...}
Is it possible to define a command, which repeats the following command n-times? Call it for example \Repeat, then
\Repeat[4] \command{...}
should be equivalent to
\command{...} \command{...} \command{...} \command{...}
This can be done in an expandable form using \csname. I would personally use the 'pre-packed' version in expl3:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new_eq:NN \Repeat \prg_replicate:nn
\ExplSyntaxOff
\begin{document}
\Repeat{4}{\command{...}}
\end{document}
For those who would code by hand, the basic approach (originally by David Kastrup, modified somewhat by the rest of the team) is
\catcode `\@ = 11\relax
\long\def\replicate#1{%
\romannumeral
\expandafter\replicate@first@aux\number#1%
\endcsname
}
\long\def\replicate@first@aux#1{%
\csname replicate@first@#1\replicate@aux
}
\chardef\rm@end=0 %
\long\expandafter\def\csname replicate@first@-\endcsname
#1{\rm@end\NegativeReplication}
\long\expandafter\def\csname replicate@first@0\endcsname
#1{\rm@end}
\long\expandafter\def\csname replicate@first@1\endcsname
#1{\rm@end #1}
\long\expandafter\def\csname replicate@first@2\endcsname
#1{\rm@end #1#1}
\long\expandafter\def\csname replicate@first@3\endcsname
#1{\rm@end #1#1#1}
\long\expandafter\def\csname replicate@first@4\endcsname
#1{\rm@end #1#1#1#1}
\long\expandafter\def\csname replicate@first@5\endcsname
#1{\rm@end #1#1#1#1#1}
\long\expandafter\def\csname replicate@first@6\endcsname
#1{\rm@end #1#1#1#1#1#1}
\long\expandafter\def\csname replicate@first@7\endcsname
#1{\rm@end #1#1#1#1#1#1#1}
\long\expandafter\def\csname replicate@first@8\endcsname
#1{\rm@end #1#1#1#1#1#1#1#1}
\long\expandafter\def\csname replicate@first@9\endcsname
#1{\rm@end #1#1#1#1#1#1#1#1#1}
\def\replicate@aux#1{%
\csname replicate@#1\replicate@aux
}
\long\expandafter\def\csname replicate@\endcsname#1{\endcsname}
\long\expandafter\def\csname replicate@0\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}}
\long\expandafter\def\csname replicate@1\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
\long\expandafter\def\csname replicate@2\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
\long\expandafter\def\csname replicate@3\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
\long\expandafter\def\csname replicate@4\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
\long\expandafter\def\csname replicate@5\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
\long\expandafter\def\csname replicate@6\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
\long\expandafter\def\csname replicate@7\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
\long\expandafter\def\csname replicate@8\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
\long\expandafter\def\csname replicate@9\endcsname
#1{\endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
\catcode `\@ = 12\relax
\edef\test{\replicate{20}{abc}}
\show\test
\bye
In the expl3 version, the \number#1 is (effectively) replaced by \number\numexpr#1\relax, which allows the 'number' used to be a calculation. If you try a negative number, the deliberately-undefined control sequence raises an error as part of the expansion, rather than having some odd error later.
A second expandable approach is to use \romannumeral, for example
\catcode `\@ = 11\relax
\def\replicate#1{%
\expandafter\replicate@aux\romannumeral\number #1000Q{}
}
\def\replicate@aux#1{\csname replicate@aux@#1\endcsname}
\long\def\replicate@aux@m#1Q#2#3{\replicate@aux#1Q{#2#3}{#3}}
\long\def\replicate@aux@Q#1#2{#1}
\edef\test{\replicate{5}{a}}
\show\test
\bye
This is clearer to code than the \csname approach, but is effectively a loop again and so gets slow for large numbers of repetitions.
\prg_replicate:nn {10000}{\prg_replicate:nn {10000}{...}}. Not needed often.
– Bruno Le Floch
May 13 '11 at 08:41
\Repeat command by a user input? \newcommand{\test}[1]{\Repeat{#1}{Test}} does not work as #1 is not recognized as number.
– Sam
Sep 01 '18 at 00:21
You can use the \foreach-command from PGF/TikZ.
\documentclass{minimal}
\usepackage{pgffor}
\newcommand{\cmd}{-x-}
% to provide your syntax
\newcommand{\Repeat}[2]{% \repeat already defined
\foreach \n in {1,...,#1}{#2}
}
\begin{document}
\foreach \n in {1,...,4}{\cmd}
\Repeat{6}{\cmd}
\end{document}
For more information see the pgfmanual.pdf, section 56, pp. 504 an following.
There’s also a TeX-Way see e.g. this page (in german …)
pgfs \foreach has the drawback that the command is executed in a group, which might be a big problem or none at all depending on the application. BTW: there is no reason the write {} after \cmd inside the loop, except if you have it as a placeholder for a possible argument (then you should write it as {...} as the OP did).
– Martin Scharrer
Apr 19 '11 at 19:33
{}. You’re right an I edited my post. Could you please outline a situation where the \foreach-group causes problems?
– Tobi
Apr 19 '11 at 20:38
\foreachif not I’ll be back to ask here ;-)
– Tobi
Apr 19 '11 at 21:57
ticket package and the \foreach loop. It failed. All tickets are printed at the same location.
– Lemming
Jul 27 '17 at 09:35
\foreach could cause problems and I gave you such a situation that I encountered in real life. The solution in my case was multido as suggested in another answer. I may edit my comment in order to make my intention clearer.
– Lemming
Jul 27 '17 at 16:08
multido has a simple interface for replication:

\documentclass{article}
\usepackage{multido}
\newcommand{\cmd}{-x-}
\newcommand{\Repeat}{\multido{\i=1+1}}
\begin{document}
\Repeat{6}{\cmd}
\end{document}
\i=1+1 is useless here, \newcommand{\Repeat}{\multido{}} is enough.
– Kpym
Apr 29 '18 at 19:47
Here some implementation I came up with which doesn't need any extra package. It uses \numexpr to avoid counters and is fully expandable.
\documentclass{article}
\makeatletter
\newcommand{\Repeat}[1]{%
\expandafter\@Repeat\expandafter{\the\numexpr #1\relax}%
}
\def\@Repeat#1{%
\ifnum#1>0
\expandafter\@@Repeat\expandafter{\the\numexpr #1-1\expandafter\relax\expandafter}%
\else
\expandafter\@gobble
\fi
}
\def\@@Repeat#1#2{%
\@Repeat{#1}{#2}#2%
}
\makeatother
\begin{document}
\Repeat{0}{test }
\Repeat{1}{test }
\Repeat{2}{test }
\Repeat{3}{test }
\Repeat{4}{test }
\Repeat{5}{test }
\edef\TEST{\Repeat{5}{test }}
\texttt{\meaning\TEST}
\end{document}
expl3 code, but it looks like it needs e-TeX to me. It uses \int_eval:w a.k.a. \numexpr.
– TH.
Apr 20 '11 at 07:42
expl3 implementation does indeed need \numexpr, as that makes the nature of the 'number' you give be more flexible. However, the original version of this approach just uses \number, and thus no e-TeX. Later on today I'll post the code 'translated' to plain TeX as a separate answer.
– Joseph Wright
Apr 20 '11 at 08:09
expl3 version.
– Joseph Wright
Apr 20 '11 at 08:34
expl3.)
– TH.
Apr 20 '11 at 08:49
\csnames) is not so clever (IMHO) because there is redundant \romannumeral-`0 and more redundant \expandafters before each \long primitive.
– wipet
Mar 21 '16 at 07:51
\expandafter (a re-writing oversight) and second to adjust where the \romannumeral is so it's doing what was intended.
– Joseph Wright
Mar 21 '16 at 08:52
expl3 is very clever and seems hard to beat. A variant can be coded more compactly, but less efficiently, using \numexpr to divide by 2 (as we don't have access bitwise to computer words must go via division by 2 and oddness checks). Perhaps it could be pointed out that apart from speed it also avoids the input save stack problem which the "linear" approach as in Martin's code , which leaves upstream one copy at a time, necessarily hits. (this is why I am leaving my comment here...). (one can modify the code here to deliver only at the end, but this is slower).
–
Mar 23 '16 at 08:25
Plain and simple (pun intended):
\def\foo{keke}
\def\bar#1#2{\count0=#1 \loop \ifnum\count0>0 \advance\count0 by -1 #2\repeat}
\bar3\foo % results in kekekekekeke
\bye
Token list registers expand more quickly, so if it suits you, you could also do:
\newtoks\foo \foo={keke}
\def\bar#1#2{\count0=#1 \loop \ifnum\count0>0 \advance\count0 by -1 \the#2\repeat}
\bar3\foo % results in kekekekekeke
\bye
Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):
\def\foo{keke}
\def\gobbleone#1{}
\long\def\replicate#1#2{%
\ifnum\numexpr#1>0
#2\expandafter\replicate\expandafter
{\number\numexpr#1-1\expandafter}%
\else
\expandafter\gobbleone
\fi{#2}}
\replicate3\foo % results in kekekekekeke
\bye
\edef or \write an TeX converts it fully to what you want. Assignments are not expandable, and so a loop using a count will not turn into a series of repeated commands inside an \edef.
– Joseph Wright
Apr 20 '11 at 07:06
Of course, the simple answer to the OP is: use \loop. But there are more codes here signed as "clever", if the loop is done only at expand processor level. And more "clever" codes here do this without using of eTeX primitives.
So, I give two codes here. You can explore them from "cleverness" point of view:).
First code uses known trick with \romannumeral #1000 which expands to #1 "em"s and then we do loop over these "em"s over input stream. The main difference from the similar code presented here by @Joseph is that we needn't to read whole long sequence of "em"s again and again:
\def\replicate#1{\expandafter\repU\expandafter{\romannumeral\number#1000}}
\def\repU#1#2{\repV{#2}#1;}
\def\repV#1#2{\ifx#2;\else#1\fihere\repV{#1}\fi}
\def\fihere#1\fi{\fi#1}
\message{\replicate{27}{abc}}
\bye
The second code is inspired by second code presented here by @Joseph where each decimal digit is processed individually. The code (in the accepted answer) uses nested \csnames. I do the same without nested \csnames and the code is more compact. Of course, it works at expand processor level without any need of eTeX primitives:
\def\replicate#1{\expandafter\repA\number#1;;}
\def\repA#1#2;#3;{\ifx;#2;\repB#1#3\fi \repA#2;#1#3;}
\def\repB#1\fi#2;#3;{\fi\repC{#1}}
\def\repC#1#2{\repD{#2}#1;}
\def\repD#1#2{\ifx#2;\else \repE{#1}#2\fi}
\def\repE#1#2\fi{\fi \repF#2{#1}\repD{\repF{10}{#1}}}
\def\repF#1#2{\ifcase#1 \or#2\or#2#2\or#2#2#2\or#2#2#2#2\or#2#2#2#2#2\or
#2#2#2#2#2#2\or#2#2#2#2#2#2#2\or#2#2#2#2#2#2#2#2\or
#2#2#2#2#2#2#2#2#2\or#2#2#2#2#2#2#2#2#2#2\fi}
\message{\replicate{27}{abc}}
\bye
\romannumeral-`0.
–
Mar 22 '16 at 22:24
Here is an example with loop and newcommand:
\documentclass{article}
\newcounter{z}
\newcommand\y[2]{
\loop \ifnum\value{z} < #1
#2%
\stepcounter{z}%
\repeat
}
\begin{document}
\y{10}{Hello}
\end{document}
I tried an alternative to the clever \csname governed expansion from Joseph's answer borrowed from expl3 code.
eTeX is used only to allow input to be an expression: else replace \the\numexpr at the start by \number.
This is less efficient than the David Kastrup + LaTeX team code, although perhaps it becomes about the same when the number of replications is in the thousands (not much tested).
The initial version of this answer had more complicated code which was at about the same level of efficiency. There was an unfortunate \chardef\z@=0 in that code, which is very wrong and I don't know why it was there.
This answer handles more efficiently than Joseph's the case of a negative asked for number of replication.
It could be easily reworked into a macro (working only in a \edef) leaving tokens behind it rather than in front of it while expanding.
\catcode`@ 11
\def\JFsignfork #10-#2#3\krof {#2}
%\chardef\z@ 0 % NO! \z@ is a dimen in TeX/LaTeX
\def\JFrep #1{\romannumeral\expandafter\JFrep@a\the\numexpr #1;3456789XY!}%
\def\JFrep@a #1{\JFsignfork
#1-\JFrep@nil
0#1\JFrep@neg
0-\JFrep@b
\krof #1%
}%
\long\def\JFrep@nil #1!#2{\z@}
\long\def\JFrep@neg #1!#2{\z@\NegativeReplication}
% TeX numbers have at most 10 digits
\def\JFrep@b #1#2#3#4#5#6#7#8#9{\JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
\def\JFrep@c #1#2#3#4!{\JFrep@d .#3.#2#1!}
\def\JFrep@d #1;#2#3{\csname JFrep@f#2#3\endcsname}
\long\expandafter\def\csname JFrep@f.0\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
\long\expandafter\def\csname JFrep@f.1\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
\long\expandafter\def\csname JFrep@f.2\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
\long\expandafter\def\csname JFrep@f.3\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
\long\expandafter\def\csname JFrep@f.4\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
\long\expandafter\def\csname JFrep@f.5\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
\long\expandafter\def\csname JFrep@f.6\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
\long\expandafter\def\csname JFrep@f.7\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
\long\expandafter\def\csname JFrep@f.8\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
\long\expandafter\def\csname JFrep@f.9\endcsname #1#2#3!#4%
{\csname JFrep@f#1#2\endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
\long\expandafter\def\csname JFrep@f;1\endcsname!#1{\z@#1}%
\long\expandafter\def\csname JFrep@f;2\endcsname!#1{\z@#1#1}%
\long\expandafter\def\csname JFrep@f;3\endcsname!#1{\z@#1#1#1}%
\long\expandafter\def\csname JFrep@f;4\endcsname!#1{\z@#1#1#1#1}%
\long\expandafter\def\csname JFrep@f;5\endcsname!#1{\z@#1#1#1#1#1}%
\long\expandafter\def\csname JFrep@f;6\endcsname!#1{\z@#1#1#1#1#1#1}%
\long\expandafter\def\csname JFrep@f;7\endcsname!#1{\z@#1#1#1#1#1#1#1}%
\long\expandafter\def\csname JFrep@f;8\endcsname!#1{\z@#1#1#1#1#1#1#1#1}%
\long\expandafter\def\csname JFrep@f;9\endcsname!#1{\z@#1#1#1#1#1#1#1#1#1}%
\catcode`@ 12
\edef\test{\JFrep{123}{abc}}
\show\test
\bye
\xintreplicate in xint but it is a clone of the expl3's code with very minor changes, it is not the code of this answer...
–
Apr 29 '18 at 20:26
\repeatis already defined by LaTeX as end-macro for\loop. – Martin Scharrer Apr 19 '11 at 19:34