Repeat command n times?A command for making a string of charactersRepeat characters n timesHow to define a...

Is the destination of a commercial flight important for the pilot?

Go Pregnant or Go Home

How to be diplomatic in refusing to write code that breaches the privacy of our users

How easy is it to start Magic from scratch?

Opposite of a diet

Large drywall patch supports

Is a stroke of luck acceptable after a series of unfavorable events?

How does Loki do this?

Was Spock the First Vulcan in Starfleet?

Is exact Kanji stroke length important?

How did Arya survive the stabbing?

How does it work when somebody invests in my business?

Why didn't Theresa May consult with Parliament before negotiating a deal with the EU?

How can I kill an app using Terminal?

What is the opposite of 'gravitas'?

How does buying out courses with grant money work?

Where does the Z80 processor start executing from?

Class Action - which options I have?

How to pronounce the slash sign

Two monoidal structures and copowering

Term for the "extreme-extension" version of a straw man fallacy?

Why Were Madagascar and New Zealand Discovered So Late?

Avoiding estate tax by giving multiple gifts

How to draw lines on a tikz-cd diagram



Repeat command n times?


A command for making a string of charactersRepeat characters n timesHow to define a parshape command with LaTeX?Beamer: including items only some slides using a relative syntaxTricks to make macros expandableelsarticle: Changing symbol used in tnoterefBox with Semicircular Parshape at Top and Bottomdatatool repeat rowHow to avoid the compilation of some of my newcommands in latexShort syntax for including multiple times the same pages in pdfpagesHow to define a command that returns different commands based on a parameterdatatool repeat rowRepeat geometry / body / object / shape in PGFplotsHow to repeat over all characters in a string?How to use macros to repeat math equations in different settingsRepeat characters n timesNew command like an arbitrary number of nested applications of some commandRepeat last environment by commandPassing next character to commandDefault value of command













38















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{...} 









share|improve this question




















  • 1





    Note that repeat is already defined by LaTeX as end-macro for loop.

    – Martin Scharrer
    Apr 19 '11 at 19:34
















38















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{...} 









share|improve this question




















  • 1





    Note that repeat is already defined by LaTeX as end-macro for loop.

    – Martin Scharrer
    Apr 19 '11 at 19:34














38












38








38


7






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{...} 









share|improve this question
















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{...} 






macros programming






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Apr 19 '11 at 19:41







student

















asked Apr 19 '11 at 19:17









studentstudent

12.4k24102176




12.4k24102176








  • 1





    Note that repeat is already defined by LaTeX as end-macro for loop.

    – Martin Scharrer
    Apr 19 '11 at 19:34














  • 1





    Note that repeat is already defined by LaTeX as end-macro for loop.

    – Martin Scharrer
    Apr 19 '11 at 19:34








1




1





Note that repeat is already defined by LaTeX as end-macro for loop.

– Martin Scharrer
Apr 19 '11 at 19:34





Note that repeat is already defined by LaTeX as end-macro for loop.

– Martin Scharrer
Apr 19 '11 at 19:34










8 Answers
8






active

oldest

votes


















29














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 `@ = 11relax
longdefreplicate#1{%
romannumeral
expandafterreplicate@first@auxnumber#1%
endcsname
}
longdefreplicate@first@aux#1{%
csname replicate@first@#1replicate@aux
}
chardefrm@end=0 %
longexpandafterdefcsname replicate@first@-endcsname
#1{rm@endNegativeReplication}
longexpandafterdefcsname replicate@first@0endcsname
#1{rm@end}
longexpandafterdefcsname replicate@first@1endcsname
#1{rm@end #1}
longexpandafterdefcsname replicate@first@2endcsname
#1{rm@end #1#1}
longexpandafterdefcsname replicate@first@3endcsname
#1{rm@end #1#1#1}
longexpandafterdefcsname replicate@first@4endcsname
#1{rm@end #1#1#1#1}
longexpandafterdefcsname replicate@first@5endcsname
#1{rm@end #1#1#1#1#1}
longexpandafterdefcsname replicate@first@6endcsname
#1{rm@end #1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@7endcsname
#1{rm@end #1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@8endcsname
#1{rm@end #1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@9endcsname
#1{rm@end #1#1#1#1#1#1#1#1#1}
defreplicate@aux#1{%
csname replicate@#1replicate@aux
}
longexpandafterdefcsname replicate@endcsname#1{endcsname}
longexpandafterdefcsname replicate@0endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}}
longexpandafterdefcsname replicate@1endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
longexpandafterdefcsname replicate@2endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
longexpandafterdefcsname replicate@3endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
longexpandafterdefcsname replicate@4endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
longexpandafterdefcsname replicate@5endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
longexpandafterdefcsname replicate@6endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
longexpandafterdefcsname replicate@7endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@8endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@9endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
catcode `@ = 12relax
edeftest{replicate{20}{abc}}
showtest
bye


In the expl3 version, the number#1 is (effectively) replaced by numbernumexpr#1relax, 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 `@ = 11relax
defreplicate#1{%
expandafterreplicate@auxromannumeralnumber #1000Q{}
}
defreplicate@aux#1{csname replicate@aux@#1endcsname}
longdefreplicate@aux@m#1Q#2#3{replicate@aux#1Q{#2#3}{#3}}
longdefreplicate@aux@Q#1#2{#1}
edeftest{replicate{5}{a}}
showtest
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.






share|improve this answer


























  • Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

    – Martin Scharrer
    Apr 19 '11 at 19:56











  • Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

    – Will Robertson
    Apr 20 '11 at 9:20











  • As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

    – Joseph Wright
    Apr 20 '11 at 9:28











  • The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

    – Joseph Wright
    Apr 20 '11 at 9:56






  • 2





    However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

    – Bruno Le Floch
    May 13 '11 at 8:41



















17














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 …)






share|improve this answer





















  • 4





    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








  • 1





    @MartinScharrer There’s no special reason why I used the {}. 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








  • 1





    All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

    – Martin Scharrer
    Apr 19 '11 at 21:06











  • @MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

    – Tobi
    Apr 19 '11 at 21:57











  • I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

    – Lemming
    Jul 27 '17 at 9:35



















12














multido has a simple interface for replication:



enter image description here



documentclass{article}
usepackage{multido}
newcommand{cmd}{-x-}
newcommand{Repeat}{multido{i=1+1}}
begin{document}

Repeat{6}{cmd}
end{document}





share|improve this answer



















  • 1





    This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

    – Kpym
    Apr 29 '18 at 19:47



















7














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@Repeatexpandafter{thenumexpr #1relax}%
}

def@Repeat#1{%
ifnum#1>0
expandafter@@Repeatexpandafter{thenumexpr #1-1expandafterrelaxexpandafter}%
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 }

edefTEST{Repeat{5}{test }}
texttt{meaningTEST}

end{document}





share|improve this answer
























  • If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

    – Joseph Wright
    Apr 19 '11 at 20:33











  • @Joseph: I have a really hard time reading the 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 7:42











  • @TH. The 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 8:09











  • @TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

    – Joseph Wright
    Apr 20 '11 at 8:34











  • @Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

    – TH.
    Apr 20 '11 at 8:49



















6














Plain and simple (pun intended):



deffoo{keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 #2repeat}
bar3foo % results in kekekekekeke
bye


Token list registers expand more quickly, so if it suits you, you could also do:



newtoksfoo foo={keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 the#2repeat}
bar3foo % results in kekekekekeke
bye


Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):



deffoo{keke}
defgobbleone#1{}
longdefreplicate#1#2{%
ifnumnumexpr#1>0
#2expandafterreplicateexpandafter
{numbernumexpr#1-1expandafter}%
else
expandaftergobbleone
fi{#2}}
replicate3foo % results in kekekekekeke
bye





share|improve this answer


























  • Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

    – Martin Scharrer
    Apr 19 '11 at 20:54













  • What does it mean not being expandable?

    – Christian Lindig
    Apr 20 '11 at 5:52











  • Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

    – morbusg
    Apr 20 '11 at 7:06






  • 1





    @Christian: Something is expandable if you can use it inside an 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 7:06











  • @Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

    – Joseph Wright
    Apr 20 '11 at 7:08



















4














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:



defreplicate#1{expandafterrepUexpandafter{romannumeralnumber#1000}}
defrepU#1#2{repV{#2}#1;}
defrepV#1#2{ifx#2;else#1fihererepV{#1}fi}
deffihere#1fi{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:



defreplicate#1{expandafterrepAnumber#1;;}
defrepA#1#2;#3;{ifx;#2;repB#1#3fi repA#2;#1#3;}
defrepB#1fi#2;#3;{firepC{#1}}
defrepC#1#2{repD{#2}#1;}
defrepD#1#2{ifx#2;else repE{#1}#2fi}
defrepE#1#2fi{fi repF#2{#1}repD{repF{10}{#1}}}
defrepF#1#2{ifcase#1 or#2or#2#2or#2#2#2or#2#2#2#2or#2#2#2#2#2or
#2#2#2#2#2#2or#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2or
#2#2#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2#2#2fi}

message{replicate{27}{abc}}
bye





share|improve this answer


























  • My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

    – Joseph Wright
    Mar 21 '16 at 10:20











  • nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

    – user4686
    Mar 22 '16 at 22:24



















2














Here is an example with loop and newcommand:



documentclass{article}
newcounter{z}
newcommandy[2]{
loop ifnumvalue{z} < #1
#2%
stepcounter{z}%
repeat
}
begin{document}
y{10}{Hello}
end{document}





share|improve this answer


























  • The request is to repeat a command

    – Andrew Swann
    Mar 20 '16 at 15:11











  • Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

    – Andrew Swann
    Mar 20 '16 at 15:23











  • Isn't this the same as the first suggestion in @morbusg's answer?

    – clemens
    Mar 20 '16 at 15:27



















2














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 thenumexpr 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 chardefz@=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

defJFsignfork #10-#2#3krof {#2}
%chardefz@ 0 % NO! z@ is a dimen in TeX/LaTeX

defJFrep #1{romannumeralexpandafterJFrep@athenumexpr #1;3456789XY!}%
defJFrep@a #1{JFsignfork
#1-JFrep@nil
0#1JFrep@neg
0-JFrep@b
krof #1%
}%
longdefJFrep@nil #1!#2{z@}
longdefJFrep@neg #1!#2{z@NegativeReplication}

% TeX numbers have at most 10 digits
defJFrep@b #1#2#3#4#5#6#7#8#9{JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
defJFrep@c #1#2#3#4!{JFrep@d .#3.#2#1!}
defJFrep@d #1;#2#3{csname JFrep@f#2#3endcsname}
longexpandafterdefcsname JFrep@f.0endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
longexpandafterdefcsname JFrep@f.1endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
longexpandafterdefcsname JFrep@f.2endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
longexpandafterdefcsname JFrep@f.3endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
longexpandafterdefcsname JFrep@f.4endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
longexpandafterdefcsname JFrep@f.5endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.6endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.7endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.8endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.9endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f;1endcsname!#1{z@#1}%
longexpandafterdefcsname JFrep@f;2endcsname!#1{z@#1#1}%
longexpandafterdefcsname JFrep@f;3endcsname!#1{z@#1#1#1}%
longexpandafterdefcsname JFrep@f;4endcsname!#1{z@#1#1#1#1}%
longexpandafterdefcsname JFrep@f;5endcsname!#1{z@#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;6endcsname!#1{z@#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;7endcsname!#1{z@#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;8endcsname!#1{z@#1#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;9endcsname!#1{z@#1#1#1#1#1#1#1#1#1}%

catcode`@ 12

edeftest{JFrep{123}{abc}}
showtest

bye





share|improve this answer


























  • There is now an 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...

    – user4686
    Apr 29 '18 at 20:26











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f16189%2frepeat-command-n-times%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























8 Answers
8






active

oldest

votes








8 Answers
8






active

oldest

votes









active

oldest

votes






active

oldest

votes









29














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 `@ = 11relax
longdefreplicate#1{%
romannumeral
expandafterreplicate@first@auxnumber#1%
endcsname
}
longdefreplicate@first@aux#1{%
csname replicate@first@#1replicate@aux
}
chardefrm@end=0 %
longexpandafterdefcsname replicate@first@-endcsname
#1{rm@endNegativeReplication}
longexpandafterdefcsname replicate@first@0endcsname
#1{rm@end}
longexpandafterdefcsname replicate@first@1endcsname
#1{rm@end #1}
longexpandafterdefcsname replicate@first@2endcsname
#1{rm@end #1#1}
longexpandafterdefcsname replicate@first@3endcsname
#1{rm@end #1#1#1}
longexpandafterdefcsname replicate@first@4endcsname
#1{rm@end #1#1#1#1}
longexpandafterdefcsname replicate@first@5endcsname
#1{rm@end #1#1#1#1#1}
longexpandafterdefcsname replicate@first@6endcsname
#1{rm@end #1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@7endcsname
#1{rm@end #1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@8endcsname
#1{rm@end #1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@9endcsname
#1{rm@end #1#1#1#1#1#1#1#1#1}
defreplicate@aux#1{%
csname replicate@#1replicate@aux
}
longexpandafterdefcsname replicate@endcsname#1{endcsname}
longexpandafterdefcsname replicate@0endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}}
longexpandafterdefcsname replicate@1endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
longexpandafterdefcsname replicate@2endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
longexpandafterdefcsname replicate@3endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
longexpandafterdefcsname replicate@4endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
longexpandafterdefcsname replicate@5endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
longexpandafterdefcsname replicate@6endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
longexpandafterdefcsname replicate@7endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@8endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@9endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
catcode `@ = 12relax
edeftest{replicate{20}{abc}}
showtest
bye


In the expl3 version, the number#1 is (effectively) replaced by numbernumexpr#1relax, 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 `@ = 11relax
defreplicate#1{%
expandafterreplicate@auxromannumeralnumber #1000Q{}
}
defreplicate@aux#1{csname replicate@aux@#1endcsname}
longdefreplicate@aux@m#1Q#2#3{replicate@aux#1Q{#2#3}{#3}}
longdefreplicate@aux@Q#1#2{#1}
edeftest{replicate{5}{a}}
showtest
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.






share|improve this answer


























  • Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

    – Martin Scharrer
    Apr 19 '11 at 19:56











  • Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

    – Will Robertson
    Apr 20 '11 at 9:20











  • As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

    – Joseph Wright
    Apr 20 '11 at 9:28











  • The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

    – Joseph Wright
    Apr 20 '11 at 9:56






  • 2





    However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

    – Bruno Le Floch
    May 13 '11 at 8:41
















29














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 `@ = 11relax
longdefreplicate#1{%
romannumeral
expandafterreplicate@first@auxnumber#1%
endcsname
}
longdefreplicate@first@aux#1{%
csname replicate@first@#1replicate@aux
}
chardefrm@end=0 %
longexpandafterdefcsname replicate@first@-endcsname
#1{rm@endNegativeReplication}
longexpandafterdefcsname replicate@first@0endcsname
#1{rm@end}
longexpandafterdefcsname replicate@first@1endcsname
#1{rm@end #1}
longexpandafterdefcsname replicate@first@2endcsname
#1{rm@end #1#1}
longexpandafterdefcsname replicate@first@3endcsname
#1{rm@end #1#1#1}
longexpandafterdefcsname replicate@first@4endcsname
#1{rm@end #1#1#1#1}
longexpandafterdefcsname replicate@first@5endcsname
#1{rm@end #1#1#1#1#1}
longexpandafterdefcsname replicate@first@6endcsname
#1{rm@end #1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@7endcsname
#1{rm@end #1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@8endcsname
#1{rm@end #1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@9endcsname
#1{rm@end #1#1#1#1#1#1#1#1#1}
defreplicate@aux#1{%
csname replicate@#1replicate@aux
}
longexpandafterdefcsname replicate@endcsname#1{endcsname}
longexpandafterdefcsname replicate@0endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}}
longexpandafterdefcsname replicate@1endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
longexpandafterdefcsname replicate@2endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
longexpandafterdefcsname replicate@3endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
longexpandafterdefcsname replicate@4endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
longexpandafterdefcsname replicate@5endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
longexpandafterdefcsname replicate@6endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
longexpandafterdefcsname replicate@7endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@8endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@9endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
catcode `@ = 12relax
edeftest{replicate{20}{abc}}
showtest
bye


In the expl3 version, the number#1 is (effectively) replaced by numbernumexpr#1relax, 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 `@ = 11relax
defreplicate#1{%
expandafterreplicate@auxromannumeralnumber #1000Q{}
}
defreplicate@aux#1{csname replicate@aux@#1endcsname}
longdefreplicate@aux@m#1Q#2#3{replicate@aux#1Q{#2#3}{#3}}
longdefreplicate@aux@Q#1#2{#1}
edeftest{replicate{5}{a}}
showtest
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.






share|improve this answer


























  • Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

    – Martin Scharrer
    Apr 19 '11 at 19:56











  • Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

    – Will Robertson
    Apr 20 '11 at 9:20











  • As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

    – Joseph Wright
    Apr 20 '11 at 9:28











  • The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

    – Joseph Wright
    Apr 20 '11 at 9:56






  • 2





    However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

    – Bruno Le Floch
    May 13 '11 at 8:41














29












29








29







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 `@ = 11relax
longdefreplicate#1{%
romannumeral
expandafterreplicate@first@auxnumber#1%
endcsname
}
longdefreplicate@first@aux#1{%
csname replicate@first@#1replicate@aux
}
chardefrm@end=0 %
longexpandafterdefcsname replicate@first@-endcsname
#1{rm@endNegativeReplication}
longexpandafterdefcsname replicate@first@0endcsname
#1{rm@end}
longexpandafterdefcsname replicate@first@1endcsname
#1{rm@end #1}
longexpandafterdefcsname replicate@first@2endcsname
#1{rm@end #1#1}
longexpandafterdefcsname replicate@first@3endcsname
#1{rm@end #1#1#1}
longexpandafterdefcsname replicate@first@4endcsname
#1{rm@end #1#1#1#1}
longexpandafterdefcsname replicate@first@5endcsname
#1{rm@end #1#1#1#1#1}
longexpandafterdefcsname replicate@first@6endcsname
#1{rm@end #1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@7endcsname
#1{rm@end #1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@8endcsname
#1{rm@end #1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@9endcsname
#1{rm@end #1#1#1#1#1#1#1#1#1}
defreplicate@aux#1{%
csname replicate@#1replicate@aux
}
longexpandafterdefcsname replicate@endcsname#1{endcsname}
longexpandafterdefcsname replicate@0endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}}
longexpandafterdefcsname replicate@1endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
longexpandafterdefcsname replicate@2endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
longexpandafterdefcsname replicate@3endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
longexpandafterdefcsname replicate@4endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
longexpandafterdefcsname replicate@5endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
longexpandafterdefcsname replicate@6endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
longexpandafterdefcsname replicate@7endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@8endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@9endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
catcode `@ = 12relax
edeftest{replicate{20}{abc}}
showtest
bye


In the expl3 version, the number#1 is (effectively) replaced by numbernumexpr#1relax, 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 `@ = 11relax
defreplicate#1{%
expandafterreplicate@auxromannumeralnumber #1000Q{}
}
defreplicate@aux#1{csname replicate@aux@#1endcsname}
longdefreplicate@aux@m#1Q#2#3{replicate@aux#1Q{#2#3}{#3}}
longdefreplicate@aux@Q#1#2{#1}
edeftest{replicate{5}{a}}
showtest
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.






share|improve this answer















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 `@ = 11relax
longdefreplicate#1{%
romannumeral
expandafterreplicate@first@auxnumber#1%
endcsname
}
longdefreplicate@first@aux#1{%
csname replicate@first@#1replicate@aux
}
chardefrm@end=0 %
longexpandafterdefcsname replicate@first@-endcsname
#1{rm@endNegativeReplication}
longexpandafterdefcsname replicate@first@0endcsname
#1{rm@end}
longexpandafterdefcsname replicate@first@1endcsname
#1{rm@end #1}
longexpandafterdefcsname replicate@first@2endcsname
#1{rm@end #1#1}
longexpandafterdefcsname replicate@first@3endcsname
#1{rm@end #1#1#1}
longexpandafterdefcsname replicate@first@4endcsname
#1{rm@end #1#1#1#1}
longexpandafterdefcsname replicate@first@5endcsname
#1{rm@end #1#1#1#1#1}
longexpandafterdefcsname replicate@first@6endcsname
#1{rm@end #1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@7endcsname
#1{rm@end #1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@8endcsname
#1{rm@end #1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@first@9endcsname
#1{rm@end #1#1#1#1#1#1#1#1#1}
defreplicate@aux#1{%
csname replicate@#1replicate@aux
}
longexpandafterdefcsname replicate@endcsname#1{endcsname}
longexpandafterdefcsname replicate@0endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}}
longexpandafterdefcsname replicate@1endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1}
longexpandafterdefcsname replicate@2endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1}
longexpandafterdefcsname replicate@3endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
longexpandafterdefcsname replicate@4endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
longexpandafterdefcsname replicate@5endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
longexpandafterdefcsname replicate@6endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
longexpandafterdefcsname replicate@7endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@8endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
longexpandafterdefcsname replicate@9endcsname
#1{endcsname{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
catcode `@ = 12relax
edeftest{replicate{20}{abc}}
showtest
bye


In the expl3 version, the number#1 is (effectively) replaced by numbernumexpr#1relax, 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 `@ = 11relax
defreplicate#1{%
expandafterreplicate@auxromannumeralnumber #1000Q{}
}
defreplicate@aux#1{csname replicate@aux@#1endcsname}
longdefreplicate@aux@m#1Q#2#3{replicate@aux#1Q{#2#3}{#3}}
longdefreplicate@aux@Q#1#2{#1}
edeftest{replicate{5}{a}}
showtest
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.







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 mins ago









Faheem Mitha

3,30653964




3,30653964










answered Apr 19 '11 at 19:40









Joseph WrightJoseph Wright

205k23562890




205k23562890













  • Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

    – Martin Scharrer
    Apr 19 '11 at 19:56











  • Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

    – Will Robertson
    Apr 20 '11 at 9:20











  • As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

    – Joseph Wright
    Apr 20 '11 at 9:28











  • The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

    – Joseph Wright
    Apr 20 '11 at 9:56






  • 2





    However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

    – Bruno Le Floch
    May 13 '11 at 8:41



















  • Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

    – Martin Scharrer
    Apr 19 '11 at 19:56











  • Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

    – Will Robertson
    Apr 20 '11 at 9:20











  • As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

    – Joseph Wright
    Apr 20 '11 at 9:28











  • The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

    – Joseph Wright
    Apr 20 '11 at 9:56






  • 2





    However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

    – Bruno Le Floch
    May 13 '11 at 8:41

















Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

– Martin Scharrer
Apr 19 '11 at 19:56





Ah, I should have known that LaTeX3 is having something like this. I coded something by myself and just saw your post.

– Martin Scharrer
Apr 19 '11 at 19:56













Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

– Will Robertson
Apr 20 '11 at 9:20





Note that while this seems like a overkill-approach, it should be (much?) more efficient than the simpler looping code proposed in other answers.

– Will Robertson
Apr 20 '11 at 9:20













As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

– Joseph Wright
Apr 20 '11 at 9:28





As @Will says, this approach scales well (I use it for testing purposes often with 100k repetitions).

– Joseph Wright
Apr 20 '11 at 9:28













The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

– Joseph Wright
Apr 20 '11 at 9:56





The important point to notice about the code is that it replicates for each power of ten. So as the number gets very big, rather than lots of single repetitions each 'level' requires only one pass.

– Joseph Wright
Apr 20 '11 at 9:56




2




2





However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

– Bruno Le Floch
May 13 '11 at 8:41





However, for huge number of repetitions, since all the repetitions are held in TeX's memory, we can overflow it. A solution in that case is prg_replicate:nn {10000}{prg_replicate:nn {10000}{...}}. Not needed often.

– Bruno Le Floch
May 13 '11 at 8:41











17














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 …)






share|improve this answer





















  • 4





    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








  • 1





    @MartinScharrer There’s no special reason why I used the {}. 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








  • 1





    All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

    – Martin Scharrer
    Apr 19 '11 at 21:06











  • @MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

    – Tobi
    Apr 19 '11 at 21:57











  • I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

    – Lemming
    Jul 27 '17 at 9:35
















17














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 …)






share|improve this answer





















  • 4





    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








  • 1





    @MartinScharrer There’s no special reason why I used the {}. 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








  • 1





    All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

    – Martin Scharrer
    Apr 19 '11 at 21:06











  • @MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

    – Tobi
    Apr 19 '11 at 21:57











  • I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

    – Lemming
    Jul 27 '17 at 9:35














17












17








17







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 …)






share|improve this answer















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 …)







share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 19 '11 at 20:38

























answered Apr 19 '11 at 19:19









TobiTobi

38.6k8131261




38.6k8131261








  • 4





    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








  • 1





    @MartinScharrer There’s no special reason why I used the {}. 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








  • 1





    All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

    – Martin Scharrer
    Apr 19 '11 at 21:06











  • @MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

    – Tobi
    Apr 19 '11 at 21:57











  • I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

    – Lemming
    Jul 27 '17 at 9:35














  • 4





    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








  • 1





    @MartinScharrer There’s no special reason why I used the {}. 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








  • 1





    All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

    – Martin Scharrer
    Apr 19 '11 at 21:06











  • @MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

    – Tobi
    Apr 19 '11 at 21:57











  • I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

    – Lemming
    Jul 27 '17 at 9:35








4




4





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







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






1




1





@MartinScharrer There’s no special reason why I used the {}. 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







@MartinScharrer There’s no special reason why I used the {}. 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






1




1





All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

– Martin Scharrer
Apr 19 '11 at 21:06





All assignments done in the loop will be executed in their own local group, which could have serious side effects depending on the code. Because you never known what code the user will use it is best to avoid these situations.

– Martin Scharrer
Apr 19 '11 at 21:06













@MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

– Tobi
Apr 19 '11 at 21:57





@MartinScharrer Thank’s. Maybe I remember that in case of getting problem with foreachif not I’ll be back to ask here ;-)

– Tobi
Apr 19 '11 at 21:57













I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

– Lemming
Jul 27 '17 at 9:35





I tried to place multiple tickets on a paper using the ticket package and the foreach loop. It failed. All tickets are printed at the same location.

– Lemming
Jul 27 '17 at 9:35











12














multido has a simple interface for replication:



enter image description here



documentclass{article}
usepackage{multido}
newcommand{cmd}{-x-}
newcommand{Repeat}{multido{i=1+1}}
begin{document}

Repeat{6}{cmd}
end{document}





share|improve this answer



















  • 1





    This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

    – Kpym
    Apr 29 '18 at 19:47
















12














multido has a simple interface for replication:



enter image description here



documentclass{article}
usepackage{multido}
newcommand{cmd}{-x-}
newcommand{Repeat}{multido{i=1+1}}
begin{document}

Repeat{6}{cmd}
end{document}





share|improve this answer



















  • 1





    This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

    – Kpym
    Apr 29 '18 at 19:47














12












12








12







multido has a simple interface for replication:



enter image description here



documentclass{article}
usepackage{multido}
newcommand{cmd}{-x-}
newcommand{Repeat}{multido{i=1+1}}
begin{document}

Repeat{6}{cmd}
end{document}





share|improve this answer













multido has a simple interface for replication:



enter image description here



documentclass{article}
usepackage{multido}
newcommand{cmd}{-x-}
newcommand{Repeat}{multido{i=1+1}}
begin{document}

Repeat{6}{cmd}
end{document}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 '14 at 6:52









WernerWerner

449k719941699




449k719941699








  • 1





    This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

    – Kpym
    Apr 29 '18 at 19:47














  • 1





    This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

    – Kpym
    Apr 29 '18 at 19:47








1




1





This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

– Kpym
Apr 29 '18 at 19:47





This is an old answer, but I want just to mention that i=1+1 is useless here, newcommand{Repeat}{multido{}} is enough.

– Kpym
Apr 29 '18 at 19:47











7














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@Repeatexpandafter{thenumexpr #1relax}%
}

def@Repeat#1{%
ifnum#1>0
expandafter@@Repeatexpandafter{thenumexpr #1-1expandafterrelaxexpandafter}%
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 }

edefTEST{Repeat{5}{test }}
texttt{meaningTEST}

end{document}





share|improve this answer
























  • If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

    – Joseph Wright
    Apr 19 '11 at 20:33











  • @Joseph: I have a really hard time reading the 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 7:42











  • @TH. The 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 8:09











  • @TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

    – Joseph Wright
    Apr 20 '11 at 8:34











  • @Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

    – TH.
    Apr 20 '11 at 8:49
















7














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@Repeatexpandafter{thenumexpr #1relax}%
}

def@Repeat#1{%
ifnum#1>0
expandafter@@Repeatexpandafter{thenumexpr #1-1expandafterrelaxexpandafter}%
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 }

edefTEST{Repeat{5}{test }}
texttt{meaningTEST}

end{document}





share|improve this answer
























  • If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

    – Joseph Wright
    Apr 19 '11 at 20:33











  • @Joseph: I have a really hard time reading the 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 7:42











  • @TH. The 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 8:09











  • @TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

    – Joseph Wright
    Apr 20 '11 at 8:34











  • @Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

    – TH.
    Apr 20 '11 at 8:49














7












7








7







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@Repeatexpandafter{thenumexpr #1relax}%
}

def@Repeat#1{%
ifnum#1>0
expandafter@@Repeatexpandafter{thenumexpr #1-1expandafterrelaxexpandafter}%
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 }

edefTEST{Repeat{5}{test }}
texttt{meaningTEST}

end{document}





share|improve this answer













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@Repeatexpandafter{thenumexpr #1relax}%
}

def@Repeat#1{%
ifnum#1>0
expandafter@@Repeatexpandafter{thenumexpr #1-1expandafterrelaxexpandafter}%
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 }

edefTEST{Repeat{5}{test }}
texttt{meaningTEST}

end{document}






share|improve this answer












share|improve this answer



share|improve this answer










answered Apr 19 '11 at 19:55









Martin ScharrerMartin Scharrer

203k47651825




203k47651825













  • If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

    – Joseph Wright
    Apr 19 '11 at 20:33











  • @Joseph: I have a really hard time reading the 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 7:42











  • @TH. The 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 8:09











  • @TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

    – Joseph Wright
    Apr 20 '11 at 8:34











  • @Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

    – TH.
    Apr 20 '11 at 8:49



















  • If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

    – Joseph Wright
    Apr 19 '11 at 20:33











  • @Joseph: I have a really hard time reading the 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 7:42











  • @TH. The 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 8:09











  • @TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

    – Joseph Wright
    Apr 20 '11 at 8:34











  • @Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

    – TH.
    Apr 20 '11 at 8:49

















If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

– Joseph Wright
Apr 19 '11 at 20:33





If you look at the LaTeX3 implementation, it's expandable even without needing e-TeX. This is some clever code that has been around for many years.

– Joseph Wright
Apr 19 '11 at 20:33













@Joseph: I have a really hard time reading the 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 7:42





@Joseph: I have a really hard time reading the 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 7:42













@TH. The 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 8:09





@TH. The 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 8:09













@TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

– Joseph Wright
Apr 20 '11 at 8:34





@TH. I've added the plain TeX code to my answer, avoiding e-TeX but explaining why it is used for the expl3 version.

– Joseph Wright
Apr 20 '11 at 8:34













@Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

– TH.
Apr 20 '11 at 8:49





@Joseph: I see now, that's very clever! Thanks. (One of these days, I really just need to learn expl3.)

– TH.
Apr 20 '11 at 8:49











6














Plain and simple (pun intended):



deffoo{keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 #2repeat}
bar3foo % results in kekekekekeke
bye


Token list registers expand more quickly, so if it suits you, you could also do:



newtoksfoo foo={keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 the#2repeat}
bar3foo % results in kekekekekeke
bye


Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):



deffoo{keke}
defgobbleone#1{}
longdefreplicate#1#2{%
ifnumnumexpr#1>0
#2expandafterreplicateexpandafter
{numbernumexpr#1-1expandafter}%
else
expandaftergobbleone
fi{#2}}
replicate3foo % results in kekekekekeke
bye





share|improve this answer


























  • Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

    – Martin Scharrer
    Apr 19 '11 at 20:54













  • What does it mean not being expandable?

    – Christian Lindig
    Apr 20 '11 at 5:52











  • Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

    – morbusg
    Apr 20 '11 at 7:06






  • 1





    @Christian: Something is expandable if you can use it inside an 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 7:06











  • @Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

    – Joseph Wright
    Apr 20 '11 at 7:08
















6














Plain and simple (pun intended):



deffoo{keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 #2repeat}
bar3foo % results in kekekekekeke
bye


Token list registers expand more quickly, so if it suits you, you could also do:



newtoksfoo foo={keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 the#2repeat}
bar3foo % results in kekekekekeke
bye


Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):



deffoo{keke}
defgobbleone#1{}
longdefreplicate#1#2{%
ifnumnumexpr#1>0
#2expandafterreplicateexpandafter
{numbernumexpr#1-1expandafter}%
else
expandaftergobbleone
fi{#2}}
replicate3foo % results in kekekekekeke
bye





share|improve this answer


























  • Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

    – Martin Scharrer
    Apr 19 '11 at 20:54













  • What does it mean not being expandable?

    – Christian Lindig
    Apr 20 '11 at 5:52











  • Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

    – morbusg
    Apr 20 '11 at 7:06






  • 1





    @Christian: Something is expandable if you can use it inside an 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 7:06











  • @Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

    – Joseph Wright
    Apr 20 '11 at 7:08














6












6








6







Plain and simple (pun intended):



deffoo{keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 #2repeat}
bar3foo % results in kekekekekeke
bye


Token list registers expand more quickly, so if it suits you, you could also do:



newtoksfoo foo={keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 the#2repeat}
bar3foo % results in kekekekekeke
bye


Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):



deffoo{keke}
defgobbleone#1{}
longdefreplicate#1#2{%
ifnumnumexpr#1>0
#2expandafterreplicateexpandafter
{numbernumexpr#1-1expandafter}%
else
expandaftergobbleone
fi{#2}}
replicate3foo % results in kekekekekeke
bye





share|improve this answer















Plain and simple (pun intended):



deffoo{keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 #2repeat}
bar3foo % results in kekekekekeke
bye


Token list registers expand more quickly, so if it suits you, you could also do:



newtoksfoo foo={keke}
defbar#1#2{count0=#1 loop ifnumcount0>0 advancecount0 by -1 the#2repeat}
bar3foo % results in kekekekekeke
bye


Repeating in an expendable way using e-tex additions (from http://www.tug.org/TUGboat/tb29-2/tb92jackowski.pdf):



deffoo{keke}
defgobbleone#1{}
longdefreplicate#1#2{%
ifnumnumexpr#1>0
#2expandafterreplicateexpandafter
{numbernumexpr#1-1expandafter}%
else
expandaftergobbleone
fi{#2}}
replicate3foo % results in kekekekekeke
bye






share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 20 '11 at 7:45

























answered Apr 19 '11 at 20:27









morbusgmorbusg

20.3k362138




20.3k362138













  • Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

    – Martin Scharrer
    Apr 19 '11 at 20:54













  • What does it mean not being expandable?

    – Christian Lindig
    Apr 20 '11 at 5:52











  • Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

    – morbusg
    Apr 20 '11 at 7:06






  • 1





    @Christian: Something is expandable if you can use it inside an 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 7:06











  • @Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

    – Joseph Wright
    Apr 20 '11 at 7:08



















  • Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

    – Martin Scharrer
    Apr 19 '11 at 20:54













  • What does it mean not being expandable?

    – Christian Lindig
    Apr 20 '11 at 5:52











  • Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

    – morbusg
    Apr 20 '11 at 7:06






  • 1





    @Christian: Something is expandable if you can use it inside an 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 7:06











  • @Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

    – Joseph Wright
    Apr 20 '11 at 7:08

















Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

– Martin Scharrer
Apr 19 '11 at 20:54







Yes, but not expandable. Ok, it isn't really necessary in the majority of the cases.

– Martin Scharrer
Apr 19 '11 at 20:54















What does it mean not being expandable?

– Christian Lindig
Apr 20 '11 at 5:52





What does it mean not being expandable?

– Christian Lindig
Apr 20 '11 at 5:52













Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

– morbusg
Apr 20 '11 at 7:06





Christian forgot to notify @Martin I guess, since I don't know the answer to that question.

– morbusg
Apr 20 '11 at 7:06




1




1





@Christian: Something is expandable if you can use it inside an 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 7:06





@Christian: Something is expandable if you can use it inside an 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 7:06













@Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

– Joseph Wright
Apr 20 '11 at 7:08





@Christian: I thought that the general question had been asked, but cannot find it. You might wish to ask about expandability in general, and those of us who understand it can try to explain!

– Joseph Wright
Apr 20 '11 at 7:08











4














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:



defreplicate#1{expandafterrepUexpandafter{romannumeralnumber#1000}}
defrepU#1#2{repV{#2}#1;}
defrepV#1#2{ifx#2;else#1fihererepV{#1}fi}
deffihere#1fi{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:



defreplicate#1{expandafterrepAnumber#1;;}
defrepA#1#2;#3;{ifx;#2;repB#1#3fi repA#2;#1#3;}
defrepB#1fi#2;#3;{firepC{#1}}
defrepC#1#2{repD{#2}#1;}
defrepD#1#2{ifx#2;else repE{#1}#2fi}
defrepE#1#2fi{fi repF#2{#1}repD{repF{10}{#1}}}
defrepF#1#2{ifcase#1 or#2or#2#2or#2#2#2or#2#2#2#2or#2#2#2#2#2or
#2#2#2#2#2#2or#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2or
#2#2#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2#2#2fi}

message{replicate{27}{abc}}
bye





share|improve this answer


























  • My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

    – Joseph Wright
    Mar 21 '16 at 10:20











  • nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

    – user4686
    Mar 22 '16 at 22:24
















4














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:



defreplicate#1{expandafterrepUexpandafter{romannumeralnumber#1000}}
defrepU#1#2{repV{#2}#1;}
defrepV#1#2{ifx#2;else#1fihererepV{#1}fi}
deffihere#1fi{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:



defreplicate#1{expandafterrepAnumber#1;;}
defrepA#1#2;#3;{ifx;#2;repB#1#3fi repA#2;#1#3;}
defrepB#1fi#2;#3;{firepC{#1}}
defrepC#1#2{repD{#2}#1;}
defrepD#1#2{ifx#2;else repE{#1}#2fi}
defrepE#1#2fi{fi repF#2{#1}repD{repF{10}{#1}}}
defrepF#1#2{ifcase#1 or#2or#2#2or#2#2#2or#2#2#2#2or#2#2#2#2#2or
#2#2#2#2#2#2or#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2or
#2#2#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2#2#2fi}

message{replicate{27}{abc}}
bye





share|improve this answer


























  • My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

    – Joseph Wright
    Mar 21 '16 at 10:20











  • nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

    – user4686
    Mar 22 '16 at 22:24














4












4








4







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:



defreplicate#1{expandafterrepUexpandafter{romannumeralnumber#1000}}
defrepU#1#2{repV{#2}#1;}
defrepV#1#2{ifx#2;else#1fihererepV{#1}fi}
deffihere#1fi{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:



defreplicate#1{expandafterrepAnumber#1;;}
defrepA#1#2;#3;{ifx;#2;repB#1#3fi repA#2;#1#3;}
defrepB#1fi#2;#3;{firepC{#1}}
defrepC#1#2{repD{#2}#1;}
defrepD#1#2{ifx#2;else repE{#1}#2fi}
defrepE#1#2fi{fi repF#2{#1}repD{repF{10}{#1}}}
defrepF#1#2{ifcase#1 or#2or#2#2or#2#2#2or#2#2#2#2or#2#2#2#2#2or
#2#2#2#2#2#2or#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2or
#2#2#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2#2#2fi}

message{replicate{27}{abc}}
bye





share|improve this answer















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:



defreplicate#1{expandafterrepUexpandafter{romannumeralnumber#1000}}
defrepU#1#2{repV{#2}#1;}
defrepV#1#2{ifx#2;else#1fihererepV{#1}fi}
deffihere#1fi{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:



defreplicate#1{expandafterrepAnumber#1;;}
defrepA#1#2;#3;{ifx;#2;repB#1#3fi repA#2;#1#3;}
defrepB#1fi#2;#3;{firepC{#1}}
defrepC#1#2{repD{#2}#1;}
defrepD#1#2{ifx#2;else repE{#1}#2fi}
defrepE#1#2fi{fi repF#2{#1}repD{repF{10}{#1}}}
defrepF#1#2{ifcase#1 or#2or#2#2or#2#2#2or#2#2#2#2or#2#2#2#2#2or
#2#2#2#2#2#2or#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2or
#2#2#2#2#2#2#2#2#2or#2#2#2#2#2#2#2#2#2#2fi}

message{replicate{27}{abc}}
bye






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 21 '16 at 10:06

























answered Mar 21 '16 at 9:57









wipetwipet

35.3k4983




35.3k4983













  • My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

    – Joseph Wright
    Mar 21 '16 at 10:20











  • nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

    – user4686
    Mar 22 '16 at 22:24



















  • My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

    – Joseph Wright
    Mar 21 '16 at 10:20











  • nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

    – user4686
    Mar 22 '16 at 22:24

















My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

– Joseph Wright
Mar 21 '16 at 10:20





My comment about eTeX was probably misleading: I've removed it (you need eTeX if you want to accept integer expressions for the number of repeats, not for the core idea of making copies).

– Joseph Wright
Mar 21 '16 at 10:20













nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

– user4686
Mar 22 '16 at 22:24





nice but it should be pointed out this doesn't expand fully under romannumeral-`0.

– user4686
Mar 22 '16 at 22:24











2














Here is an example with loop and newcommand:



documentclass{article}
newcounter{z}
newcommandy[2]{
loop ifnumvalue{z} < #1
#2%
stepcounter{z}%
repeat
}
begin{document}
y{10}{Hello}
end{document}





share|improve this answer


























  • The request is to repeat a command

    – Andrew Swann
    Mar 20 '16 at 15:11











  • Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

    – Andrew Swann
    Mar 20 '16 at 15:23











  • Isn't this the same as the first suggestion in @morbusg's answer?

    – clemens
    Mar 20 '16 at 15:27
















2














Here is an example with loop and newcommand:



documentclass{article}
newcounter{z}
newcommandy[2]{
loop ifnumvalue{z} < #1
#2%
stepcounter{z}%
repeat
}
begin{document}
y{10}{Hello}
end{document}





share|improve this answer


























  • The request is to repeat a command

    – Andrew Swann
    Mar 20 '16 at 15:11











  • Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

    – Andrew Swann
    Mar 20 '16 at 15:23











  • Isn't this the same as the first suggestion in @morbusg's answer?

    – clemens
    Mar 20 '16 at 15:27














2












2








2







Here is an example with loop and newcommand:



documentclass{article}
newcounter{z}
newcommandy[2]{
loop ifnumvalue{z} < #1
#2%
stepcounter{z}%
repeat
}
begin{document}
y{10}{Hello}
end{document}





share|improve this answer















Here is an example with loop and newcommand:



documentclass{article}
newcounter{z}
newcommandy[2]{
loop ifnumvalue{z} < #1
#2%
stepcounter{z}%
repeat
}
begin{document}
y{10}{Hello}
end{document}






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 21 '16 at 3:39

























answered Mar 20 '16 at 15:04









Steven PennySteven Penny

1




1













  • The request is to repeat a command

    – Andrew Swann
    Mar 20 '16 at 15:11











  • Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

    – Andrew Swann
    Mar 20 '16 at 15:23











  • Isn't this the same as the first suggestion in @morbusg's answer?

    – clemens
    Mar 20 '16 at 15:27



















  • The request is to repeat a command

    – Andrew Swann
    Mar 20 '16 at 15:11











  • Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

    – Andrew Swann
    Mar 20 '16 at 15:23











  • Isn't this the same as the first suggestion in @morbusg's answer?

    – clemens
    Mar 20 '16 at 15:27

















The request is to repeat a command

– Andrew Swann
Mar 20 '16 at 15:11





The request is to repeat a command

– Andrew Swann
Mar 20 '16 at 15:11













Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

– Andrew Swann
Mar 20 '16 at 15:23





Only the simplest commands - e.g. if the new command defines other commands the grouping is not equivalent.

– Andrew Swann
Mar 20 '16 at 15:23













Isn't this the same as the first suggestion in @morbusg's answer?

– clemens
Mar 20 '16 at 15:27





Isn't this the same as the first suggestion in @morbusg's answer?

– clemens
Mar 20 '16 at 15:27











2














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 thenumexpr 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 chardefz@=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

defJFsignfork #10-#2#3krof {#2}
%chardefz@ 0 % NO! z@ is a dimen in TeX/LaTeX

defJFrep #1{romannumeralexpandafterJFrep@athenumexpr #1;3456789XY!}%
defJFrep@a #1{JFsignfork
#1-JFrep@nil
0#1JFrep@neg
0-JFrep@b
krof #1%
}%
longdefJFrep@nil #1!#2{z@}
longdefJFrep@neg #1!#2{z@NegativeReplication}

% TeX numbers have at most 10 digits
defJFrep@b #1#2#3#4#5#6#7#8#9{JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
defJFrep@c #1#2#3#4!{JFrep@d .#3.#2#1!}
defJFrep@d #1;#2#3{csname JFrep@f#2#3endcsname}
longexpandafterdefcsname JFrep@f.0endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
longexpandafterdefcsname JFrep@f.1endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
longexpandafterdefcsname JFrep@f.2endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
longexpandafterdefcsname JFrep@f.3endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
longexpandafterdefcsname JFrep@f.4endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
longexpandafterdefcsname JFrep@f.5endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.6endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.7endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.8endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.9endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f;1endcsname!#1{z@#1}%
longexpandafterdefcsname JFrep@f;2endcsname!#1{z@#1#1}%
longexpandafterdefcsname JFrep@f;3endcsname!#1{z@#1#1#1}%
longexpandafterdefcsname JFrep@f;4endcsname!#1{z@#1#1#1#1}%
longexpandafterdefcsname JFrep@f;5endcsname!#1{z@#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;6endcsname!#1{z@#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;7endcsname!#1{z@#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;8endcsname!#1{z@#1#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;9endcsname!#1{z@#1#1#1#1#1#1#1#1#1}%

catcode`@ 12

edeftest{JFrep{123}{abc}}
showtest

bye





share|improve this answer


























  • There is now an 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...

    – user4686
    Apr 29 '18 at 20:26
















2














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 thenumexpr 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 chardefz@=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

defJFsignfork #10-#2#3krof {#2}
%chardefz@ 0 % NO! z@ is a dimen in TeX/LaTeX

defJFrep #1{romannumeralexpandafterJFrep@athenumexpr #1;3456789XY!}%
defJFrep@a #1{JFsignfork
#1-JFrep@nil
0#1JFrep@neg
0-JFrep@b
krof #1%
}%
longdefJFrep@nil #1!#2{z@}
longdefJFrep@neg #1!#2{z@NegativeReplication}

% TeX numbers have at most 10 digits
defJFrep@b #1#2#3#4#5#6#7#8#9{JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
defJFrep@c #1#2#3#4!{JFrep@d .#3.#2#1!}
defJFrep@d #1;#2#3{csname JFrep@f#2#3endcsname}
longexpandafterdefcsname JFrep@f.0endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
longexpandafterdefcsname JFrep@f.1endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
longexpandafterdefcsname JFrep@f.2endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
longexpandafterdefcsname JFrep@f.3endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
longexpandafterdefcsname JFrep@f.4endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
longexpandafterdefcsname JFrep@f.5endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.6endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.7endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.8endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.9endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f;1endcsname!#1{z@#1}%
longexpandafterdefcsname JFrep@f;2endcsname!#1{z@#1#1}%
longexpandafterdefcsname JFrep@f;3endcsname!#1{z@#1#1#1}%
longexpandafterdefcsname JFrep@f;4endcsname!#1{z@#1#1#1#1}%
longexpandafterdefcsname JFrep@f;5endcsname!#1{z@#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;6endcsname!#1{z@#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;7endcsname!#1{z@#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;8endcsname!#1{z@#1#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;9endcsname!#1{z@#1#1#1#1#1#1#1#1#1}%

catcode`@ 12

edeftest{JFrep{123}{abc}}
showtest

bye





share|improve this answer


























  • There is now an 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...

    – user4686
    Apr 29 '18 at 20:26














2












2








2







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 thenumexpr 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 chardefz@=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

defJFsignfork #10-#2#3krof {#2}
%chardefz@ 0 % NO! z@ is a dimen in TeX/LaTeX

defJFrep #1{romannumeralexpandafterJFrep@athenumexpr #1;3456789XY!}%
defJFrep@a #1{JFsignfork
#1-JFrep@nil
0#1JFrep@neg
0-JFrep@b
krof #1%
}%
longdefJFrep@nil #1!#2{z@}
longdefJFrep@neg #1!#2{z@NegativeReplication}

% TeX numbers have at most 10 digits
defJFrep@b #1#2#3#4#5#6#7#8#9{JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
defJFrep@c #1#2#3#4!{JFrep@d .#3.#2#1!}
defJFrep@d #1;#2#3{csname JFrep@f#2#3endcsname}
longexpandafterdefcsname JFrep@f.0endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
longexpandafterdefcsname JFrep@f.1endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
longexpandafterdefcsname JFrep@f.2endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
longexpandafterdefcsname JFrep@f.3endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
longexpandafterdefcsname JFrep@f.4endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
longexpandafterdefcsname JFrep@f.5endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.6endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.7endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.8endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.9endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f;1endcsname!#1{z@#1}%
longexpandafterdefcsname JFrep@f;2endcsname!#1{z@#1#1}%
longexpandafterdefcsname JFrep@f;3endcsname!#1{z@#1#1#1}%
longexpandafterdefcsname JFrep@f;4endcsname!#1{z@#1#1#1#1}%
longexpandafterdefcsname JFrep@f;5endcsname!#1{z@#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;6endcsname!#1{z@#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;7endcsname!#1{z@#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;8endcsname!#1{z@#1#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;9endcsname!#1{z@#1#1#1#1#1#1#1#1#1}%

catcode`@ 12

edeftest{JFrep{123}{abc}}
showtest

bye





share|improve this answer















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 thenumexpr 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 chardefz@=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

defJFsignfork #10-#2#3krof {#2}
%chardefz@ 0 % NO! z@ is a dimen in TeX/LaTeX

defJFrep #1{romannumeralexpandafterJFrep@athenumexpr #1;3456789XY!}%
defJFrep@a #1{JFsignfork
#1-JFrep@nil
0#1JFrep@neg
0-JFrep@b
krof #1%
}%
longdefJFrep@nil #1!#2{z@}
longdefJFrep@neg #1!#2{z@NegativeReplication}

% TeX numbers have at most 10 digits
defJFrep@b #1#2#3#4#5#6#7#8#9{JFrep@c {.#9.#8.#7.#6.#5.#4.#3.#2;#1}}
defJFrep@c #1#2#3#4!{JFrep@d .#3.#2#1!}
defJFrep@d #1;#2#3{csname JFrep@f#2#3endcsname}
longexpandafterdefcsname JFrep@f.0endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}}%
longexpandafterdefcsname JFrep@f.1endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4}%
longexpandafterdefcsname JFrep@f.2endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4}%
longexpandafterdefcsname JFrep@f.3endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4}%
longexpandafterdefcsname JFrep@f.4endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4}%
longexpandafterdefcsname JFrep@f.5endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.6endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.7endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.8endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f.9endcsname #1#2#3!#4%
{csname JFrep@f#1#2endcsname#3!{#4#4#4#4#4#4#4#4#4#4}#4#4#4#4#4#4#4#4#4}%
longexpandafterdefcsname JFrep@f;1endcsname!#1{z@#1}%
longexpandafterdefcsname JFrep@f;2endcsname!#1{z@#1#1}%
longexpandafterdefcsname JFrep@f;3endcsname!#1{z@#1#1#1}%
longexpandafterdefcsname JFrep@f;4endcsname!#1{z@#1#1#1#1}%
longexpandafterdefcsname JFrep@f;5endcsname!#1{z@#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;6endcsname!#1{z@#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;7endcsname!#1{z@#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;8endcsname!#1{z@#1#1#1#1#1#1#1#1}%
longexpandafterdefcsname JFrep@f;9endcsname!#1{z@#1#1#1#1#1#1#1#1#1}%

catcode`@ 12

edeftest{JFrep{123}{abc}}
showtest

bye






share|improve this answer














share|improve this answer



share|improve this answer








edited Apr 13 '17 at 12:34









Community

1




1










answered Mar 23 '16 at 11:47







user4686




















  • There is now an 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...

    – user4686
    Apr 29 '18 at 20:26



















  • There is now an 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...

    – user4686
    Apr 29 '18 at 20:26

















There is now an 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...

– user4686
Apr 29 '18 at 20:26





There is now an 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...

– user4686
Apr 29 '18 at 20:26


















draft saved

draft discarded




















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f16189%2frepeat-command-n-times%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

El tren de la libertad Índice Antecedentes "Porque yo decido" Desarrollo de la...

Castillo d'Acher Características Menú de navegación

Connecting two nodes from the same mother node horizontallyTikZ: What EXACTLY does the the |- notation for...