Repeating a command n times

O TeX não foi projetado como uma linguagem de programação, mas há ocasiões em que você deseja repetir alguma parte de seu documento, do mesmo modo que partes de programas precisam ser executadas várias vezes. Um exemplo óbvio é desenho baseado em TeX: o ambiente picture do LaTeX e o pgf ((pelo menos) fornecem facilidades para repetições — elas são úteis para desenhar padrões que se repetem. Consequentemente, técnicas “comuns” de programação geralmente precisam ser emuladas pelo uso de obscuras “TeXniques” de macro.

Essa resposta aborda a repetição de uma operação um determinado número de vezes; a repetição de operações uma vez para cada objeto de um conjunto é tratada na resposta Repetir algo para cada ‘coisa’ de um conjunto.

O próprio Plain TeX fornece um construto \loop\repeat , que permite que você repita um comando (ou conjunto de comandos). A sintaxe é bastante simples, mas seu uso de condicionais do TeX é diferente o suficiente para que muitas pessoas achem confuso.

\newcount\foo
\foo=10
\loop
  \message{\the\foo}
  \advance \foo -1
\ifnum \foo>0
\repeat
Nesse código ligeiramente complicado, \loop inicia a construto terminado em \repeat, mas \repeat também “serve como” o \fi para o \ifnum. O loop acima imprime os números de 10 a 1 via \message do TeX (isto é, na saída do console).

O pacote multido também é “genérico” (pode ser usado no Plain TeX e no latex[[[LBRACE]]][[[RBRACE]]]); ele define o comando \multido com três argumentos:

\multido{‹variables›}{‹repetitions›}{‹stuff to repeat›}
Quando a macro estiver sendo executada, ‹coisas a repetir› serão executadas ‹repetições› vezes; ‹variáveis› fornece uma lista de variáveis que podem ser usadas nas ‹coisas a repetir›. Cada variável é um composto de uma sequência de comandos e como ela varia; assim, uma variável “\iz=2+4” define \iz como 2 na primeira vez, depois 6 e 10 nas duas repetições seguintes, e assim por diante. (A variável \iz é um número inteiro; variáveis com outras letras iniciais representam diferentes tipos de dados.)

Tanto o LaTeX atual quanto o LaTeX3 (experimental) possuem comandos de iteração para uso interno e para escritores de pacotes; o uso deles é provavelmente não recomendável.

O pacote ifthen da distribuição do LaTeX oferece a macro \whiledo:

\newcounter{ct}
...
\setcounter{ct}{1}
\whiledo {\value{ct} < 5}%
{%
  \thect\
  \stepcounter {ct}%
}

O pacote forloop fornece o \forloop e nada mais:

\newcounter{ct}
...
\forloop{ct}{1}{\value{ct} < 5}%
{%
  \thect\
}
Como se pode ver, os argumentos são contador, valor inicial e condição para terminar; um argumento opcional fornece um valor de incremento (o incremento ‘default’ é 1).

O ambiente picture do LaTeX tem um comando simples para desenho repetido:

\multiput(x,y)(xstep,ystep){n}{obj}
que coloca o ‹obj› (parte de uma figura) ‹n› vezes nas posições (‹x›, ‹y›), (‹x›+‹xstep›, ‹y›+‹ystep›), (‹x›+2‹xstep›, ‹y›+2‹ystep›), e assim por diante, adicionando o deslocamento novamente a cada vez. O comando foi criado para ser usado no picture, mas ele não faz qualquer verificação, podendo até ser usado para produzir uma composição excêntrica de uma frase “normal”, tal como:
Here \multiput(0,0)(1,1){3}{we} are again.
com efeito previsível (se não realmente desejável). Ele pode ser usado com nada além de um cálculo iterativo no argumento entre chaves, caso em que suas capacidades gráficas não têm efeito.

O pacote pgffor , que faz parte da pgf distribuição, também fornece iterações para suportar as necessidades de gráficos. Sua sintaxe é no estilo das linguagens de programação comuns:

\usepackage{pgffor}
\newcommand{\cmd}{-x-}
...
\foreach \n in {1,...,4}{\cmd{}}
escreve “-x--x--x--x-

O comando \foreach tem a potencial desvantagem de que sua unidade repetida seja executada em um grupo, de modo que quaisquer cálculos feitos dentro do loop sejam perdidos (a menos que seu resultado seja tornado \global); no entanto, ele não “incorpora” suas origens gráficas (como o \multiput faz), razão pela qual seu potencial é mais evidente fora de sua própria “casa” do ambiente gráfico. %

% \input repeat
% \newcount\foo
% \repeat
%   \for{foo} \from{1} \to{10} \do{x*}
% 
%
% \repeat
%   \for{var}
%     \from{} \by{} \to{}
%     \downto{} \until{} \while{}
% \do{}
% 

forarray.sty
forarray
forloop.sty
forloop
ifthen.sty
Distributed as part of latex
multido.sty
multido
pgffor.sty
Distributed as part of pgf

This answer last edited: 2013-03-01


Do you have any question? Ask on: latex.net.br - we love qood questions!