Comment répéter une commande N fois ?#

n’a pas été conçu comme un langage de programmation, mais il arrive de vouloir répéter une partie d’un document, tout comme certaines parties de programmes doivent être exécutées plusieurs fois. La conception de schémas est un exemple évident. Dans l’exemple ci-dessous, vous n’avez évidemment pas envie de répéter manuellement le dessin de chaque graduation sur l’axe, alors que l’ordinateur saurait très bien le faire pour vous :

\documentclass[french]{article}
  \usepackage[T1]{fontenc}    % Encodage T1 (adapté au français)
  \usepackage{lmodern}        % Caractères plus lisibles
  \usepackage{babel}          % Réglages linguistiques (avec french)
  \pagestyle{empty}           % N'affiche pas de numéro de page
  \usepackage{tikz}

\begin{document}
\begin{tikzpicture}
\draw[line width=.8pt,->] (0cm,0pt) -- ++(5.5cm,0pt) ;
\foreach \x in {0,0.5,...,5.0} \draw (\x cm,4pt) -- (\x cm,-4pt)
node[anchor=north,font=\footnotesize\it] {\x} ;
\end{tikzpicture}
\end{document}

Donc, tout naturellement, l’environnement picture de et PGF (notamment) fournissent des fonctions pour répéter des actions. Même en dehors du contexte de dessin, il est souvent plus simple d’utiliser ces fonctionnalités, plutôt que de les réimplémenter à l’aide d’obscures commandes niques.

Cette réponse traite de la répétition d’une opération un nombre donné de fois ; si vous souhaitez exécuter une action pour chaque élément d’une liste d’objets, lisez plutôt la réponse à la question « Comment répéter une action pour chaque élément d’un ensemble ? ».

1.  En Plain #

Plain fournit lui-même une structure \loop … \repeat, qui permet de répéter une commande (ou un ensemble de commandes). La syntaxe est relativement simple, mais l’utilisation des structures conditionnelles de est assez inhabituelle, ce qui fait que beaucoup de personnes la trouvent déroutante.

Voici un exemple :

\newcount\foo
\foo=10
\loop
  \message{\the\foo}
  \advance \foo -1
\ifnum \foo>0
\repeat

Dans ce code un peu intrigant, \loop démarre la boucle terminée par \repeat, en même temps, \repeat tient également lieu de \fi pour le \ifnum. La boucle ci-dessus imprime donc les nombres de 10 à 1 dans le terminal, en utilisant la primitive \message.

2.  Avec l’extension multido#

À faire

Activer l’exemple

L’extension multido est également « générique » (ie utilisable aussi bien avec Plain que ) ; elle définit une commande \multido prenant trois arguments :

  \multido{⟨variables⟩}{⟨répétitions⟩}{⟨choses à répéter⟩}

Lorsque la commande s’exécute, les ⟨choses à répéter⟩ sont exécutées ⟨répétitions⟩ fois ; l’argument ⟨variables⟩ donne une liste de variables qui peuvent être utilisées dans les ⟨choses à répéter⟩. Chaque variable est composée d’une suite de commandes et de la façon dont elle varie ; ainsi, la valeur \iz=2+4 définirait la variable \iz à 2 la première fois, puis à 6 et 10 lors des deux itérations suivantes, et ainsi de suite. (Si le nom de la variable commence par un i, comme \iz, elle représente un nombre entier ; les autres lettres initiales représentent d’autres types de données).

dans sa version actuelle, ainsi que (expérimental), comportent tous deux des commandes d’itération pour leur usage interne, utilisables par les auteurs d’extensions ; cependant leur utilisation dans un document n’est pas recommandée.

3.  Avec l’extension ifthen#

L’extension ifthen, fournie avec propose la macro \whiledo :

\documentclass[french]{article}
  \usepackage[T1]{fontenc}    % Encodage T1 (adapté au français)
  \usepackage{lmodern}        % Caractères plus lisibles
  \usepackage{babel}          % Réglages linguistiques (avec french)
  \pagestyle{empty}           % N'affiche pas de numéro de page
  \usepackage{ifthen}

\begin{document}
Comptons un peu :%
\newcounter{ct}
\setcounter{ct}{1}
\whiledo {\value{ct} < 5}%
{%
  \thect, 
  \stepcounter {ct}%
}%
5.
\end{document}

4.  Avec l’extension forloop#

L’extension forloop propose une unique macro, \forloop :

\documentclass[french]{article}
  \usepackage[T1]{fontenc}    % Encodage T1 (adapté au français)
  \usepackage{lmodern}        % Caractères plus lisibles
  \usepackage{babel}          % Réglages linguistiques (avec french)
  \pagestyle{empty}           % N'affiche pas de numéro de page
  \usepackage{forloop}

\begin{document}
Comptons un peu : 
\newcounter{ct}
\forloop{ct}{1}{\value{ct} < 5}%
{%
  \thect,
}%
5.
\end{document}

Comme vous pouvez le voir, les arguments sont le compteur, la valeur de départ et la condition de fin ; un argument facultatif fournit une valeur d’incrément (l’incrément par défaut est de 1).

5.  Avec l’environnement picture#

L’environnement picture de possède une commande simple pour répéter des opérations dans un dessin :

\multiput(⟨x⟩,⟨y⟩)(⟨xstep⟩,⟨xstep⟩){⟨n⟩}{⟨obj⟩}

qui place ⟨obj⟩ (par exemple un élément d’une image) ⟨n⟩ fois aux positions

  • (⟨x⟩, ⟨y⟩) ;

  • (⟨x⟩ + ⟨xstep⟩, ⟨y⟩ + ⟨ystep⟩) ;

  • (⟨x⟩ + 2 ⟨xstep⟩, ⟨y⟩ + 2 ⟨ystep⟩) ;

  • et ainsi de suite ;

en ajoutant à chaque fois le déplacement (⟨xstep⟩, ⟨ystep⟩). Cette commande a été conçue pour être utilisée dans un evironnement picture, mais elle ne fait aucun contrôle particulier pour ça, et peut tout à fait être utilisée dans du texte ordinaire, par exemple (peu pratique) :

\documentclass[french]{article}
  \usepackage[T1]{fontenc}    % Encodage T1 (adapté au français)
  \usepackage{lmodern}        % Caractères plus lisibles
  \usepackage{babel}          % Réglages linguistiques (avec french)
  \pagestyle{empty}           % N'affiche pas de numéro de page

\begin{document}
Et nous \multiput(0,0)(2,3){3}{re}voilà !
\end{document}

Elle peut être utilisé avec un simple calcul itératif dans son dernier argument, auquel cas ses capacités graphiques n’ont aucun effet.

6.  Avec l’extension pgffor#

L’extension pgffor, qui fait partie de PGF, fournit également de quoi faire des itérations pour répondre aux besoins des graphiques. Sa syntaxe reprend le style des langages de programmation courants :

\documentclass[french]{article}
  \usepackage[T1]{fontenc}    % Encodage T1 (adapté au français)
  \usepackage{lmodern}        % Caractères plus lisibles
  \usepackage{babel}          % Réglages linguistiques (avec french)
  \pagestyle{empty}           % N'affiche pas de numéro de page
  \usepackage{pgffor}

\newcommand{\cmd}{-x-}

\begin{document}
  \foreach \n in {1,...,4}{\cmd{}}
\end{document}

La commande \foreach présente l’inconvénient potentiel que son contenu est exécuté dans un groupe, de sorte que tous les calculs effectués dans la boucle sont perdus (à moins que leur résultat ne soit rendu \global) ; cependant, elle n’a rien de particulièrement spécifique au dessin, à la différence de \multiput, de sorte que son potentiel en dehors de son environnement graphique d’origine est plus clair.