> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/fr/articles-approfondis/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# Comment fonctionne \expandafter : étude détaillée d’une macro

&#x20;[Partie 1](/latex/fr/articles-approfondis/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Partie 2](/latex/fr/articles-approfondis/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Partie 3](/latex/fr/articles-approfondis/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Partie 4](/latex/fr/articles-approfondis/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Partie 5](/latex/fr/articles-approfondis/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Partie 6](/latex/fr/articles-approfondis/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)&#x20;

## Étude de cas : \expandafter exemple tiré du $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Manuel

Le $$\varepsilon\mathrm{\text{-}{\TeX}}$$ le moteur de composition a été dérivé du logiciel TeX de Knuth et devait à l'origine servir de étape « provisoire » vers le développement du [Nouveau système de composition](https://en.wikipedia.org/wiki/New_Typesetting_System) (NTS), écrit dans le langage de programmation Java. $$\varepsilon\mathrm{\text{-}{\TeX}}$$ a été d'abord développé à la fin des années 1990 pour ajouter une suite de nouvelles commandes primitives offrant des fonctionnalités supplémentaires non disponibles dans le programme original de Knuth. Bien que $$\varepsilon\mathrm{\text{-}{\TeX}}$$ ait reçu des mises à jour périodiques depuis sa sortie initiale, il n'est aujourd'hui pas largement utilisé comme moteur de composition autonome, bien que ses innovations aient été intégrées dans les générations ultérieures de TeX : pdfTeX, XeTeX et LuaTeX.

Le [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) contient un exemple éclairant d'une macro qui fait un usage astucieux de `\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` met en œuvre un mécanisme de boucle, de sorte que `\foo{7}{13}` produit `7, 8, 9, 10, 11, 12, 13`; cependant, `\foo` n'utilise aucune *affectation à des variables* afin de contrôler le processus de boucle — ce qui en fait une macro intéressante à examiner en détail.

### Quelques notions de base : expressions et affectations

Un élément important du `\foo`de son code est son utilisation de la commande `\numexpr`, une commande d'un ensemble de quatre primitives apparentées introduites pour la première fois par $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` et `\muexpr`. Leur but est de construire ce qu'on appelle des *expressions* qui permettent de calculer/manipuler des valeurs TeX de type number, dimen, glue ou muglue (respectivement). Comme indiqué aux pages 8–9 du $$\varepsilon\mathrm{\text{-}{\TeX}}$$ Manuel, une caractéristique importante des *expressions* est que leur évaluation (calcul) ne requiert pas que TeX effectue des *affectations*.

En programmation, l'affectation est le processus consistant à attribuer à une variable une valeur particulière ; par exemple, affecter `\count` un registre `99` pour contenir la valeur `12345` via `\count99=12345`. De nombreux autres types d'affectation ont lieu lors du traitement de TeX — par exemple, affecter à des registres de jetons une série de jetons, affecter à des registres de boîtes du contenu de boîtes, et ainsi de suite.

Pour effectuer une affectation, comme `\count99=12345`, TeX doit activer (exécuter) le code interne qui implémente le comportement de `\count` ou de toute autre primitive qui effectue une forme quelconque d'affectation. Cependant, il arrive que TeX effectue une *extension* et, à ces moments-là, de telles affectations ne sont pas exécutées —*à ce stade du traitement de TeX*. Des exemples de cette situation incluent les commandes suivantes :

* `\edef\command {*token list*}` la commande de définition de macro « définition développée » qui développe les jetons dans *liste de jetons* et stocke le résultat comme définition de `\command`.
* `\write *number* {*token list*}` développe les jetons dans `*token list*` et les écrit dans un fichier représenté par `*number*`.
* `\directlua {*token list*}` cette commande primitive de LuaTeX sert à transmettre du code Lua à l'interpréteur Lua intégré. Tous les jetons dans `*token list*` sont entièrement développés avant d'être transmis à l'interpréteur Lua pour exécution.

#### Exemple rapide de \edef

Si nous écrivons les macros de base suivantes :

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` développera `\mycount` en ses jetons constitutifs, mais n'ira pas plus loin : aucune des commandes contenues dans la définition de `\mymacro` sera exécutée : c'est-à-dire que l'affectation de `12345` à `\count99` *ne se produit pas à ce stade*; ce n'est qu'en appelant `\mymacro` que cette affectation aura lieu, lorsque TeX exécutera le code pour traiter la `\count` primitive. Lorsque TeX effectue des activités *de développement uniquement* toute affectation sera exécutée plus tard dans le traitement de TeX, et non pendant le processus de développement lui-même.

#### Pourquoi les affectations nous intéressent-elles ici ?

Lorsqu'on écrit du code pour effectuer une boucle — dans n'importe quel langage de programmation — il est courant d'avoir une variable désignée comme « compteur de boucle » : utilisée pour contrôler le nombre de fois qu'une boucle est exécutée. Le bouclage est généralement contrôlé en testant si cette variable de compteur de boucle désignée a atteint une certaine valeur — cette variable est incrémentée (ou décrémentée) à chaque itération de la boucle. Cependant, modifier une variable de compteur de boucle signifie lui attribuer une nouvelle valeur, ce qui, pour TeX, nécessite généralement la commande primitive `\advance` pour incrémenter (ou décrémenter) une valeur stockée dans un `\count` registre. Comme nous l'avons vu, pendant le processus de développement pur de TeX, de telles affectations (y compris l'incrémentation de variables) ne peuvent pas avoir lieu : la macro `\foo` contourne astucieusement cette restriction.

### Revenons à l'explication de \foo

La macro `\foo` est capable de contrôler le processus de boucle *sans* sans avoir besoin d'attribuer des valeurs à des variables : elle contrôle la fréquence de la boucle à l'aide de données issues du développement : des valeurs de données stockées dans des listes temporaires de jetons. En utilisant notre connaissance de l'utilisation (création) par TeX de listes temporaires de jetons, nous pouvons examiner de plus près pour voir exactement comment `\foo` obtient ses résultats.

**Rappelez-vous**: Nous examinons l'exécution d'une macro après que le texte original de sa définition — contenu dans un `.tex` fichier — a été analysé (lu par TeX) et converti en une liste de jetons représentant la définition de la macro. En substance, nous suivons le traitement par TeX de ces *jetons* stockés pendant qu'il lit et traite les jetons dans la définition de la macro contenue quelque part dans la mémoire de TeX. Tout caractère espace présent à l'origine dans le code TeX de la définition de la macro (texte à l'intérieur du `.tex` fichier) aura été absorbé lorsque TeX a analysé ce texte à la recherche de commandes (les espaces comme délimiteurs), ou il aura été converti en jetons, comme le caractère espace après la virgule (`,`) dans `\ifnum#1<#2,` qui provient de la conversion du caractère de fin de ligne (`\r`) en espace.

Parce que le code TeX dans `\foo` utilise plusieurs `\expandafter` commandes, nous allons faciliter notre explication en ajoutant des indices à chaque `\expandafter`, indiquant à laquelle nous faisons référence. De plus, nous étendrons la notation pour les jetons traités par `\expandafter` à $$\mathrm{T^i\_1}$$ et $$\mathrm{T^i\_2}$$, en représentant les jetons $$\mathrm{T\_1}$$ et $$\mathrm{T\_2}$$ pour `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

Voici le code de la macro annoté :

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

`\foo` commence par `\number#1` qui utilise la commande développable `\number` pour convertir la valeur du premier argument en sa représentation typographique. La `\number` commande fonctionne en générant une liste temporaire de jetons contenant des jetons de caractères qui représentent les chiffres individuels contenus dans la valeur numérique sur laquelle `\number` opère. Cette liste de jetons devient la prochaine source d'entrée de TeX. Ici, cette liste de jetons est lue et les jetons sont émis pour composer la valeur de `#1`.

Ensuite, la macro effectue le test `\ifnum#1<#2` pour vérifier si l'argument de `#1` est inférieur à l'argument passé pour `#2`. Si c'est le cas, une virgule (`,`) est émis (composé), suivi d'un espace provenant du jeton généré à partir du caractère de saut de ligne après la virgule (`,`). Ce caractère espace a d'abord été généré lorsque TeX a lu cette ligne depuis le `.tex` fichier.

La macro continue en traitant cette section suivante du code, qui constitue le cœur de son fonctionnement :

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

En substance, ce code génère une série de listes temporaires de jetons qui aboutissent à plusieurs appels à la `\foo` macro, s'arrêtant lorsque le test if `\ifnum#1<#2` n'est plus vrai. Mais *comment* le bouclage est-il contrôlé alors qu'aucune affectation n'a lieu : où est donc le « compteur de boucle » ?

Commençons par examiner le code `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`. Notez que nous utiliserons la notation en indice `<sub>token</sub>` (ou `<sub>(token)</sub>`) pour nous rappeler qu'ici, TeX lit/traite des valeurs de jetons numériques (entiers).

Ici, nous avons les jetons suivants comme entrée pour `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` qui est lu et stocké pour un *réinsertion* dans l’entrée
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (jeton)</sub>` qui est développé

Pour `\expandafter<sub>2</sub>` nous avons :

* $$\mathrm{T^2\_1} =$$`{<sub>token</sub>` qui est conservé pour une *réinsertion* dans l’entrée
* $$\mathrm{T^2\_2} =$$ `\number<sub>token</sub>` qui est développé

**Remarque :**`\number` est une commande développable dont le but est de « convertir en jetons » : c'est-à-dire convertir une quantité numérique en une série de jetons de caractères représentant cette quantité. Lorsque `\number` est développé, la première chose que fait TeX est d'analyser l'entrée à la recherche d'entiers : un processus qui déclenche un développement supplémentaire.

**La clé de l'histoire :** Ici, `\number` agit sur l' *expression* `\numexpr#1+1` qui calcule la valeur de `#1+1`. Le résultat de ce calcul est traité par `\number` pour le convertir en une liste temporaire de jetons contenant des jetons de caractères représentant la valeur de `#1 + 1`Cette liste temporaire de jetons, générée par `\number`, sera finalement lue comme premier argument d'un autre appel à `\foo`. Plutôt que d'incrémenter un compteur de boucle (via `\advance` et une affectation), l'utilisation de `\numexpr` crée une nouvelle valeur sans qu'une affectation soit nécessaire. Grâce à ce mécanisme, la variable qui contrôle la boucle (`\foo`le paramètre de `#1`) est incrémentée et l'itération à travers la boucle est contrôlée et terminée : très ingénieux !

Ensuite, `\expandafter<sub>3</sub>` est traité, donnant :

* $$\mathrm{T^3\_1} =$$`}<sub>token</sub>` qui est conservé pour une *réinsertion* dans l’entrée
* $$\mathrm{T^3\_2} =$$`\expandafter<sub>4 (token)</sub>`, qui est développé :

Pour `\expandafter<sub>4</sub>` nous avons :

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` qui est conservé pour une *réinsertion* dans l’entrée
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` qui est développé et convertit `#2` en une autre liste temporaire de jetons.

Enfin,`\expandafter<sub>5</sub>` est développé :

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` qui est conservé pour une *réinsertion* dans l’entrée
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`, qui est une commande développable.

  Le développement de `Этот текст будет на русском языке. Это демонстрация того, что символы кириллицы в сгенерированном документе отображаются правильно.` met effectivement fin à la `\ifnum` et, en pratique, clôt cette itération de la macro. TeX termine maintenant la réinsertion de tous les jetons temporairement sauvegardés par les multiples `\expandafter` commandes : cela génère une série de listes de jetons à jeton unique provenant des jetons sauvegardés par chaque `\expandafter`. De plus, TeX a également créé des listes de jetons à partir de par l'action de `\number`.

### Assemblage des listes de jetons

En substance, la `\foo` macro génère une séquence de listes de jetons : vous pouvez considérer `\foo` comme une « usine » de fabrication de listes de jetons. Ces listes de jetons sont lues par TeX pour devenir les prochaines sources d'entrée. La partie astucieuse se trouve dans l'une des actions précédentes de `\foo`:

```
    \expandafter1\foo\expandafter2
```

par laquelle `\foo` organise un nouvel appel à elle-même, mais avec des arguments différents stockés dans des listes de jetons construites par `\number`. Pour faire en sorte que ces listes de jetons se comportent collectivement comme un appel de macro, les accolades `{` et `}` ont toutes été sauvegardées et réinsérées dans l'entrée (sous forme de listes à jeton unique) par les actions des `\expandafter` commandes.

![listes de jetons générées par la macro \foo](/files/fede854d00161bbfba037b061c26cd7fe5485214)

&#x20;[Partie 1](/latex/fr/articles-approfondis/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)   [Partie 2](/latex/fr/articles-approfondis/22-how-does-expandafter-work-the-meaning-of-expansion.md)   [Partie 3](/latex/fr/articles-approfondis/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md)   [Partie 4](/latex/fr/articles-approfondis/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md)   [Partie 5](/latex/fr/articles-approfondis/17-how-does-expandafter-work-a-detailed-macro-case-study.md)   [Partie 6](/latex/fr/articles-approfondis/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/fr/articles-approfondis/17-how-does-expandafter-work-a-detailed-macro-case-study.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
