> 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/autres-sujets/24-how-tex-macros-actually-work-part-6.md).

# Comment fonctionnent réellement les macros TeX : partie 6

[Partie 1](/latex/fr/autres-sujets/19-how-tex-macros-actually-work-part-1.md) [Partie 2](/latex/fr/autres-sujets/20-how-tex-macros-actually-work-part-2.md) [Partie 3](/latex/fr/autres-sujets/21-how-tex-macros-actually-work-part-3.md) [Partie 4](/latex/fr/autres-sujets/22-how-tex-macros-actually-work-part-4.md) [Partie 5](/latex/fr/autres-sujets/23-how-tex-macros-actually-work-part-5.md) [Partie 6](/latex/fr/autres-sujets/24-how-tex-macros-actually-work-part-6.md)

## Introduction et aperçu : l’histoire jusqu’ici

Dans les 5 parties précédentes de cette série, nous avons vu :

* comment TeX lit les caractères d’un fichier d’entrée et utilise des codes de catégorie pour reconnaître différentes « classes » de caractères, puis les convertir en jetons de caractère et en jetons de commande ;
* qu’une macro est, en réalité, composée de quatre sections :

```
<primitive de macro TeX><nom de macro><texte de paramètre>{<texte de remplacement>}
```

où :

* `<primitive de macro TeX>` = l’une des `\def`, `\edef`, `\gdef` ou `\xdef`;
* `<nom de macro>`= le nom de votre macro, tel que `\foo`;
* `<texte de paramètre>` peut être « nul » (absent) ou peut être une chaîne de jetons délimiteurs et de jetons de paramètre de macro ;
* `<texte de remplacement>` est le corps réel de votre macro : la section qui est « exécutée » (développée) lorsque vous appelez la macro.
* comment la `<texte de paramètre>` section peut contenir un large éventail de jetons et que TeX utilise cette section comme un « modèle de jetons » pour faire correspondre un appel de macro à sa définition d’origine et déterminer les arguments utilisés avec la macro — et comment TeX attend que votre utilisation d’une macro corresponde à sa définition d’origine ;
* qu’à l’intérieur de TeX, une définition de macro est stockée comme une séquence continue de jetons représentant les `<texte de paramètre>` et `<texte de remplacement>` sections.

Lorsque vous utilisez une commande de macro, TeX vérifie d’abord si elle prend des paramètres. Si oui, TeX doit ensuite identifier les véritables *arguments* utilisés dans votre appel de macro. TeX doit tester votre appel de macro par rapport à la définition « modèle de jetons » qu’il a stockée en mémoire. Plus précisément, TeX utilise la définition interne (stockée) de la `<texte de paramètre>` section de votre macro comme modèle à travers lequel il peut repérer *jetons* qui sont les arguments réels, et qui *jetons* sont là uniquement pour servir de délimiteurs.

## La signification de l’expansion des macros

Nous sommes maintenant enfin prêts à passer au sujet le plus important : comment TeX traite les arguments des macros et exécute réellement la macro : un processus que TeX appelle *l’expansion des macros*.

### Mais d’abord, un court exemple : quelque chose d’étrange ?

Pour « planter le décor » et expliquer le mécanisme par lequel TeX traite les macros et leurs arguments, nous utiliserons un court exemple pour indiquer les points à prendre en considération.

#### Les arguments sont d’abord convertis en jetons

L’exemple suivant est basé sur celui discuté aux pages 114–115 de [The Advanced TeXbook](https://www.amazon.co.uk/Advanced-Texbook-David-Salomon/dp/0387945563) écrit par David Salomon. Il a été choisi parce qu’il résume très bien les idées centrales dans une très courte macro TeX.

Lors des opérations normales de TeX/LaTeX, le `$` signe a le code de catégorie 3 (« bascule mathématique »), ce qui fait entrer/sortir TeX du mode mathématique en ligne (`$...$`)`$$...$$`) — bien sûr, LaTeX utilise `\(..\)` et `\[..\]` aux mêmes fins.

Supposons que nous voulions une macro qui change le code de catégorie d’un `$` signe à, disons, 11 afin de pouvoir le composer comme n’importe quel caractère ordinaire. Nous pouvons utiliser la commande primitive TeX `\catcode` et notre première tentative pour une telle macro, `\docat`, pourrait être

```
\def\docat #1{\catcode`\$=11 #1}
```

Cependant, lorsque nous essayons de l’utiliser, comme ceci

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

nous nous attendons à ce que TeX compose `I paid $90 for that book.` mais cela échoue avec un message d’erreur :

```
! Missing $ inserted.
<texte inséré>
                $
<à relire>
                   \par
l.7
```

D’après l’erreur, il semble que le `$` utilisé dans l’argument de notre macro déclenche toujours TeX pour composer des maths ; manifestement, TeX *n’a pas* modifié le code de catégorie du `$` utilisé dans l’argument de notre macro (`$90`). La question est *pourquoi* pourquoi TeX n’a-t-il pas modifié le code de catégorie de `$` à 11 et l’a-t-il composé comme un caractère ordinaire ? La réponse courte est que TeX convertit d’abord les arguments des macros en jetons **avant** avant de les injecter dans la liste de jetons de la `<texte de remplacement>`— mais nous examinerons les mécanismes sous-jacents beaucoup plus en détail.

Ce qu’il faut retenir, c’est que notre idée de TeX utilisant du texte/des caractères ne s’applique qu’au contenu du fichier que TeX est en train de lire : dès que TeX a lu des caractères, nous entrons dans le monde des *jetons*. Les appels de macro TeX fonctionnent avec *jetons*, et non avec la représentation *écrite/sous forme de texte* des commandes TeX/LaTeX — cela deviendra plus clair au fil de l’exemple.

Au départ, nous pourrions penser que notre utilisation de la `\docat` macro dans `I paid \docat{$90} for that book.` est la même que d’écrire directement le code TeX (ou LaTeX) équivalent — comme ce qui suit, qui *contient* fonctionne :

```
\begin{document}
I paid \catcode`\$=11 $90 for that book.
\end{document}
```

![Du code TeX s’exécutant sur Overleaf](/files/2d46189e5eb1a35ea204d83bb942f4f0daa7f21e)

Cependant, comme nous l’avons vu ci-dessus, la manière dont TeX traite les arguments des macros produit un résultat (`! Missing $ inserted.`) *pourquoi* qui est obtenu.

### Macros et arguments sous forme de listes de jetons

Pour comprendre pleinement le comportement de la `\docat` macro, et de son argument (`$90`), et pourquoi elle échoue, nous devons à nouveau visualiser la définition de la `\docat` macro et tout argument utilisé (lorsque \docat est appelée) comme *des listes de jetons*, et non comme une suite de caractères.

Lorsque TeX parcourt votre texte d’entrée, il reconnaîtrait `\docat` comme une commande de macro ; ensuite, il vérifie si elle prend des paramètres — la manière dont TeX fait cela est expliquée dans la section suivante pour les lecteurs intéressés par les détails.

#### Pour ceux qui aiment les détails...

Après l’appel de la macro, TeX vérifie si le tout premier jeton (dans la liste de jetons de la définition stockée de la macro) est le **jeton de fin de correspondance** jeton : si c’est le cas, TeX peut être certain que la macro ne prend aucun paramètre.

**Un exemple**

Les diagrammes de listes de nœuds suivants comparent les listes de jetons de deux macros :

* `\def\foo A#1B{#1}` : cela comporte `<texte de paramètre>` de `A#1B`, par conséquent le **jeton de fin de correspondance** jeton **ne** est le premier jeton, donc TeX poursuivrait en cherchant des paramètres ;
* `\def\foo{X}` : cela n’a pas de `<texte de paramètre>` section, par conséquent le **jeton de fin de correspondance** jeton est le premier de la liste de jetons et TeX sait qu’il ne doit chercher aucun paramètre.

![Comment TeX vérifie si une macro prend des paramètres](/files/e98e9d2f10fb9a993daf1e60d8e7a12357647518)

## Vers le « grand final » : l’expansion

Rappelons-nous la question : pourquoi la macro suivante n’a-t-elle pas fonctionné ; autrement dit, pourquoi TeX ne change-t-il pas le code de catégorie des `$` signes utilisés dans l’argument de la `\docat` macro, comme `\docat{$90}`?

```
\begin{document}
\def\docat #1{\catcode`\$=11 #1}
I paid \docat{$90} for that book.
\end{document}
```

Comme expliqué ci-dessus, lorsque TeX parcourt votre entrée et reconnaît une commande de macro — au moment où TeX va l’exécuter — TeX vérifie d’abord si cette macro prend des paramètres. Si c’est le cas, TeX devra continuer à parcourir le fichier d’entrée pour identifier les véritables *arguments* que l’utilisateur a fournis pour cet appel de macro précis : TeX doit faire cela **avant** avant de pouvoir appeler le code réel de la macro. Manifestement, TeX doit déterminer les données que l’utilisateur souhaite fournir à la macro.

Pour identifier les arguments présents dans l’entrée (l’appel de macro de l’utilisateur), TeX s’appuiera sur la définition stockée en interne de cette macro : plus précisément, la `<texte de paramètre>` section de la définition de macro stockée (liste de jetons) — qui fournit une sorte de « modèle de jetons ». À l’aide de ce « modèle de jetons », TeX doit déterminer quels *jetons* dans l’appel de macro de l’utilisateur ne sont que *délimiteurs* (en quelque sorte de la « ponctuation ») et quels *jetons* font partie d’un *argument*. C’est lorsque TeX rencontre un **paramètre de correspondance** jeton dans la définition stockée de la macro `<texte de paramètre>` section (« modèle de jetons ») qu’il sait commencer à former une *liste de jetons* pour cet argument particulier.

Dès que TeX reconnaît la nécessité d’identifier l’argument de l’utilisateur, TeX parcourt l’entrée pour générer des jetons et les vérifie très soigneusement, jeton par jeton, par rapport à la définition stockée de la macro. TeX continue à recueillir des jetons pour un argument jusqu’à ce qu’il détecte un jeton qui est en réalité un délimiteur, ou s’il détecte le **jeton de fin de correspondance** jeton : dans les deux cas, TeX sait alors qu’il est temps d’arrêter de chercher des jetons qui font partie de cet argument.

### Pourquoi la macro \docat a échoué

Comme indiqué, *avant* Pour que TeX puisse effectivement appeler une macro, il doit identifier et préparer tous les arguments qui doivent être utilisés avec cette macro. Cependant, pour identifier le ou les arguments, prêts à être injectés dans la macro, TeX doit générer chaque argument sous forme de *liste de jetons* : et c’est la raison de `\docat`l’échec de la

Dans notre exemple, nous avons fourni `\docat` avec un argument de `$90` mais cet argument est d’abord *converti en une liste de jetons* lorsque TeX parcourt l’appel de macro — l’argument est converti en jetons *avant* avant que la macro soit réellement appelée. Ici, pour l’argument `$90`, TeX générera trois jetons de caractère : un jeton pour chacun des `$`, `9` et `0`.

Le graphique suivant montre la liste de jetons générée pour l’argument `$90`, avant d’être injectée dans le corps de la `\docat` macro :

![Liste de jetons TeX générée pour un argument de macro](/files/aaf141055d7831ca4b9b3705b98c02e8c2a75155)

Dans le graphique ci-dessus, nous pouvons clairement voir que la liste de jetons de l’argument contient le `$` comme jeton de caractère basé sur un code de catégorie de 3.

Comme nous l’avons vu dans les parties 1 à 3, les jetons de caractère sont créés à l’aide des valeurs de code de catégorie *en vigueur au moment où le caractère est lu*— c’est-à-dire au moment où la liste de jetons de l’argument est créée (transformée en jetons). Au moment où les arguments sont tokenisés, la `\docat` macro n’a pas encore été exécutée, donc le changement de code de catégorie que nous avons mis dans l’appel de macro (``\catcode`\$=11``) *ne déclenche pas* n’affecte pas les codes de catégorie utilisés pour générer les jetons de l’argument.

Une fois que TeX a généré une liste de jetons représentant l’argument de `$90`, ces trois jetons de caractère sont injectés dans la macro réelle `<texte de remplacement>`. Cependant, cela entraîne le `$` fait d’être injecté comme un *jeton de caractère* jeton de caractère créé à l’aide du code de catégorie 3 : « maths activé » et nous avons vu qu’une fois qu’un jeton de caractère est formé, le code de catégorie associé est permanent. Le `$` est *ne* injecté dans la macro *comme caractère*, *jeton de caractère* mais comme un `$` basé sur le

### Exécution de \docat : expansion de la macro

TeX désigne le processus d’« exécution » d’une macro comme *l’expansion des macros*; un terme qui, selon l’auteur, est un peu confus, mais c’est la terminologie admise, donc nous continuerons à l’utiliser.

#### Le vrai sens de l’expansion des macros

Après que TeX a détecté la `\docat` commande dans l’entrée de l’utilisateur, il parcourt les arguments et génère une liste de jetons pour son argument (`$90`). Pour exécuter (développer) la macro, TeX détourne son attention du fichier d’entrée de l’utilisateur et commence à lire les jetons contenus `\docat`de `<texte de remplacement>` dans la liste de jetons stockée dans la mémoire de TeX.

Lorsque TeX traite `\docat`de sa définition, il verra alors, et exécutera, la série de jetons utilisée à l’origine pour définir la macro (`**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**#1**`).

Le graphique suivant montre le processus d’expansion de la `\docat` macro : TeX cesse de prendre des jetons dans le fichier d’entrée et commence à lire des jetons depuis la `<texte de remplacement>` section de la `\docat` définition de macro stockée en mémoire. TeX procède à l’exécution de ces jetons préalablement préparés jusqu’à ce qu’il voie un **paramètre de sortie** jeton qui ordonne à TeX de lire (« injecter ») et d’« exécuter » les jetons de l’argument à ce moment-là. Dans notre exemple, il s’agit de trois jetons de caractère représentant `$90` et cela provoque une erreur parce que le jeton de caractère préparé à l’avance pour `$` a le code de catégorie 3. Comme nous avons affaire à des jetons de caractère, et non à des caractères, le `$` n’est pas affecté par le changement précédent du code de catégorie provoqué par les jetons dans ``\catcode`\$=11``.

![Illustration du processus d’expansion de la macro \docat](/files/1b8d91e1ef950b4dd386939842b03418528ac580)

Après que TeX a traité les jetons représentant ``\catcode`\$=11``, le changement de code de catégorie pour `$` sera désormais effectif. TeX rencontre alors le « jeton spécial » appelé **paramètre de sortie** qui indique à TeX de **insèrent** la liste de jetons de l’argument. Cependant, cette liste de jetons est composée de trois jetons de caractère *jetons*, dont le premier est un jeton pour un `$` qui lui est attribué avec un code de catégorie 3 (« maths activé ») : le changement précédent de code de catégorie au sein de la macro ne peut pas affecter ce jeton de caractère, de sorte que TeX traite ce jeton comme un signal pour commencer le traitement mathématique, ce qui fait échouer la macro.

### Peut-on corriger la macro \docat ?

D’après les explications ci-dessus, il est clair que tous les caractères apparaissant dans les arguments de macros sont tokenisés à l’aide des codes de catégorie en vigueur au moment où la tokenisation a lieu — ce qui, dans notre exemple, est *toujours* avant que la `<texte de remplacement>` du `\docat` macro soit effectivement exécutée. Alors, comment pouvons-nous nous assurer que les codes de catégorie des arguments d’une macro soient modifiés ?

Une façon consiste à modifier `\docat` pour en faire une macro sans paramètre qui se contente de changer le code de catégorie — elle n’a aucun argument à tokeniser. Nous utilisons alors une deuxième macro, `\getarg`, qui prend un seul paramètre, et nous faisons en sorte que son argument soit tokenisé lorsque le code de catégorie approprié pour `$` est en vigueur.

```
\begin{document}
\def\docat{\catcode`\$=11 \getarg} % Aucun paramètre, appelle une deuxième macro \getarg
\def\getarg#1{#1} %1 paramètre dont l’argument sera tokenisé
Vous pouvez maintenant l’exécuter ainsi et cela fonctionnera :

I paid \docat{$90} for that book.
\end{document}
```

Lorsque nous utilisons notre nouvelle version de `\docat` (comme ceci `\docat{$90}`) cela *semble* comme si le `$90` était encore utilisé comme argument pour la `\docat` macro. Cependant, comme indiqué ci-dessus, lorsque TeX détecte `\docat` dans l’entrée, il vérifie s’il a des arguments : ce n’est plus le cas, donc TeX procède à son exécution (développement). L’expansion de `\docat` est la séquence de jetons `**catcode**`, ``**`**``, `**\$**`, `**=**`, `**1**`, `**1**`, `**espace**`, `**getarg**` et cela se produit *avant* TeX commence à lire (tokeniser) les caractères suivants contenus dans le fichier d’entrée — c’est-à-dire le groupe `{$90}`. Rappelez-vous que lorsque TeX développe une macro, il obtient sa prochaine entrée en lisant les jetons contenus dans la liste de jetons de la définition de cette macro ; c’est-à-dire depuis sa `<texte de remplacement>` section stockée en mémoire.

TeX traitera, et exécutera, l’expansion de `\docat` et détectera la *le jeton* **`getarg`**, en le reconnaissant comme un jeton qui représente une commande prenant des paramètres. À ce stade, TeX parcourra le fichier d’entrée à la recherche de **`getarg`**&#x64;e son argument : les caractères : `{$90}`. Comme d’habitude, ils sont tokenisés mais, comme TeX a lu et traité l’expansion de `\docat`, `$90` sont tokenisés lorsque le code de catégorie de `$` a été changé à 11. La définition (`<texte de remplacement>`) de `\getarg` est simplement `#1` ce qui signifie composer l’argument fourni, et c’est ce qui se produit, donnant lieu à un `$` avec le code de catégorie 11 étant généré et composé sans problème.

## Remarques finales : l’histoire en nœuds

La séquence d’événements résultant de la réécriture de `\docat` pour utiliser la macro `\getarg` est présentée dans le diagramme annoté de liste de nœuds suivant, qui montre le processus d’expansion de la macro `\docat`. Les lecteurs souhaitant étudier attentivement ce diagramme peuvent télécharger le graphique au format [PDF](https://assets.ctfassets.net/nrgyaltdicpt/7MOBdavza4WxAEQGISEEht/cabe5097d9063a6415bc553cd38237e6/newdocatexpansion.pdf) ou [SVG](https://images.ctfassets.net/nrgyaltdicpt/2FIqqVRXjakdAzTpZsV0m9/10ccc1353741d42d3df18f1692d8aa84/newdocatexpansion--plain.svg) pour une utilisation hors ligne.

![Illustration du processus d’expansion de la macro \docat modifiée et de la macro \getarg](/files/d20a2de9b7c9b2f73c2f7ef76c797f2a6b0de9ff)

[Partie 1](/latex/fr/autres-sujets/19-how-tex-macros-actually-work-part-1.md) [Partie 2](/latex/fr/autres-sujets/20-how-tex-macros-actually-work-part-2.md) [Partie 3](/latex/fr/autres-sujets/21-how-tex-macros-actually-work-part-3.md) [Partie 4](/latex/fr/autres-sujets/22-how-tex-macros-actually-work-part-4.md) [Partie 5](/latex/fr/autres-sujets/23-how-tex-macros-actually-work-part-5.md) [Partie 6](/latex/fr/autres-sujets/24-how-tex-macros-actually-work-part-6.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/autres-sujets/24-how-tex-macros-actually-work-part-6.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.
