> 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/09-an-introduction-to-luatex-part-2-understanding-directlua.md).

# Introduction à LuaTeX (partie 2) : comprendre \directlua

## Le but de cet article

Dans la première partie de cet article, [Introduction à LuaTeX (partie 1) : qu’est-ce que c’est — et qu’est-ce qui le rend si différent ?](/latex/fr/articles-approfondis/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md), nous avons brièvement passé en revue LuaTeX comme un moteur TeX extrêmement polyvalent : un système de composition sophistiqué et programmable, qui fournit une large gamme d’outils pour construire des solutions d’ingénierie documentaire et de production.

Dans cet épisode final, nous examinons de près le composant le plus vital de la boîte à outils LuaTeX : la `\directlua` commande qui fournit la « passerelle » vers le contrôle programmatique de la composition de LuaTeX via le langage de script Lua.

Cependant, exploiter pleinement LuaTeX via `\directlua` nécessite certaines connaissances de base sur plusieurs sujets TeX : les jetons de TeX, les listes de jetons et le mécanisme d’expansion. Le but de cet article est d’explorer et d’expliquer ces concepts fondamentaux de TeX : reconstituer les processus liés à TeX derrière `\directlua` afin de développer une compréhension de son fonctionnement et de fournir les bases sur lesquelles construire vos propres solutions de composition en utilisant LuaTeX.

Cet article comprend de nombreux courts exemples pour démontrer et expliquer les aspects clés de `\directlua`du comportement de LuaTeX, en évitant délibérément un code trop complexe au profit de courts fragments de code. Lorsque nécessaire, les exemples utilisent un TeX de base (brut/plain)—bien que la plupart des gens utilisent et préfèrent LaTeX (macros), les commandes TeX de base ont l’avantage de la simplicité.

## Introduction au Lua dans LuaTeX

[Lua](https://www.lua.org/about.html) est un langage de script dont le [code source](https://www.lua.org/download.html) est hautement portable et facile à intégrer dans des applications logicielles, ce qui permet aux développeurs d’incorporer des capacités de script dans leurs programmes. Lua a été intégré dans [de nombreuses applications](https://en.wikipedia.org/wiki/List_of_applications_using_Lua) et est un choix populaire dans l’industrie du jeu vidéo — l’exemple le plus célèbre est peut-être [World of Warcraft](https://wowwiki.fandom.com/wiki/Lua_functions).

LuaTeX, comme son nom l’indique, est un moteur TeX qui intègre le langage de script Lua, offrant aux utilisateurs la possibilité de contrôler le comportement de composition de LuaTeX en incluant des programmes Lua (scripts) dans leurs documents. Outre le contrôle direct de LuaTeX, les utilisateurs peuvent exploiter Lua purement comme un langage de programmation très performant pour effectuer des tâches qui pourraient être extrêmement difficiles à réaliser en utilisant le langage TeX — qui, à tous égards raisonnables, est difficile à apprendre et à maîtriser. Grâce à l’ajout et à l’intégration de Lua, LuaTeX devient un moteur TeX très polyvalent et puissant qui prend directement en charge deux langages de programmation.

### Utiliser Lua et TeX dans votre document : introduire \directlua

Lua et TeX sont deux *très différents* langages de programmation : Lua est beaucoup plus proche de ce que la plupart des gens considèrent comme un langage de programmation, mais TeX, avec ses codes de catégorie, ses jetons, ses macros et son mécanisme d’expansion, est très éloigné des expériences/attentes de la plupart des gens concernant un langage dans lequel écrire des programmes. Cependant, comme l’histoire l’a montré, le langage TeX a perduré parce qu’il est bon dans ce pour quoi il a été conçu : contrôler la composition, même si son mode de fonctionnement est quelque peu ésotérique.

Pour relever le défi du mélange des langages Lua et TeX dans un seul document TeX, les développeurs de LuaTeX ont introduit une nouvelle commande appelée `\directlua` qui est la voie pour utiliser Lua — à la fois comme langage de programmation autonome à part entière et pour contrôler le comportement de composition de LuaTeX.

Le `\directlua` commande permet aux utilisateurs d’intégrer du code Lua dans leurs documents TeX ; ce code est ensuite transmis à l’interpréteur Lua intégré à LuaTeX. Cependant, `\directlua` permet également de vous *combiner* code Lua et (La)TeX ensemble, dans la même `\directlua` commande—bien que cela introduise des complexités supplémentaires en raison des différences fondamentales entre les langages de programmation Lua et ceux basés sur TeX. Le principal défi lors de l’utilisation d’une combinaison de code (La)TeX et Lua est de s’assurer que ces deux langages coexistent paisiblement et ne se « gênent » pas.

`\directlua` convient mieux à une utilisation avec de courts fragments de code Lua intégrés dans le document, mais vous pouvez l’utiliser avec des programmes Lua plus étendus, si vous le souhaitez. En général, les programmes Lua plus conséquents et les bibliothèques de code Lua sont enregistrés dans des fichiers externes qui peuvent être chargés en utilisant la fonction `dofile()` dans une `\directlua` commande. Du point de vue du traitement TeX, un avantage important de l’utilisation de fichiers de code Lua externes est d’éviter les complications qui découlent du mécanisme des codes de catégorie de TeX — un sujet entièrement abordé dans cet article.

### Description plus formelle de \directlua

Le [Le manuel de référence LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) décrit `\directlua` comme suit (légèrement modifié) :

> Afin de fusionner du code Lua avec l’entrée TeX, quelques nouveaux primitifs sont nécessaires. Le primitif `\directlua` est utilisé pour exécuter immédiatement du code Lua. La syntaxe de base est `\directlua{⟨code⟩}`. Le `⟨code⟩` est entièrement développé, puis envoyé à l’interpréteur Lua. Après que la lecture et le développement ont été appliqués à `⟨code⟩`, la liste de jetons résultante est convertie en une chaîne comme si elle était affichée à l’aide de `\the\toks`.

Bien sûr, cela est techniquement exact mais peut-être pas si facile à comprendre sans quelques connaissances des processus TeX de bas niveau — tels que les jetons et l’expansion.

## Comprendre \directlua : quels sujets allons-nous couvrir ?

Dans cet article, nous examinerons de plus près certains sujets de contexte clés et proposerons un certain nombre d’exemples conçus pour montrer comment `\directlua` fonctionne et à quels endroits (ou pourquoi) il faut être prudent lorsque vous combinez TeX et Lua dans votre `⟨code⟩`.

Nous explorerons suffisamment en détail les sujets suivants pour fournir une base permettant de comprendre `\directlua` et son « prétraitement » du code que vous utilisez à l’intérieur :

* les codes de catégorie et les jetons TeX : conversion du texte en jetons et des jetons en texte ;
* le processus d’expansion de TeX (et l’empêchement de l’expansion) ;
* les mécanismes/séquences d’échappement Lua pour les caractères et les chaînes ;
* l’utilisation des commentaires de style Lua ;
* une courte introduction à l’API Lua de LuaTeX.

Si vous comprenez comment les moteurs TeX créent et utilisent des jetons et développez une conscience du mécanisme d’expansion de TeX, alors vous aurez les bases nécessaires pour libérer l’incroyable polyvalence de la `\directlua` commande.

## Les bases : du texte aux jetons et des jetons au texte

Overleaf a publié plusieurs articles qui examinent en profondeur les jetons TeX et les concepts associés, nous ne répéterons donc pas tout ce matériel ici ; au lieu de cela, nous décrirons ces domaines/sujets pertinents pour développer une meilleure compréhension de `\directlua`.

Voici une liste d’articles publiés précédemment qui pourraient vous intéresser :

* [Qu’est-ce qu’un jeton TeX ?](/latex/fr/articles-approfondis/53-what-is-a-tex-token.md)
* [Qu’est-ce qu’une liste de jetons TeX ?](/latex/fr/articles-approfondis/54-what-is-a-tex-token-list.md)
* [Comment fonctionne \expandafter : une introduction aux jetons TeX](/latex/fr/articles-approfondis/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md)
* [Une série en six parties : comment les macros TeX fonctionnent-elles réellement ?](/latex/fr/autres-sujets/01-a-six-part-series-how-do-tex-macros-actually-work.md)

### Comprendre les jetons de caractère

Tout caractère qu’un moteur TeX peut lire à partir d’un fichier texte est représenté par deux valeurs numériques :

* son *code de caractère* (valeur ASCII ou, aujourd’hui, son point de code Unicode) ;
* une deuxième valeur, centrée sur TeX, appelée son *code de catégorie*.

Les lecteurs qui souhaitent en savoir plus sur les codes de catégorie pourraient être intéressés par cette introduction publiée par Overleaf : [Alors, par où commencer ? Avec les codes de catégorie](/latex/fr/autres-sujets/19-how-tex-macros-actually-work-part-1.md#so2c-where-do-we-start3f-with-category-codes).

Par exemple, si un moteur TeX lit un caractère `A` il aurait accès à deux informations : `A`son code de caractère (65) et son code de catégorie (11, généralement). Une fois que TeX a saisi ce caractère `A`, son code de catégorie ne sera pas changé, mais les macros utilisateur peuvent effectuer des changements de code de catégorie qui pourraient affecter tout *caractère* suivant `A` qui *n’a pas encore été lu* par TeX. Par conséquent, TeX doit enregistrer que *ceci* suivant `A`, *tout juste lu*, a le code de catégorie 11. Pour ce faire, TeX utilise la paire d’entiers (65,11) pour calculer une autre valeur entière qu’il appelle un *jeton de caractère*. En calculant cette valeur de jeton, qui est transmise au traitement interne de TeX, ce `A` et son code de catégorie sont *liés ensemble*; en effet, ce jeton de caractère *encapsule* les données que TeX doit connaître à propos de ce caractère pour les utiliser dans toute activité de composition ultérieure plus profondément à l’intérieur du moteur TeX.

#### Comment les jetons de caractère sont-ils calculés ?

Tout d’abord, nous devons nous rappeler que les moteurs TeX utilisent le code de catégorie 13 pour créer ce qu’on appelle *des caractères actifs*: tout caractère ayant le code de catégorie 13 se comporte comme une mini-macro ; par conséquent, et comme nous le verrons ci-dessous, les jetons pour les caractères actifs sont calculés différemment de ceux des caractères ordinaires avec d’autres codes de catégorie tels que 10, 11 ou 12.

Pour *non actifs* caractères :

* les anciens moteurs 8 bits (TeX de Knuth, e-TeX, pdfTeX) calculent les jetons de caractère pour *non actifs* caractères en utilisant

$$\text{(non-active) character token} = (256 \times \text{category code}) + (\text{ASCII character code})$$

* pour LuaTeX, qui doit gérer des valeurs de caractères Unicode, le calcul pour *non actifs* caractères est similaire mais produit des valeurs entières beaucoup plus grandes :

$$\text{(non-active) character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

En revenant à notre exemple précédent pour la lettre A avec le code de catégorie 11, LuaTeX calculerait une valeur de jeton de caractère de $$2^{21} \times 11 + 65 = 23068737$$. Une fois calculée, cette valeur de jeton de caractère *lie* ce caractère A particulier à une valeur de code de catégorie de 11. Les macros utilisateur peuvent changer le code de catégorie de tout caractère A ultérieur, mais le code de catégorie de celui-ci a été fixé en le convertissant en jeton pour son utilisation lorsqu’il passe à travers les rouages internes de LuaTeX. LuaTeX a préservé, ou encapsulé, le sens voulu de ce caractère tel qu’il a été déterminé au moment où il a été lu.

Les moteurs TeX utilisent au total [16 codes de catégorie différents](/latex/fr/autres-sujets/43-table-of-tex-category-codes.md) et *tout* de ces codes de catégorie peuvent être attribués, via la `\catcode` commande, à *tout* caractère que le moteur TeX est capable de lire. Les changements de codes de catégorie servent à modifier la manière dont les moteurs TeX traitent certains caractères dans l’entrée, permettant aux utilisateurs de TeX d’écrire des macros qui produisent des résultats ou comportements typographiques spéciaux.

**Caractères actifs**

Comme indiqué, les moteurs TeX utilisent le code de catégorie 13 pour attacher une « signification spéciale » à un caractère, en en faisant un soi-disant *caractère actif* qui se comporte comme une mini-macro : pas de `\` initial n’est requis, le caractère isolé, en raison de son code de catégorie, suffit à déclencher son comportement de type macro.

Parce qu’un caractère actif agit comme une mini-macro, il n’est pas converti en un *jeton de caractère* mais en un deuxième type de jeton (entier) appelé un *jeton de commande*. Ceux-ci sont calculés comme suit :

* pour les anciens moteurs 8 bits (TeX de Knuth, e-TeX, pdfTeX), les jetons pour les caractères actifs sont calculés via :

1. calculer une valeur intermédiaire appelée $$\text{curcs}$$ (**cour**ant **c**contr **e**séquence) où $$\text{curcs} = \text{character code} + 1$$3. calculer la valeur du jeton où $$\text{active character token} = \text{curcs} + \text{4095}$$

* pour LuaTeX, le calcul est un peu plus complexe parce qu’il doit gérer toute la gamme des caractères Unicode, dont n’importe lequel pourrait être rendu actif :

1. calculer la valeur entière intermédiaire $$\text{curcs}$$ en appliquant une soi-disant *fonction de hachage* à la valeur du point de code Unicode du caractère actif exprimée en UTF-8 : $$\text{curcs}=\texttt{hashfunction}\text{(UTF-8 text for Unicode value of active character)}$$3. calculer la valeur entière du jeton : $$\text{active character token} = \text{curcs} + 2^{29} - 1$$

**Exemples**

* moteurs 8 bits : le calcul du jeton pour le caractère actif `~` (code de caractère 126) donne $$\text{curcs} = 126 + 1 = 127$$, ce qui donne une valeur de jeton de $$4095 + 127 = 4222$$.
* LuaTeX : le calcul du jeton pour le caractère actif `~` donne $$\text{curcs}=3186$$ ce qui donne une valeur de jeton de $$3186 + 2^{29} - 1 = 536874097$$. Les jetons LuaTeX utilisent des valeurs entières beaucoup plus grandes !

### Comprendre les jetons de commande

En plus de traiter des *caractères* individuels, les moteurs TeX peuvent, bien sûr, traiter *séquences* de caractères appelées *commandes* (ou, plus correctement, *séquences de contrôle*). Par tradition, le `\` caractère est utilisé pour signaler le début d’une commande, mais ce n’est qu’une convention — en fait, tout caractère ayant le code de catégorie 0 (le caractère d’échappement) pourrait être utilisé à la place.

Les moteurs TeX reconnaissent deux types de commande connus comme *mots de contrôle* et *symboles de contrôle*:

* **mots de contrôle**: commandes construites à partir d’un ou plusieurs caractères ayant le code de catégorie 11 ;
* **symboles de contrôle**: commandes à caractère unique où le code de catégorie de ce caractère *n’est pas* 11 : comme `\$`, `\#` ou `\\`.

**Remarque**: Les primitives TeX `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` et `\toksdef` sont également utilisées pour définir des séquences de contrôle, mais, contrairement aux définitions de macros ordinaires, les séquences de contrôle résultantes (mots de contrôle ou symboles de contrôle) *ne sont pas expansibles*—nous les explorerons plus en détail ci-dessous.

#### Comment les jetons de commande sont-ils calculés ?

Tout comme les caractères actifs, les moteurs TeX utilisent le deuxième type de valeur de jeton entier pour représenter les commandes : *jetons de commande*—rappelez-vous que les caractères actifs génèrent également des jetons de commande car ils se comportent comme des mini-macros.

Les calculs utilisés par les moteurs 8 bits pour créer les entiers de jetons de commande se trouvent dans cet [article Overleaf](/latex/fr/articles-approfondis/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md#how-tex-calculates-token-values). Ici, nous résumerons les étapes clés des calculs de jetons de commande pour LuaTeX — qui sont légèrement différents parce que LuaTeX doit traiter des valeurs de code de caractère Unicode qui peuvent être considérablement plus grandes que les valeurs 8 bits ; cependant, les calculs de LuaTeX suivent les mêmes principes généraux que ceux utilisés par les anciens moteurs 8 bits.

Après avoir détecté une commande entrante, les moteurs TeX, y compris LuaTeX, ignorent le `\` caractère initial : il n’est pas utilisé dans les calculs de valeurs de jetons de commande mais agit simplement comme un « commutateur » pour informer un moteur TeX qu’il doit traiter une commande. La valeur du jeton de commande est calculée à partir de la séquence de caractères (un ou plusieurs) présente dans le nom de la commande — LuaTeX calcule les jetons de commande pour les symboles de contrôle et les mots de contrôle en utilisant le même algorithme :

1. calculer la valeur entière intermédiaire $$\text{curcs}$$ en appliquant une soi-disant [fonction de hachage](https://en.wikipedia.org/wiki/Hash_function) à la chaîne UTF-8 Unicode de caractères contenue dans le nom de la commande : $$\text{curcs}=\texttt{hashfunction}\text{(Unicode UTF-8 string of characters in command name)}$$3. calculer la valeur du jeton de commande où $$\text{command token} = \text{curcs} + 2^{29} - 1$$

**Exemples**

* pour le `\\` commande (un symbole de contrôle), LuaTeX calcule $$\text{curcs}=94$$, ce qui donne une valeur de jeton pour `\\` de $$94 + 2^{29} - 1 = 536871005$$.
* pour le `\vskip` commande primitive (un mot de contrôle) LuaTeX calcule $$\text{curcs}=3560$$, ce qui donne une valeur de jeton pour `\vskip` de $$3560 + 2^{29} -1 = 536874471$$.
* pour la macro définie par l’utilisateur `\mynewmacro` (un mot de contrôle) LuaTeX calcule $$\text{curcs} = 2971$$, ce qui donne une valeur de jeton pour `\mynewmacro` de $$2971 + 2^{29} -1 = 536873882$$.

Une fois créés, les jetons peuvent être stockés pour une utilisation ultérieure via ce qu’on appelle des *listes de jetons* ou ils peuvent être immédiatement transmis pour un traitement ultérieur à l’intérieur du moteur TeX. L’utilisation de valeurs entières pour représenter les jetons fonctionne non seulement sur tous les types de plateformes informatiques/systèmes d’exploitation, mais c’est aussi une manière très efficace pour TeX de stocker/traiter des données.

### Comment un moteur TeX identifie le type de jeton (commande ou caractère)

Étant donné une certaine valeur entière de jeton, $$T$$, un moteur TeX peut facilement déterminer si $$T$$ représente une commande ou un caractère en vérifiant si $$T$$ dépasse un certain $$\text{threshold value}$$—cela $$\text{threshold value}$$ dépend du moteur TeX. Si $$T \geq \text{threshold value}$$ alors $$T$$ est un jeton de commande sinon $$T$$ est un jeton de caractère. Le $$\text{threshold value}$$ est $$4095$$ pour les moteurs 8 bits et $$2^{29}-1$$ (536 870 911) pour LuaTeX. Knuth a conçu les méthodes utilisées dans les formules de calcul des jetons de manière à ce que son moteur TeX, et tous les moteurs ultérieurs basés sur son code/architecture, puissent tester rapidement et facilement les valeurs des jetons.

## Les jetons peuvent être décomposés (et reconvertis en texte)

Les jetons (entiers) sont le mécanisme par lequel un moteur TeX « encapsule » tout ce qu’il doit enregistrer à propos d’un élément d’entrée (caractère ou commande). Cependant, il y a des moments où un moteur TeX doit inverser le processus de tokenisation — pour savoir ce qui a été lu à l’origine pour produire cette valeur de jeton — un caractère individuel ou une séquence d’un ou plusieurs caractères formant le nom d’une commande :

* **pour les jetons de caractère**: Tout jeton de caractère peut être décomposé en ses deux parties constitutives : le code de caractère et le code de catégorie correspondant attribué à ce caractère *au moment où il a été initialement lu*. Comme tous les moteurs TeX, LuaTeX ne modifiera pas cette attribution originale de code de catégorie, mais l’utilisera lors des activités de traitement interne ultérieures.
* **pour les jetons de commande :** Ceux-ci sont légèrement plus détaillés, mais si vous examinez le calcul des jetons de commande par LuaTeX, y compris les jetons pour les caractères actifs, vous voyez qu’ils suivent un schéma : $$\text{command token} = \text{curcs} + 2^{29} -1$$

où $$\text{curcs}$$ est calculée selon le type de jeton de commande généré : caractère actif, symbole de contrôle ou mot de contrôle. La $$\text{curcs}$$ variable est une *extrêmement* composante importante du fonctionnement interne d’un moteur TeX : étant donné toute valeur de jeton de commande (entier), LuaTeX peut très facilement extraire la valeur de $$\text{curcs}$$ à partir de ce jeton de commande en utilisant $$\text{curcs} = \text{token value} - (2^{29} -1)$$.

### Pourquoi $$\text{curcs}$$ est-il si important ?

La variable interne TeX $$\text{curcs}$$ (**cour**ant **c**contr **e**équence) est un composant d’une importance vitale des opérations internes « sous le capot » d’un moteur TeX. Bien que vous ne puissiez pas, et ne deviez pas, l’utiliser ou y accéder directement dans votre code, $$\text{curcs}$$ joue un rôle crucial car les moteurs TeX utilisent la valeur actuelle de $$\text{curcs}$$ comme indice dans des tables internes qui stockent des données sur chaque commande actuellement connue du moteur. Ces tables stockent des informations sur le sens actuel d’une commande : que fait-elle, ou que représente-t-elle, et, en outre, elles enregistrent la séquence de caractères utilisée à l’origine pour calculer cette $$\text{curcs}$$ valeur. En extrayant la valeur de $$\text{curcs}$$ d’un jeton de commande, un moteur TeX est capable de déterminer le nom, c’est-à-dire le texte lisible par l’humain, correspondant à n’importe quel jeton (de commande), ce qui lui permet d’effectuer les conversions de jeton en texte qui constituent un aspect clé de `\directlua`son fonctionnement.

### Conversion des jetons entiers en caractères ou en séquences de caractères (noms de commande)

Nous avons vu que les moteurs TeX convertissent les caractères d’entrée, ou les séquences de caractères, en valeurs entières de jetons, mais il arrive qu’un moteur TeX doive *inverser* ce processus — pour produire le texte lisible par l’humain utilisé à l’origine pour créer ces valeurs de jetons entiers ; par exemple :

* écrire des messages d’erreur ou d’avertissement à l’écran ou `.log` fichier ;
* produire du code TeX/LaTeX dans un fichier texte via la `\write` commande ;
* lors de la conversion d’une séquence de jetons en texte dans `\directlua` (comme nous le verrons bientôt !)

#### Conversion des jetons de caractère en texte

Comme indiqué, les jetons pour les caractères non actifs sont calculés à l’aide du code de catégorie et du code de caractère (valeur Unicode) d’un caractère d’entrée. LuaTeX utilise la formule :

$$\text{character token} = (2^{21} \times \text{category code}) + (\text{Unicode value})$$

C’est une tâche de programmation simple que de séparer la valeur entière $$\text{character token}$$ pour obtenir son code de caractère constitutif ($$\text{Unicode value}$$) et $$\text{category code}$$.

#### Conversion des jetons de commande en texte

Tous les moteurs TeX stockent le nom (séquence de caractères) de chaque commande qu’ils « connaissent » : qu’il s’agisse d’une macro définie par l’utilisateur ou d’un primitif intégré — le stockage des noms de commandes primitives a lieu au démarrage du moteur TeX, bien avant qu’il ne commence à traiter votre code. Pour les commandes définies par l’utilisateur (macros), le nom de cette macro (sans le `\`d’échappement initial) est stocké dans le cadre des processus de définition des macros à l’intérieur des moteurs TeX.

Lorsque un moteur TeX doit accéder au texte lisible par l’humain à partir duquel un jeton de commande entier a été calculé à l’origine, il déterminera d’abord la $$\text{curcs}$$ valeur pour ce jeton ; dans LuaTeX, $$\text{curcs} = \text{token} - (2^{29} -1$$). En utilisant la valeur de $$\text{curcs}$$ extrait d’un jeton de commande, un moteur TeX peut accéder à une structure de données interne appelée le *pool de chaînes* pour déterminer la séquence de caractères lisibles par l’humain utilisée à l’origine pour calculer cette valeur particulière pour $$\text{curcs}$$ et, par conséquent, le jeton de commande correspondant.

Comme nous le verrons, ces activités de traitement des jetons—conversion des séquences de caractères en valeurs entières de jetons et conversion des valeurs entières de jetons en séquences de caractères (« dé-tokenisation »)—sont les *mécanismes fondamentaux* utilisés à l’intérieur `\directlua`.

## Listes de jetons

Lorsqu’un moteur TeX lit l’entrée, génère des jetons de caractère et de commande (et les traite), il peut rencontrer certaines commandes qui lui ordonnent d’arrêter temporairement de transmettre les jetons pour un traitement ultérieur mais, à la place, de les stocker pour une utilisation ultérieure. L’exemple le plus courant est la définition d’une macro à l’aide de l’une des commandes de définition de macro `\def`, `\edef`, `\gdef` ou `\xdef`—des commandes LaTeX telles que `\newcommand` sont des macros qui fournissent des fonctionnalités supplémentaires construites autour des primitifs de bas niveau qui, en fin de compte, effectuent le processus réel de définition de macro. Une macro peut être considérée comme le nom donné à une liste particulière de jetons stockés : une liste de jetons.

Les moteurs TeX font *un usage* étendu des listes de jetons, en particulier [des listes internes temporaires](/latex/fr/articles-approfondis/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) utilisées à des fins de traitement interne. Chaque moteur TeX fournit également des commandes au niveau utilisateur pour créer des listes de jetons qui sont stockées en attente lorsque l’utilisateur, ou le moteur TeX lui-même, en a besoin. Le nombre de commandes de création de listes de jetons (primitifs intégrés) varie selon le moteur TeX, mais elles partagent toutes un ensemble minimal de base pris en charge par chaque moteur, comme le `\toks` primitif.

En pratique, une liste de jetons n’est qu’une séquence stockée de valeurs entières :

* l’entrée est lue pour générer (calculer) des jetons individuels, représentant un caractère ou une commande ;
* chaque jeton est ensuite stocké, préservant la séquence dans laquelle les jetons ont été générés à partir de l’entrée.

Les moteurs TeX stockent les listes de jetons à l’aide d’une structure de données appelée [liste chaînée](https://en.wikipedia.org/wiki/Linked_list) (la variété simplement chaînée). Les lecteurs souhaitant en savoir plus sur les listes de jetons sont invités à lire l’article Overleaf [Qu’est-ce qu’une liste de jetons TeX ?](/latex/fr/articles-approfondis/54-what-is-a-tex-token-list.md) qui utilise une analogie pour construire les concepts/idées derrière une liste de jetons. Une exploration approfondie des listes de jetons de TeX et de la manière dont elles sont utilisées dans le traitement des macros peut être trouvée dans la série d’articles Overleaf [Comment fonctionnent réellement les macros TeX ?](/latex/fr/autres-sujets/01-a-six-part-series-how-do-tex-macros-actually-work.md)

#### Une liste de jetons sous forme graphique

Le graphique suivant montre une liste de jetons générée par LuaTeX avec les valeurs de jetons correspondantes produites à partir de l’entrée suivante

`Hi, \TeX! \hskip 5bp`

Par exemple, si nous définissons `\mymacro` comme `\def\mymacro{Hi, \TeX! \hskip 5bp}` la définition de `\mymacro` serait stockée en mémoire à l’aide d’une liste de jetons comme celle-ci :

![](/files/a6772e0db15fbb592009cd5b65a1ec5769535d6a)

La liste de jetons est une séquence d’éléments liés appelés *nœuds*, le nom donné à un petit ensemble de mémoire allouée de LuaTeX destiné à contenir chaque élément de la liste (comme des maillons individuels d’une chaîne). Chaque nœud contient une valeur entière de jeton et l’adresse mémoire du *suivant* nœud de la chaîne, formant une structure de données appelée [liste chaînée](https://en.wikipedia.org/wiki/Linked_list). Le dernier nœud indique la fin de la liste en utilisant une « valeur nulle » spéciale pour le nœud suivant — car il n’en existe pas.

**Remarques :**

* Par commodité, nous avons inclus l’adresse de chaque nœud individuel mais, en pratique, ces données ne sont pas stockées dans les nœuds de la liste de jetons ; seule l’adresse du *nœud suivant* est requise pour construire les listes de jetons du moteur TeX.
* La deuxième colonne du graphique intitulé « Ce que chaque jeton signifie » montre une série de cases grises contenant des informations sur le jeton contenu dans chaque nœud : celles-ci sont purement informatives et *ne deviennent pas* ne font pas partie des données réelles stockées dans la liste de jetons.

Voici un tableau des valeurs de jetons contenues dans la liste de jetons représentée ci-dessus :

|                      |                      |                                                                                  |                     |
| -------------------- | -------------------- | -------------------------------------------------------------------------------- | ------------------- |
| **Élément d’entrée** | **Type d’entrée**    | <p><strong>Code de catégorie</strong><br><br><strong>(si caractère)</strong></p> | **Valeur du jeton** |
| H                    | suivant              | 11                                                                               | 23068744            |
| i                    | suivant              | 11                                                                               | 23068777            |
| ,                    | suivant              | 12                                                                               | 25165868            |
|                      | suivant              | 10                                                                               | 20971552            |
| \TeX                 | commande (macro)     |                                                                                  | 536871539           |
| !                    | suivant              | 12                                                                               | 25165857            |
|                      | suivant              | 10                                                                               | 20971552            |
| \hskip               | commande (primitive) |                                                                                  | 536874247           |
| 5                    | suivant              | 12                                                                               | 25165877            |
| b                    | suivant              | 11                                                                               | 23068770            |
| p                    | suivant              | 11                                                                               | 23068784            |

**Remarque :** Notre texte d’entrée original contient un a après le `\hskip` commande, mais il n’existe aucun jeton représentant ce caractère dans la liste des jetons. Ce caractère a été absorbé par le processus de lecture (input-scanning) de LuaTeX parce qu’il a servi à terminer la recherche de LuaTeX pour les caractères constituant le `\hskip` commande.

## Comment \directlua fonctionne réellement

Maintenant que nous avons exploré les jetons, les listes de jetons et la conversion des jetons en texte, le prochain défi consiste à comprendre le concept, dans le moteur TeX, de jeton *expansion*.

Comme indiqué, `\directlua{⟨code⟩}` peut être amené à traiter `⟨code⟩` qui contient à la fois du code Lua et du code TeX/LaTeX, mais l’interpréteur Lua intégré à LuaTeX ne comprend ni TeX ni LaTeX : alors comment cela peut-il fonctionner ? Comment est-il possible pour le `⟨code⟩` de contenir des instructions TeX/LaTeX sans complètement embrouiller l’interpréteur Lua avec des commandes qu’il ne comprend pas ? Par exemple, la commande `\directlua` n’utilise que des macros TeX, mais elle fonctionne :

```
\def\aa{tex}
\def\bb{.}
\def\cc{print}
\def\dd{("Hello")}
\directlua{
   \aa\bb\cc\dd
}
```

Ce `\directlua` commande produit dans LuaTeX la composition de `Hello` mais pourquoi et comment cela fonctionne-t-il puisque le langage Lua ne comprend pas les macros TeX ?

La réponse se trouve dans la description précédente que nous avons empruntée au [Le manuel de référence LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) mais nous pouvons considérer que `\directlua{⟨code⟩}` fonctionne parce que LuaTeX « prétraite » d’abord le `⟨code⟩` avant que quoi que ce soit ne soit transmis à l’interpréteur Lua. La nature de ce « prétraitement » — c’est-à-dire ce qu’il signifie réellement et ses conséquences pour votre `⟨code⟩`— est le prochain sujet que nous aborderons pour aider les lecteurs intéressés à tirer parti de la puissance et de la flexibilité de `\directlua`.

### Comment LuaTeX traite \directlua : un premier regard

Pour approfondir notre compréhension des activités de `\directlua`de « prétraitement », nous pouvons commencer par le diagramme simplifié suivant, qui donne un aperçu de ce qui se passe. Le `⟨code⟩` fourni à `\directlua{⟨code⟩}` est d’abord converti en jetons à l’aide des processus et calculs décrits ci-dessus ; cette séquence de jetons est stockée dans une liste de jetons. Une fois cette liste de jetons constituée, chaque jeton de cette liste est reconverti dans sa représentation textuelle : le texte produit par chaque jeton — jeton de caractère ou jeton de commande — est combiné (concaténé) pour créer une seule chaîne de code transmise à l’interpréteur Lua pour exécution.

![](/files/d2bed145e2fa0c5d654457783f0075553873e8c7)

Mais attendez, quel serait l’intérêt de passer du texte aux jetons puis de reconvertir ces jetons directement en texte ? Vous ne serez peut-être pas surpris d’apprendre que, oui, il existe un processus supplémentaire et essentiel que nous n’avons pas inclus dans ce schéma : *expansion des jetons*. Chaque jeton produit à partir du texte de votre `⟨code⟩` est soumis à une forme d’« inspection » au cours de laquelle LuaTeX applique un test pour voir si ce jeton représente une commande appartenant au sous-ensemble connu sous le nom de *commandes extensibles*. Si c’est le cas, LuaTeX filtre cette commande en *supprimer* la retirant de votre `⟨code⟩` et *en la remplaçant* par le(s) résultat(s) d’un processus que les moteurs TeX appellent *expansion des jetons*.

### Comment LuaTeX traite \directlua : un deuxième regard (sur l’expansion)

Le mécanisme d’expansion de TeX est un composant essentiel de tous les moteurs de composition typographique basés sur TeX, car, en fin de compte, chacun d’eux dérive du code source et de la conception originaux de TeX par Knuth, ou en est issu. Cependant, le concept d’expansion est difficile à expliquer dans un langage à la fois concis et accessible, car, en pratique, l’expansion est un terme « parapluie » utilisé pour décrire un seul processus — mais qui produit une gamme de résultats. Ces résultats variés sont la conséquence de l’ensemble quelque peu éclectique de commandes auxquelles l’expansion peut s’appliquer ; vous pouvez donc considérer que chaque commande extensible a un certain « comportement d’expansion ».

À titre *de première approximation* pour comprendre l’expansion, nous pouvons dire que l’expansion d’un jeton (commande) signifie *supprimer* retirer cette commande (jeton) de l’entrée courante de TeX et *remplacer* la remplacer par une séquence de jetons résultant de l’exécution de cette commande extensible particulière — en remplaçant le jeton original par les résultats/conséquences de son expansion *comportement*. Cependant, cette première « définition » de l’expansion — en termes de génération de nouveaux jetons à lire par TeX — n’est pas totalement exacte pour toutes les commandes extensibles, mais elle est suffisante comme point de départ.

Pour donner un exemple simple : la primitive TeX `\jobname` est une commande extensible et son *expansion* est une séquence de jetons de caractères qui représente le nom du fichier d’entrée principal de TeX. Si TeX décide d’étendre une commande (jeton) `\jobname` elle est *retirée* de la source d’entrée courante de TeX et *remplacée* par la séquence de jetons de caractères qu’elle génère — que TeX se met alors à lire/traiter.

Dans `\directlua`LuaTeX, après qu’un jeton extensible a été traité (retiré) et remplacé par de nouveaux jetons, LuaTeX continue à lire ces nouveaux jetons qu’il vient de mettre en place — mais certains de ces nouveaux jetons peuvent aussi être extensibles. Parce que `\directlua` effectue ce qu’on appelle *l’expansion complète*, LuaTeX lira ces nouveaux jetons et, une fois de plus, passera par le processus d’expansion pour développer (retirer) tous les nouveaux jetons (extensibles) — ce processus d’expansion se poursuit jusqu’à ce qu’il ne reste plus aucun jeton extensible. Cependant, il existe deux exceptions importantes à cette règle du « continuer à développer », que nous aborderons ci-dessous :

* en utilisant le construct `\the\toks`;
* la prévention délibérée (suppression) de l’expansion pour un ou plusieurs jetons sélectionnés.

Comme indiqué, notre définition de travail (première approximation) pour comprendre l’expansion ne couvre pas toute la gamme des comportements d’expansion démontrés par le sous-ensemble des commandes extensibles. Par exemple, certaines commandes extensibles ne génèrent pas de jetons de la manière dont `\jobname` le fait, mais elles peuvent :

* « filtrer » des jetons de l’entrée : les commandes conditionnelles d’un moteur TeX (`\if`, `\ifcat`, `\ifnum`, `\ifdim`, `\ifodd`, `\ifvmode`, …) sont extensibles. Leur comportement d’expansion est une forme de « filtrage de jetons » — les conditionnels peuvent être utilisés dans `\directlua`.
* « jongler » avec les jetons de l’entrée : le [`\expandafter` commande](/latex/fr/articles-approfondis/03-a-six-part-article-series-on-expandafter-tex-tokens-and-expansion.md) est extensible et modifie l’ordre dans lequel deux jetons sont développés.
* empêcher l’expansion : les commandes extensibles `\noexpand` et `\unexpanded` suppriment l’expansion des jetons de commande dans l’entrée.
* convertir des séquences de caractères de l’entrée en jetons de commande : `\csname … \endcsname.`
* convertir des quantités internes en une séquence de jetons de caractères : `\number` et `\the` sont des commandes extensibles qui génèrent une séquence de jetons de caractères représentant la valeur d’une quantité interne.
* convertir des jetons de commande en jetons de caractères : `\string` et `\detokenize` sont des commandes extensibles qui convertissent leurs arguments en une séquence de jetons de caractères avec le code de catégorie 12. Notez que `\detokenize` diffère de `\string`: `\detokenize` peut traiter plusieurs jetons et il introduit un caractère espace, avec le code de catégorie 10, après le traitement des jetons de commande créés à partir de *mots de contrôle*. En effet, `\detokenize` ajoute un espace final après le nom de la commande — nous verrons quelques exemples plus loin dans l’article.

#### Affiner notre « définition » de l’expansion

Nous pouvons maintenant généraliser notre définition en disant que l’expansion d’une commande (jeton) implique *la suppression* de cette commande (jeton) de la source d’entrée courante de TeX et *en la remplaçant* son remplacement par le résultat de *l’opération(s) sur les jetons* effectuée(s) par cette commande. En substance, le processus d’expansion amène une commande extensible à effectuer un certain type d’« opération » sur les jetons de l’entrée courante de TeX, ce qui affecte le nombre ou le comportement des jetons que TeX lira ensuite — la nature précise de cette « opération » dépend de la commande en cours d’expansion. Toutes les macros et les caractères actifs sont extensibles, mais seul un petit nombre de commandes intégrées (primitives) d’un moteur TeX sont classées comme extensibles — la liste des commandes extensibles dépend du moteur TeX que vous utilisez.

Chaque nouveau moteur TeX hérite des commandes primitives intégrées à ses ancêtres — le ou les moteurs TeX des générations précédentes dont il dérive — et certaines de ces primitives héritées seront extensibles. Bien sûr, un nouveau moteur TeX peut choisir de ne pas implémenter certaines des commandes primitives présentes dans les moteurs antérieurs ou de modifier leur comportement pour répondre aux besoins du nouveau moteur. En outre, les nouveaux moteurs TeX implémentent généralement des primitives supplémentaires pour prendre en charge leurs propres fonctionnalités améliorées — certaines d’entre elles peuvent aussi être extensibles. Par conséquent, le nombre de commandes extensibles dont vous disposez variera selon le moteur TeX utilisé — LuaTeX en possède toute une collection.

Une autre difficulté à expliquer/comprendre l’expansion, et peut-être le véritable défi, consiste à savoir exactement *quand* un moteur TeX est, ou n’est pas, en train d’effectuer réellement le processus d’expansion. C’est un sujet vaste et complexe car l’expansion est profondément intégrée dans le fonctionnement interne des moteurs TeX : nous n’avons pas la place d’en traiter en détail au-delà de l’usage de l’expansion dans `\directlua`.

### Comment LuaTeX traite \directlua : un dernier regard

Le diagramme suivant résume les `\directlua` activités de prétraitement qui se déroulent à l’intérieur même du moteur LuaTeX. Dans ce diagramme, nous montrons aussi deux fonctions LuaTeX de bas niveau (internes) qui effectuent réellement le travail : `scan_toks()` et `tokenlist_to_cstring()`. Ces fonctions sont écrites en langage C et résident au plus profond du logiciel exécutable LuaTeX : elles font partie de la machinerie interne de LuaTeX et ne sont pas *directement* accessibles à votre code TeX/LaTeX.

![](/files/02c7dc73e007ef127f6b97e29ac4eef9257adaee)

La description suivante de `\directlua ⟨code⟩`de son activité de prétraitement résume le diagramme ci-dessus.

1. La séquence de caractères de votre ⟨code⟩ est traitée par `scan_toks()`. Son but est de lire votre ⟨code⟩ caractère par caractère afin de générer des jetons de caractères et des jetons de commande. Comme elle crée des jetons, le code de catégorie attribué à chaque caractère dans ⟨code⟩ au moment où il est lu est extrêmement important.
2. Pendant le traitement (génération) des jetons par `scan_toks()`tout jeton (commande) extensible est développé *sauf si* cela a été empêché par des commandes telles que `\protected` (définitions de macros), `\noexpand`, `\unexpanded` etc. Les caractères actifs (code de catégorie 13) sont également développés (sauf si cela est empêché).
3. Le flux de jetons créé par `scan_toks()` est assemblé en une longue liste de jetons — les jetons présents dans cette liste comprennent ceux produits par l’application de l’expansion aux commandes extensibles (telles que les macros) présentes dans votre `⟨code⟩`. Notez aussi que `scan_toks()` *ne déclenche pas* l’exécution d’un jeton représentant une commande non extensible : de tels jetons non extensibles sont simplement transmis tels quels pour être incorporés dans la liste de jetons en cours de construction.
4. Une fois la liste de jetons terminée et toute l’activité d’expansion achevée, cette liste de jetons est traitée par une autre fonction appelée `tokenlist_to_cstring()` qui convertit chaque jeton de la liste finale en sa représentation textuelle. Cela génère une chaîne de texte qui est le code Lua à transmettre à l’interpréteur Lua. Pour une exécution réussie, cette chaîne doit contenir un code Lua syntaxiquement correct.
5. Le traitement de ce code par Lua se déroule en deux étapes :
6. L’interpréteur Lua intégré à LuaTeX analyse et « compile » le code Lua généré lors des étapes précédentes. Si cette analyse/compilation échoue, l’interpréteur Lua générera des erreurs (comme des erreurs de syntaxe) — ces erreurs peuvent faire échouer l’exécution de LuaTeX, à moins que vous n’ayez choisi d’utiliser `--interaction=nonstopmode` sur la ligne de commande.
7. Si l’analyse/la compilation réussit, l’interpréteur Lua exécute le code compilé à l’étape (5a).

En substance, la fonction `scan_toks()` est le cœur des activités de prétraitement de LuaTeX : sa tâche principale est de développer toutes les commandes TeX/LaTeX extensibles contenues dans le texte de votre `⟨code⟩` et de construire une liste de jetons à partir de tout ce qu’elle a traité. Encore une fois, nous insistons sur le fait que `scan_toks()` *n’exécute pas les commandes non extensibles* (jetons) : elle *stocke* simplement ces jetons dans la liste de jetons qu’elle est en train de construire. Une fois achevée, cette liste de jetons est ensuite convertie *de nouveau en une représentation textuelle* par `tokenlist_to_cstring()`— une liste de jetons est un concept propre à TeX, totalement étranger à un interpréteur Lua ; d’où la nécessité de la convertir en texte, devenant du code Lua à transmettre à l’interpréteur Lua.

## L’expansion comme « interface » de langage de programmation

Vous pouvez considérer `\directlua`que le processus d’expansion de LuaTeX est utilisé comme un mécanisme, ou une interface, pour transférer des données/informations du « monde TeX » vers le « monde Lua » : fournir une méthode au langage TeX pour communiquer des données au langage Lua. Par exemple, du code TeX tel que `\number\count75` peut être utilisé pour transférer une valeur du « monde TeX » stockée dans le registre de compte 75 vers la variable entière x du « monde Lua » :

```
\count75=1564 % Données existant dans le « monde TeX »
\directlua{
   local x=\number\count75 \space % Transfert des données TeX vers le « monde Lua »
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" et y = "..y)
}
```

Cela génère le code Lua

```
 local x=1564 tex.print("x= "..x) local y = (2*x-65)/5 tex.print(" et y = "..y)
```

**Remarque**: Nous avons ajouté `<space>\space` après `\number\count75` pour garantir qu’un caractère espace soit conservé entre `1564` et `tex.print`— ce n’est pas strictement nécessaire ici, car Lua analyserait quand même le code correctement si nous l’omettons. Le caractère espace qui suit immédiatement `\count75` est absorbé pendant le processus que les moteurs TeX utilisent pour rechercher des valeurs numériques — ici, la valeur fournie à `\count`. Le caractère espace après `75` est utilisé pour terminer la recherche de LuaTeX de la suite de chiffres `75` et est absorbé de l’entrée. La macro `\space` développe afin de fournir le caractère espace nécessaire pour séparer le texte `1564` et `tex.print`.

En utilisant le code ci-dessus, LuaTeX composera

`x= 1564 et y = 612.6`

Ici, le mécanisme de « transmission de données » est réalisé par `\number`: une commande extensible qui, dans cet exemple, ordonne à TeX de récupérer la valeur stockée dans `\count` registre de TeX `75` et, à partir de cette valeur (`1546`), de générer une série de jetons de caractères, un jeton de caractère pour chaque chiffre, ce qui donne une séquence de jetons pour les chiffres `1`, `5`, `6` et `4`. Ces 4 jetons de caractères sont incorporés dans la liste principale de jetons en cours de construction par `\directlua` et sont ensuite reconvertis dans leur représentation textuelle lorsque la liste de jetons est convertie en texte. C’est sans aucun doute un détour très sinueux, allant de la `\count75` valeur du registre stockée à l’intérieur de LuaTeX jusqu’aux chiffres destinés au code Lua, mais, au final, cela fonctionne.

**CONSEIL :** Si vous souhaitez inspecter les résultats des activités d’expansion de LuaTeX, vous pouvez écrire du code comme ceci :

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" et y = "..y)]]
   print(foo)
}
```

Dans cet exemple, nous utilisons la méthode des crochets longs pour créer une variable chaîne `foo` dont le but est de contenir la chaîne de code Lua générée à partir de l’expansion de tout ce qui se trouve entre `[[` et `]]`. Cette chaîne est imprimée dans la console via l’appel de la fonction Lua `print(foo)`.

Sur Overleaf, vous pouvez voir des résultats similaires en écrivant le contenu de `foo` dans le `.log` fichier à l’aide de la fonction LuaTeX Lua `texio.write()`:

```
\directlua{
   local foo=[[local x=\number\count75
   tex.print("x= "..x)
   local y = (2*x-65)/5
   tex.print(" et y = "..y)]]
   texio.write(foo)
}
```

## Jetons dans la liste de jetons \directlua : jetons non extensibles et jetons non développés

Nous avons noté que `\directlua{⟨code⟩}` effectue *l’expansion complète* de votre `⟨code⟩`: elle retire et développe toutes les commandes extensibles jusqu’à ce qu’il ne reste plus que des jetons non extensibles. La séquence de jetons créée par `\directlua`le traitement de `scan_toks()` (dans la fonction

a été assemblée en une liste de jetons dont les jetons individuels seront reconvertis en texte pour être transmis à Lua. Cependant, nous n’avons pas encore abordé la dernière partie de cette histoire, car nous devons considérer les deux « classes » de jetons de commande qui peuvent parvenir jusqu’à la liste de jetons en cours de construction dans `\directlua`: nous les appellerons *jetons de commande abrégés* et *non développés* jetons :

* **jetons de commande abrégés**: Ce type de jeton de commande provient de séquences de contrôle définies à l’aide de l’une des primitives TeX `\chardef`, `\mathchardef`, `\countdef`, `\dimendef`, `\skipdef`, `\muskipdef` et `\toksdef`. Ces commandes primitives sont utilisées pour définir des séquences de contrôle qui représentent une valeur numérique — les séquences de contrôle résultantes sont *ne* extensibles.
* **jetons non développés**: Ce type de jeton provient de commandes qui seraient normalement développées mais `\directlua` a soit :
* été explicitement instruite *ne* à les développer ; par exemple, la suppression de l’expansion par les commandes `\noexpand` ou `\unexpanded`— nous expliquerons bientôt comment cela se fait ;
* jetons injectés en traitant la séquence `\the\toks` (plus d’informations à ce sujet ci-dessous).

### Deux « groupes » de jetons dans une liste de jetons \directlua

Sur la base de nos discussions, nous pouvons dire que les jetons contenus dans la liste de jetons en cours de construction pendant la première étape de `\directlua`de prétraitement de `scan_toks()` (dans la fonction

1. *intrinsèquement non extensibles* jetons

* tout jeton représentant un caractère non actif *suivant*;
* tout jeton représentant une *primitive non extensible* *commande*;
* tout jeton représentant un *jeton de commande abrégée* (ceux-ci ne sont pas extensibles, voir ci-dessous).

3. *non développés* jetons :

* tout jeton représentant une commande extensible dont l’expansion a été *supprimée* (ou évitée) pendant le prétraitement de `\directlua`.

#### Jetons de commande abrégés : création de commandes non extensibles

Comme indiqué, les moteurs TeX fournissent un ensemble de primitives (commandes intégrées) qui peuvent être utilisées pour construire *non extensibles* séquences de contrôle (indiquées ici par `⟨commande⟩`). Ces primitives prennent la forme suivante :

* `\chardef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\mathchardef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\countdef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\dimendef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\skipdef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\muskipdef ⟨commande⟩ = ⟨valeur numérique⟩`
* `\toksdef ⟨commande⟩ = ⟨valeur numérique⟩`

où `⟨valeur numérique⟩` est une certaine valeur entière appropriée à chaque commande.

Ici, nous allons brièvement passer en revue l’utilisation de `\chardef` pour démontrer la caractéristique clé de ces primitives — produire une `⟨commande⟩` qui est non extensible. Vous pouvez utiliser ``\chardef\mydollar=`\$`` pour créer la séquence de contrôle `\mydollar` et l’utiliser pour composer un `$`:

`J’ai payé \mydollar30.`

Cela composera `J’ai payé 30 $.` La séquence de contrôle `\mydollar` créée par `\chardef` n’est pas extensible, comme on peut le voir dans l’exemple suivant :

```
\chardef\mydollar=`\$
\directlua{
   local x =[[J’ai payé \mydollar30.]]
   texio.write(x)
}
```

Ce qui produit le texte suivant dans le `.log` modifiable

`J’ai payé \mydollar 30.`

Cela montre `\mydollar` a été *ne* développé pendant le prétraitement de `\directlua`de LuaTeX. L’espace apparaissant après `\mydollar` est ajouté lorsqu’un jeton de commande est converti dans sa représentation textuelle.

Lorsque vous utilisez `\chardef` pour créer une séquence de contrôle, la classification interne de cette séquence de contrôle (commande) par TeX fait qu’elle est *non extensibles* ce qui est un comportement très différent de celui des séquences de contrôle définies par l’une des commandes de définition de macro : \def, \edef, \gdef ou \xdef. Comme indiqué ci-dessus, lors du processus de construction de sa liste de jetons `\directlua` examine chaque jeton de commande entrant pour vérifier son extensibilité. Si un jeton de commande n’est pas extensible, il passe directement dans la liste de jetons et sa représentation textuelle réapparaîtra plus tard dans la chaîne de code Lua résultant de la conversion des jetons de la liste de jetons en leur forme textuelle.

**Brèves notes sur plain TeX vs. LaTeX**

Historiquement, le plain TeX original de Knuth définissait les symboles de contrôle couramment utilisés `\%`, `\&`, `\#` et `\$` en utilisant `\chardef`— sans utiliser l’une des commandes standard de définition de macro `\def`, `\edef`, `\gdef` ou `\xdef`. Par exemple :

```
   \chardef\#=`\#
   \chardef\$=`\$
   \chardef\%=`\%
   \chardef\&=`\&
```

La curieuse `` `\ `` syntaxe est une méthode TeX pour obtenir la valeur numérique du code de caractère. Dans l’ancien régime plain TeX, ces symboles de contrôle ne sont pas extensibles (à cause de `\chardef`) mais LaTeX (ou des paquets) peut les redéfinir comme *macros* pour fournir des fonctionnalités améliorées — cela les rendrait extensibles, donc il faut en être conscient.

**Comment cela affecte-t-il \directlua ?**

Comparons le résultat du code suivant exécuté sous plain TeX et sous LaTeX. Pour simplifier, nous écrirons les résultats dans le fichier `.log` en utilisant la fonction API Lua LuaTeX `texio.write()`.

```
\directlua{
   local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]]
   texio.write(x)
}
```

En exécutant ce code avec **plain TeX** produit le texte de sortie suivant dans le fichier `.log` montrant le résultat de toutes les expansions :

```
\$150 pour le produit "\#1"---20\%! de plus que son concurrent, Widget \& Co.
```

Clairement, sous plain TeX, aucun des symboles de contrôle`\$`, `\#`, `\%` ou `\&` n’ont pas été développés — parce qu’ils sont tous créés à l’aide de `\chardef`.

L’exécution de ce code en utilisant **LaTeX** document :

```
\documentclass{article}
\begin{document}
   \directlua{local x=[[\$150 for the "\#1" product---20\%! more than its competitor, Widget \& Co.]] texio.write(x)}
\end{document}
```

produit le texte de sortie suivant dans le fichier `.log` modifiable

```
\protect \TU\textdollar 150 pour le produit "\#1"---20\%! de plus que son concurrent, Widget \& Co.
```

Clairement, l’exécution de LaTeX génère un résultat différent de plain TeX car sous LaTeX la commande `\$` a été développée, ce qui indique qu’il s’agit d’une macro.

**Remarque :** Dans plain TeX comme dans LaTeX `\directlua` n’a pas traité entièrement l’un quelconque des symboles de contrôle `\%`, `\&`, `\#` et `\$` pour générer le caractère correspondant. Pendant le processus de développement effectué par `\directlua` les jetons représentant ces symboles de contrôle — ou, pour LaTeX, leur développement — passent directement dans la liste principale de jetons en cours de construction.

**Remarque :** Les symboles de contrôle sont formés à partir d’un seul caractère dont le code de catégorie n’est pas 11, comme `\#`. Lorsqu’un jeton représentant un symbole de contrôle est reconverti en sa représentation textuelle, les moteurs TeX n’insèrent pas d’espace après ce texte. Ce traitement spécial des symboles de contrôle est une règle intégrée au fonctionnement des moteurs TeX.

### Jetons non développés : suppression du développement

`\directlua`Le prétraitement de ’s est un exemple où un moteur TeX effectue un développement, mais vous voudrez peut-être *empêcher* l’application du développement à un ou plusieurs jetons qui, autrement, seraient développés. À titre d’autre exemple, LuaTeX (et tous les moteurs TeX) effectuent un processus de développement, similaire à celui de `\directlua`, lorsqu’ils traitent `\write` commande :

`\write file-number {⟨material⟩}`

\write ordonne à un moteur TeX de produire `⟨material⟩`—souvent contenant des commandes TeX/LaTeX—dans un fichier texte (`numéro de fichier`); toute commande développable à l’intérieur de `⟨material⟩` sera, sauf si on l’en empêche, développée avant que `⟨material⟩` soit effectivement écrite dans ce fichier.

Comme vous pouvez vous y attendre, les moteurs TeX fournissent des commandes pour supprimer ou contrôler le développement :

* `\noexpand⟨token⟩`: empêche le développement du seul `⟨token⟩`;
* `\unexpanded{⟨material⟩}`: empêche le développement de toutes les commandes développables (jetons) dans `⟨material⟩`. C’est, en pratique, une version multi-jetons de `\noexpand`;
* `\protected`: un préfixe ajouté aux définitions de macros qui empêche le développement de cette macro dans certaines circonstances (par exemple lors de `\directlua`, `\write` ou `\edef`).

Malgré des noms qui suggèrent le contraire, à la fois `\noexpand` et `\unexpanded` le sont *commandes extensibles* et offrent de bons exemples de la façon de considérer le processus de développement d’un moteur TeX comme effectuant des « opérations sur les jetons » : l’opération ici consiste à empêcher le développement d’un ou plusieurs jetons suivants (commandes). Parce que `\noexpand` et `\unexpanded` sont toutes deux des commandes développables, elles sont retirées et traitées (exécutées) pendant `\directlua`le prétraitement de ’s lors de la construction de la liste de jetons à partir de votre `⟨code⟩`.

#### \noexpand ⟨token⟩

`\noexpand ⟨token⟩` empêche le développement du seul `⟨token⟩`. `\noexpand` dans `\directlua` sera développé (retiré de l’entrée) et remplacé par les résultats de son « comportement de développement ». Le résultat du développement de `\noexpand` est de créer un `⟨jeton marqueur⟩` spécial (caché) `⟨token⟩` qui est placé devant l’original `⟨jeton marqueur⟩` dont le développement doit être supprimé : ce `\directlua` agit comme un indicateur disant « ne pas développer le jeton suivant ». Parce que `\noexpand ⟨token⟩` effectue un développement complet, il retraitera tous les jetons qui résultent du « comportement de développement » d’une commande développable. Par conséquent, lorsque le développement de `⟨jeton marqueur⟩⟨token⟩` est terminé, LuaTeX revient lire les résultats et voit la séquence de deux jetons `⟨token⟩` qui fait passer l’original `\directlua`.

**Exemple**

Si nous écrivons

```
\directlua{
   local x= "\TeX"
}
```

le `\TeX` la macro est développée en ses jetons constitutifs qui, en plain TeX, entraîneront le passage du texte suivant à Lua (remarque : Lua ne peut pas traiter ce code, c’est juste un exemple pour démontrer le processus) :

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Si nous *suspendons* le développement de la `\TeX` macro à l’aide de `\noexpand`

`\directlua{local x= "\noexpand\TeX"}`

le code Lua suivant est produit (là encore, Lua ne peut pas exécuter ce code ; il s’agit simplement d’un exemple pour démontrer `\noexpand`):

`local x= "\TeX "`

À cause de `\noexpand`, `\directlua` ne développera pas `\TeX` mais laissera simplement la valeur de jeton représentant la `\TeX` commande passer, indemne, dans la liste de jetons construite lors de la première étape de `\directlua`.

**Remarque :** L’espace apparaissant après `\TeX` est introduit par la conversion ultérieure par LuaTeX du `\TeX` valeur de jeton entière de nouveau vers sa représentation textuelle (dans la `tokenlist_to_cstring()` fonction).

#### \unexpanded{⟨material⟩}

`\unexpanded` est une commande développable qui supprime le développement de tous les jetons formés à partir de `⟨material⟩`. Comme nous l’avons noté, lorsqu’un moteur TeX effectue un développement, toute commande développable est *retirée* retirée de l’entrée et *remplacée* remplacée par les résultats de son « comportement de développement » ; alors qu’est-ce que cela signifie réellement pour `\unexpanded`? Généralement, pendant *l’expansion complète*, une fois le processus de développement d’une commande particulière terminé, le moteur TeX continue à lire/traiter tous les jetons issus du « comportement de développement » de cette commande — il doit développer davantage tous les jetons produits. Cependant, `\unexpanded` *contourne* tout développement supplémentaire : voici comment il fait cela.

À l’intérieur du moteur TeX, la `\unexpanded` commande convertit d’abord les caractères et les commandes de `⟨material⟩` en une liste temporaire de jetons composée de *non développés* jetons. Après que tous les jetons ont été créés et stockés dans cette liste temporaire, la `\unexpanded` commande fait en sorte que `\directlua` à *sauter* le retour en arrière pour les relire et les traiter — même si \directlua effectue un développement complet. À la place, ces *non développés* jetons passent directement et sont incorporés dans la liste principale de jetons en cours de construction par `\directlua` (dans la `scan_toks()` fonction). De cette façon, tout ce qui se trouve dans `⟨material⟩` est converti en jetons et le processus de développement est omis pour cet ensemble de jetons. Le fonctionnement de `\unexpanded{⟨material⟩}` est similaire à l’utilisation de `\the\toks`, que nous discutons ci-dessous.

**Exemple**

`\unexpanded` produit des résultats d’une manière similaire à `\noexpand` sauf qu’il peut empêcher le développement de plusieurs jetons ; voici un exemple :

```
\directlua{
   local x = "\unexpanded{\foo\bar\foobar}. But Lua can't process this code!"
}
```

ce qui produit le texte suivant comme code pour Lua :

`local x = "\foo \bar \foobar . But Lua can't process this code!"`

**Remarque**: il y a des espaces après chaque nom de commande. Ceux-ci sont encore une conséquence de la conversion ultérieure par LuaTeX des jetons non développés `\foo`, `\bar` et `\foobar` en texte dans la `tokenlist_to_cstring()` fonction.

#### définitions de macros protégées

Le `\protected` commande est un préfixe appliqué à une définition de macro pour empêcher que cette macro soit développée lorsque TeX construit une liste de jetons développée, telle que la liste de jetons construite par `\directlua`.

**Exemple**

Supposons que vous définissiez les macros suivantes avec et sans utiliser le `\protected` préfixe :

```
\def\macroA{"This unprotected macro contains a string"}
\protected\def\macroB{"This protected macro also contains a string"}
```

Si vous utilisez l’opérateur de concaténation de chaînes de Lua (`..`) pour écrire

```
\directlua{
   local x=\macroA..\macroB
}
```

`\directlua`le prétraitement de ’s produirait le code suivant à transmettre à Lua :

`local x="This unprotected macro contains a string"..\macroB`

`\macroA` n’est pas définie avec `\protected` donc elle est développée, produisant la première partie de la chaîne à concaténer, mais `\macroB` est définie avec `\protected` donc elle n’a pas été développée.

Pendant le prétraitement, la `scan_toks()` fonction de LuaTeX a créé un jeton pour `\macroA`, a reconnu qu’il s’agissait d’une commande développable ordinaire et l’a développée : ce développement produit une séquence de jetons de caractères, un jeton de caractère pour chaque caractère de `"This unprotected macro contains a string"`. Chaque jeton de caractère est transmis et ajouté à la liste de jetons en cours de construction.

Lorsque `scan_toks()` crée le jeton pour `\macroB` elle remarque que cette commande a été définie comme `\protected` et ne la développe pas : le jeton représentant `\macroB` passe, intact (non développé), dans la liste de jetons en cours de construction. Une fois cette liste de jetons construite, l’étape suivante du prétraitement, dans la `tokenlist_to_cstring()` fonction, consiste à reconvertir tous les jetons de la liste en leur représentation textuelle. Le jeton non développé représentant `\macroB` est détecté et converti en sa représentation textuelle, ce qui donne le texte `\macroB` apparaissant dans le code destiné à Lua. Notez que Lua ne peut pas réellement concaténer `"This unprotected macro contains a string"..\macroB` pour produire la chaîne finale parce que `\macroB` n’a aucune signification dans la syntaxe de Lua, ce qui entraîne l’erreur `unexpected symbol near '\'`.

**Anecdote**: Le `\protected` commande a été introduite par $$\varepsilon\text{-}\mathrm{\TeX}$$, la première extension majeure du logiciel TeX original de Knuth, et est prise en charge par tous les moteurs TeX dont la lignée de code inclut $$\varepsilon\text{-}\mathrm{\TeX}$$.

### Jetons non développés : utilisation de \the\toks dans \directlua

La vie en programmation ne serait pas la même sans ces « cas particuliers » à gérer et l’utilisation de `\the` conjointement avec `\toks` dans une `\directlua` commande est un de ces cas particuliers.

#### Bref aperçu de \toks

La primitive TeX `\toks` ordonne à un moteur TeX de conserver certains jetons pour une utilisation ultérieure : au lieu d’être transmis pour traitement ultérieur, ces jetons sont mis de côté et stockés dans un emplacement mémoire spécifié à l’aide d’un *registre de jetons*. Par exemple, on peut dire à un moteur TeX de créer certains jetons et de les stocker dans l’emplacement du registre de jetons `100` en utilisant

`\toks100={Hi, \TeX! \hskip 5bp}`

Ici, TeX utilise le registre de jetons `100` pour accéder à un emplacement connu dans sa mémoire : une zone de stockage désignée pour contenir des listes de jetons.

Les jetons représentant tout ce qui se trouve entre le `{` et `}` sont créés, *mais non développés*, et assemblés dans une liste de jetons — similaire à la liste de jetons que nous avons explorée plus tôt dans cet article. Pour réutiliser ces jetons, nous écririons `\the\toks100` dans lequel `\the` (une commande développable) ordonne à TeX de récupérer les jetons stockés et de les insérer à l’emplacement où vous avez écrit `\the\toks100`. Une autre façon de voir cela est que `\the\toks` fait insérer à TeX des jetons à cet emplacement.

Le `\toks` commande *ne développe pas* aucun des jetons qu’on lui demande de créer et d’enregistrer : il convertit simplement les caractères et les commandes entre `{` et `}` en jetons et les stocke.

#### Retour à \directlua

Dans la discussion sur le développement, nous avons noté `\directlua{⟨code⟩}` effectue *l’expansion complète* de `⟨code⟩`: supprimer toutes les commandes développables et les remplacer par le résultat de leur comportement de développement — en continuant à *développer davantage* tous les jetons résultant du développement initial d’une commande développable.

`\the` est une commande développable, donc `\directlua` le développera ; cependant, lorsque `\the` est utilisé conjointement avec `\toks` dans `\directlua`, comme dans `\the\toks⟨token register⟩`, les jetons insérés ne sont *pas développés davantage*. Le développement de `\the\toks⟨token register⟩` injecte la séquence de *non développés* jetons, stockée dans `⟨token register⟩`, directement dans la liste de jetons en cours de construction par `\directlua`: ce comportement contourne le processus habituel de développement complet. En effet, ces jetons passent, *non développés*, pour être incorporés dans la liste principale de jetons en cours de construction par `\directlua`—ce processus de passage pour les jetons non développés est similaire dans son fonctionnement à `\unexpanded`, comme discuté précédemment.

**Exemple**

Supposons que nous définissions la macro `\mymacro` comme `\def\mymacro{\TeX}`. Elle ne contient qu’un seul jeton pour la `\TeX` commande (qui est une macro) : nous avons donc une commande développable `\mymacro` qui contient une autre macro `\TeX`, qui est également développable.

Le code suivant amènera Lua à essayer de créer une variable chaîne `x`:

```
\def\mymacro{\TeX}
\directlua{
   local x="\mymacro"
}
```

Dans \\`directlua`, le jeton pour `\mymacro` est développé mais cela donne un autre jeton développable, `\TeX`, qui est développé davantage. En plain TeX, ces développements donnent le texte suivant transmis à Lua :

`local x = "T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX"`

Ce code tente de définir une chaîne qui contient un texte représentant la version développée de la `\TeX` macro. Si vous essayez d’exécuter cet exemple, Lua tentera de construire cette chaîne mais échouera, générant une erreur :

`séquence d’échappement invalide près de ' "T\k'.`

Plus loin dans cet article, nous explorerons la signification de « invalid escape sequence ».

Contrastons maintenant l’utilisation de `\mymacro` avec le fait de placer le `\TeX` jeton à l’intérieur d’une liste de jetons générée par un `\toks` commande :

```
\toks100={\TeX}
\directlua{
   local x="\the\toks100"
}
```

Le `\directlua` traitement de LuaTeX générera cette chaîne de texte pour Lua :

`local x = "\TeX "`

L’espace après `\TeX` est généré par le processus de conversion commande-vers-texte de LuaTeX.

**Mais notez**: Le `\TeX` la macro a *ne* été développée en ses jetons constitutifs. `\the\toks100` a provoqué l’insertion des jetons stockés dans le registre 100, mais c’est tout : ils ne sont *ne* pas développés davantage et sont incorporés dans la liste principale de jetons en cours de construction par `\directlua` (dans la fonction `scan_toks()`). Mettre des jetons dans une liste de jetons créée par `\toks` est une autre façon d’empêcher le développement des jetons.

Si nous exécutons cet exemple, lui aussi produit une erreur :

`séquence d’échappement invalide près de ' "\T'.`

Nous explorerons plus tard dans l’article les séquences d’échappement Lua.

## Autres commandes/techniques utilisées dans le développement

Dans cette section, nous examinons quelques commandes/méthodes TeX supplémentaires qui peuvent être utiles dans les situations où le développement est appliqué (comme dans `\directlua`).

### \string ⟨token⟩

`\string` est une commande développable qui convertit le ⟨token⟩ en une série de jetons de caractères, chacun avec un code de catégorie 12.

Par exemple, `\string\TeX` produirait une série de 4 jetons de caractères `\`, `T`, `e` et `X` où chaque caractère se voit attribuer le code de catégorie 12 (y compris le caractère `\` initial).

Si nous écrivons

```
\directlua{
   local x="I will use \string\newcommand"
   print(x)
}
```

le `\string` commande sera développée, entraînant une séquence de jetons de caractères avec le code de catégorie 12. Après `\string` est développé, les jetons de caractères résultants (représentant chaque caractère dans `\newcommand`) seront incorporés dans la liste principale de jetons en cours de construction par `\directlua`. Une fois `\directlua` a terminé la construction de sa liste principale de jetons, ses jetons constitutifs sont reconvertis dans leur représentation textuelle, ce qui produit le code suivant à transmettre à l’interpréteur Lua :

`local x="I will use \newcommand" print(x)`

Lorsque ce code est transmis à Lua, `print(x)` affichera la chaîne `x` à l’écran (console). Cependant, nous avons légèrement rusé et utilisé délibérément un exemple de commande commençant par `\n`. Si vous pouvez exécuter cet exemple sur une installation TeX locale, vous remarquerez que Lua affiche le texte suivant à l’écran :

```
   J’utiliserai
   ewcommand
```

Pour exécuter ce code sur Overleaf, vous pouvez demander à LuaTeX d’écrire directement dans le `.log` en utilisant la fonction API Lua LuaTeX `texio.write(*string*)`:

```
\directlua{
   local x="I will use \string\newcommand"
   texio.write(x)
}
```

Si vous inspectez le `.log` fichier résultant, vous verrez qu’il contient aussi

```
   J’utiliserai
   ewcommand
```

Cette sortie inattendue est due à l’interprétation par Lua du `\n` au début de `**\n**ewcommand` comme la séquence d’échappement du caractère de saut de ligne (code de caractère 10) : Lua suppose que vous voulez commencer une nouvelle ligne de texte qui commence par `ewcommand`. Nous abordons plus tard dans cet article les séquences d’échappement Lua.

### \detokenize{⟨material⟩}

`\detokenize` est, dans ses effets, une version multi-jetons de `\string` et c’est aussi une commande développable qui convertit tout ce qui se trouve dans `⟨material⟩` en une séquence de jetons de caractères avec le code de catégorie 12 —*sauf* les caractères d’espace (valeur ASCII/Unicode 32) qui obtiennent le code de catégorie 10. `\detokenize` insère aussi un caractère d’espace terminal après les noms de commande qui sont *mots de contrôle* (par exemple, `\foo`) mais aucun caractère d’espace n’est inséré après *symboles de contrôle* (par exemple, `\#`, `\%` etc).

### Exemple

Même si les macros `\foohoo`, `\foo`, `\bar` et `\foobar` ne sont pas définies, si vous écrivez ceci :

```
\directlua{
   local x = "\string\foohoo\detokenize{\foo\bar\foobar}"
}
```

cela produirait le texte suivant comme code à transmettre à l’interpréteur Lua

`local x = "\foohoo\foo \bar \foobar "`

Si vous n’utilisez pas `\string` et `\detokenize` et écrivez :

`\directlua{local x = "\foohoo\foo\bar\foobar"}`

`\directlua` traiterait `\foohoo`, reconnaîtrait qu’il s’agit d’une commande et essaierait de la développer ; mais comme `\foohoo` n’est pas définie, cela entraînerait une erreur :

```
   ! Séquence de contrôle indéfinie.
   l.1 \directlua{local x = "\foohoo
                      \foo\bar\foobar"}
         ?
```

Parce que `\string` et `\detokenize` convertissent leurs arguments en une série de jetons de caractères, `\directlua`le processus de développement a bien l’occasion de détecter les jetons de commandes développables `\foohoo`, `\foo`, `\bar`, ou `\foobar`: ils sont transformés en séquences de jetons de caractères bien avant de pouvoir déclencher le développement.

Comme indiqué précédemment, le développement d’une commande consiste à la retirer de l’entrée et à la remplacer par le résultat de son « comportement de développement ». Les résultats du développement (généralement des jetons) sont ensuite lus par le moteur TeX. Ici, le « comportement de développement » pour `\string` et `\detokenize` consiste à absorber les jetons de caractères et de commandes de l’entrée et à les convertir en séquences de jetons de caractères, d’abord stockées dans une liste temporaire de jetons, que `\directlua` lit ensuite. Ces jetons de caractères sont incorporés dans la liste principale de jetons en cours de construction par `\directlua`.

Le graphique suivant montre comment `\string` convertit la `\foohoo` commande en une séquence de jetons de caractères, produisant une liste temporaire de jetons qui est ensuite lue par `\directlua` pour incorporer ces jetons de caractères dans la liste principale de jetons en cours de construction.

![](/files/3cab2ee2422f52577cc1db5658587b9001753ae3)

Si `\string` ou `\detokenize` rencontrent des caractères dans leur argument, par exemple, `\string a` ou `\detokenize{abc}` ces caractères (ici, avec le code de catégorie 11) produisent des jetons de caractères mais avec le code de catégorie 12.

Remarques :

Si nous revenons à l’exemple ci-dessus :

`\directlua{local x = "\string\foohoo\detokenize{\foo\bar\foobar}"}`

qui produit le texte suivant comme code à transmettre à l’interpréteur Lua

`local x = "\foohoo\foo \bar \foobar "`

nous pouvons observer ce qui suit :

* `\detokenize` a inséré un caractère espace après chaque nom de macro, mais `\string` ne l’a pas fait.
* `\string` agit sur un seul jeton.
* Dans la chaîne `"\foohoo\foo \bar \foobar "` utilisé pour définir `x` nous rencontrerons à nouveau le mécanisme de caractères d’échappement de Lua (abordé ci-dessous) :

  * `\bar` commence par `\b` qui est la séquence d’échappement Lua utilisée pour représenter le [caractère de retour arrière](https://en.wikipedia.org/wiki/Backspace) (code caractère 8) ;
  * commandes `\foohoo`, `\foo` et `\foobar` commence entièrement par `\f`, la séquence d’échappement Lua utilisée pour représenter le [caractère de saut de page](https://en.wikipedia.org/wiki/Page_break#Form_feed) (code caractère 12).

  Parce que les séquences de caractères `\b` et `\f` sont utilisées dans une chaîne créée avec des guillemets doubles `"..."` elles produiront des résultats indésirables, à moins de prendre des mesures pour l’empêcher au moyen de ce que Lua appelle *crochets longs* méthode de chaîne : un sujet que nous pouvons maintenant aborder avec les séquences d’échappement Lua.

## Que sont les « séquences d’échappement Lua » ?

Les langages de programmation réservent certains caractères à un « usage spécial » dans le cadre de la syntaxe du langage : en effet, ces caractères sont définis comme ayant une forme de signification spéciale. Il arrive toutefois que vous deviez temporairement « désactiver » la signification spéciale d’un tel caractère si, par exemple, vous voulez l’incorporer dans une chaîne plus longue où son comportement standard introduirait des erreurs de syntaxe. En substance, ce caractère doit être traité *sans* sans déclencher son interprétation standard — afin de passer inaperçu. Pour ce faire, les programmeurs utilisent une technique appelée *échappement* dans laquelle un « caractère spécial » est représenté par sa prétendue *séquence d’échappement*.

Un exemple standard (également pris en charge par Lua) consiste à utiliser des guillemets doubles dans une chaîne, en échappant les guillemets doubles internes avec la séquence d’échappement `\"`:

`"Lorsqu’on leur a demandé leur avis sur LuaTeX, ils ont répondu : \"C’est un formidable moteur TeX !\" J’étais d’accord."`

Le langage Lua fournit plusieurs mécanismes pour travailler avec les séquences d’échappement :

* des séquences standard, notamment `\n` (nouvelle ligne), `\r` (retour chariot), `\\` (barre oblique inverse), `\"` (guillemet double), `\t` (tabulation horizontale), `\v` (tabulation verticale) et `\'` (guillemet simple) ;
* `\xXX`, où `XX` est une séquence d’exactement deux chiffres hexadécimaux ;
* `\ddd`, où `ddd` est une séquence d’au plus trois chiffres décimaux ;
* au moment de la rédaction de cet article (août 2019), la dernière version de LuaTeX, bien qu’elle ne soit pas encore disponible sur Overleaf, utilise la version 5.3 de Lua, qui a introduit la prise en charge des séquences d’échappement UTF-8 : `\u{XXX}`. Ce mécanisme d’échappement concerne les caractères Unicode encodés en UTF-8, où `XXX` est une séquence d’un ou plusieurs chiffres hexadécimaux représentant le point de code du caractère. Notez que les crochets englobants `{ }` sont obligatoires.

### Contrôle des séquences d’échappement

Traditionnellement, les chaînes sont définies à l’aide de guillemets doubles, comme dans `"this is a string"`; dans une telle chaîne, vous pouvez utiliser des séquences d’échappement : `"this is a string.\nI'll now start on a new line."`. Cependant, Lua possède un second mécanisme *très* pratique pour définir des chaînes : son mécanisme dit *crochets longs* dans lequel vous définissez une chaîne en entourant le texte de `[[` et `]]`:

`[[I am a long brackets string]]`

Dans une chaîne créée à l’aide de la méthode des crochets longs, le mécanisme d’échappement de caractères de Lua est *désactivé*: les séquences d’échappement sont traitées comme des caractères ordinaires. Par exemple, dans la chaîne

`[[I am a long brackets\n string]]`

le `\n` la séquence d’échappement n’est pas traitée comme le caractère unique de retour chariot (code ASCII 13), mais comme deux caractères ordinaires : `\` suivi de `n`.

### Pourquoi les chaînes à crochets longs sont-elles si utiles ?

Comme nous l’explorerons plus tard, LuaTeX fournit un ensemble de fonctions Lua spécialisées et intégrées que vous pouvez utiliser avec `\directlua` pour contrôler le comportement de composition de LuaTeX. Parmi ces nombreuses fonctions se trouve une fonction appelée `tex.print(*string*)` qui vous permet de transmettre du contenu `*string*` depuis le code Lua vers LuaTeX pour la composition. Un exemple très simple est :

`\directlua{tex.print("Hello, World!")}`

ce qui amènera LuaTeX à composer `Hello, World!`

Le `*string*` utilisé dans `tex.print(*string*)` peut également inclure du texte représentant des commandes TeX et LaTeX à traiter par LuaTeX. Cependant, les commandes TeX/LaTeX commencent par un caractère `\` ce qui est problématique avec les chaînes créées à l’aide de guillemets doubles, car Lua essaierait d’analyser la chaîne, détecterait le caractère initial `\` et l’interpréterait comme le début d’une séquence d’échappement. Lorsque Lua essaie de traiter cette séquence, il échoue généralement, car le caractère initial `\` combiné au premier caractère de nombreux noms de commandes TeX/LaTeX ne forme pas une séquence d’échappement valide connue de Lua. Par exemple, lors du traitement d’une chaîne telle que `"I like \LaTeX"` Lua verrait `\L` et échouerait avec l’erreur « invalid escape sequence », ce qui est la cause des erreurs mentionnées ci-dessus.

#### Les chaînes à crochets longs viennent à la rescousse !

La méthode des crochets longs pour créer (définir) des chaînes est extrêmement utile, car même si les commandes TeX/LaTeX commencent par un caractère `\` la méthode des chaînes à crochets longs désactive le mécanisme de séquences d’échappement de Lua. Voici un court exemple, en gardant à l’esprit que nous devons empêcher l’expansion des macros en utilisant, par exemple, `\protected` ou `\noexpand`.

Supposons que nous définissions une macro `\newtest` comme ceci

`**\protected**\def\newtest#1{The argument: #1}`

et que nous l’utilisions dans `\directlua` avec la fonction API Lua de LuaTeX `tex.print()`:

```
\directlua{
   tex.print("\newtest{Hello}")
}
```

En raison de l’utilisation de `\protected`, la macro `\newtest` n’est pas développée, ce qui donne le texte suivant transmis à Lua :

`tex.print("\newtest {Hello}")`

Le caractère espace ajouté après `\newtest` et avant l’accolade ouvrante (`{`) est un effet secondaire de la `\directlua`conversion des jetons de commande en leur représentation textuelle.

Ce code est transmis à Lua, qui exécute ensuite la fonction LuaTeX `tex.print()` mais il y a un problème qui se manifeste de différentes manières selon les polices que vous utilisez. Dans LaTeX sur Overleaf, vous verriez une sortie comme celle-ci :

![](/files/a269128d41b31adef6b7ec666ef68413cd59679d)

accompagnée d’un avertissement dans le fichier journal :

```
   Caractère manquant : il n’y a pas de
   (U+000A) dans la police [lmroman10-regular]:+tlig;!
```

En plain TeX, vous pourriez voir une sortie qui ressemble à ceci :

![](/files/5dbb1a1e134a9d2cfaf6470b04c82fbce0e238b1)

Dans les deux cas, la `\newtest` macro n’est pas appelée et la sortie n’est pas celle que nous voulions. L’erreur est causée par le mécanisme de caractère d’échappement de Lua : dans le texte `\newtest {Hello}` le nom de macro commence par `\n` que Lua reconnaît comme la séquence d’échappement d’un caractère de saut de ligne, et il remplace donc `\n` par le caractère ASCII 10, ou 0A en hexadécimal. Dans le message d’erreur LaTeX, `U+000A` est une manière de représenter la valeur Unicode à l’aide de 4 chiffres hexadécimaux.

Parce que le `\n` est converti en caractère de saut de ligne, LuaTeX ne voit pas un appel de macro, mais croit plutôt qu’on lui demande de composer du texte commençant par le code de caractère ASCII 10 :

`⟨ASCII 10⟩ewtest {Hello}`

Selon la police utilisée, LuaTeX peut ou non être en mesure de composer le caractère `⟨ASCII 10⟩` mais le texte restant est produit tel quel, avec le `{` et `}` traité comme un groupe et non imprimé.

Plain TeX donne un résultat différent, car la police par défaut est Computer Modern Roman, qui possède un encodage étrange entraînant la composition d’un Oméga majuscule lorsque le code caractère 10 est rencontré.

Pour éviter ces problèmes, nous devons utiliser des chaînes à crochets longs afin d’empêcher l’application du mécanisme d’échappement de Lua. Le résultat correct est produit avec

`\directlua{tex.print([[\newtest{Hello}]])}`

ce qui produit le résultat montré dans la capture d’écran suivante :

![](/files/16becd168d30b5fae95bf64121b3fc8685831aa0)

### Expansion et non-exécution des commandes non expansibles

Lorsque nous avons parlé de l’expansion, nous avons noté qu’il s’agit d’un processus dans lequel un moteur TeX *supprime* une commande (jeton) expansible de l’entrée actuelle et *remplace* celle-ci par le ou les résultats produits par cette commande expansible. Puisque \directlua effectue des activités *d’expansion uniquement* (pour générer une liste de jetons), il *ne déclenche pas* ne pousse pas le traitement de LuaTeX plus loin. Une fois qu’une commande expansible a été lue et entièrement développée, les résultats de cette expansion — qui comprennent fréquemment des commandes (jetons) non expansibles — sont incorporés dans la liste de jetons en cours de construction, prête à être reconvertie en texte pour être transmise à Lua.

Un principe important est à l’œuvre ici : pendant les *d’expansion uniquement* activités conçues pour produire une liste de jetons, les moteurs TeX, y compris LuaTeX, *n’exécutent pas* de commandes TeX primitives, intégrées et non expansibles.

Dans le cas de `\directlua{⟨code⟩}`, si la version entièrement développée de votre `⟨code⟩` produit ou contient des commandes TeX/LaTeX non expansibles, elles *seront transmises à Lua* (représentées sous forme de texte).

#### Exemple

Voici un exemple pour démontrer que les primitives non expansibles ne sont pas exécutées lors d’un traitement par expansion uniquement (tel qu’au sein de `\directlua`). Supposons que nous définissions une macro `\setcountreg` comme ceci :

`\def\setcountreg#1#2{\count#1=#2\relax}`

**Remarque**: Nous utilisons `\relax` après le paramètre `#2` pour empêcher LuaTeX d’aller trop loin lors de l’analyse de l’entrée à la recherche de la valeur numérique (argument) correspondant au paramètre `#2`.

Si, en dehors de `\directlua`, nous exécutons ultérieurement la macro ainsi

```
   \setcountreg{100}{50}
   The value in count register 100 is \the\count100.
```

elle produirait

`La valeur du registre de comptage 100 est 50.`

Dans ce contexte, tout moteur TeX traiterait la macro `\setcountreg`— développerait la macro, déterminerait les arguments et continuerait à lire *et à agir sur* (exécuter) les commandes contenues dans le texte de remplacement (définition) de la macro. Le résultat est ici d’assigner `50` comme valeur stockée dans le registre `\count100`.

Cependant, lorsqu’un moteur TeX effectue des *d’expansion uniquement* activités, comme c’est le cas avec `\directlua`, il *n’exécutera pas* les commandes non expansibles contenues dans la définition de la macro.

Si nous écrivons

```
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{50}]]
}
```

cela produit le texte suivant comme code pour Lua :

`local x = [[\count 100=50\relax ]]`

Le code Lua produit ci-dessus montre qu’au sein de `\directlua` le `\setcountreg` a été développée, ses arguments ont été identifiés et substitués dans le paramètre approprié (`#1` et `#2`) mais cela ne va pas plus loin : la commande TeX primitive non expansible `\count` a été *n’est pas exécutée* pendant `\directlua`le traitement d’expansion de .

Cependant, LuaTeX exécutera le code TeX si nous transmettons la chaîne résultante `x` *à LuaTeX* via `tex.print(x)` comme ceci

```
\count100=50 % définir \count100 à une valeur initiale de 50
\def\setcountreg#1#2{\count#1=#2\relax}
\directlua{
   local x = [[\setcountreg{100}{250}]]
   tex.print(x)
}
La valeur stockée dans le registre de comptage 100 est \the\count100.
```

Après que `\directlua` a terminé, la sortie serait

`La valeur stockée dans le registre de comptage 100 est 250.`

montrant que le registre de comptage `100` contient désormais la valeur `250`.

Le code Lua produit à partir de l’exemple ci-dessus est

`local x = [[\count 100=250\relax ]] tex.print(x)`

Ce code définit `x` comme une chaîne créée à l’aide de la méthode des crochets longs, utilisée pour éviter les erreurs de séquences d’échappement erronées. Si nous utilisions des guillemets doubles `"..."` pour définir x, la combinaison de caractères `\c` au début de `\count` déclencherait une erreur : `invalid escape sequence near ' "\c'`.

L’appel API Lua de LuaTeX `tex.print(x)` entraîne l’exécution par LuaTeX de la séquence de code TeX `\count 100=250\relax` et `\count100` reçoit une valeur de `250` comme le montre la sortie composée :

`La valeur stockée dans le registre de comptage 100 est 250.`

#### Attention : macros et API Lua de LuaTeX

Dans l’exemple ci-dessus, nous avons vu que pendant le `\directlua`prétraitement (expansion) de , LuaTeX n’a pas exécuté le code `\count 100=250`, qui contient la `non extensibles` commande primitive `\count`: pour exécuter ce code, nous avons dû *le retransmettre à LuaTeX* via `tex.print()`.

`\directlua` n’est qu’un exemple où LuaTeX effectue un traitement par expansion uniquement afin de construire une liste de jetons. D’autres commandes effectuent un traitement d’expansion et des activités de génération de listes de jetons similaires, telles que `\write` et `\edef`: ces commandes n’exécutent pas non plus les primitives non expansibles pendant leur traitement d’expansion. C’est un principe général que les moteurs TeX n’exécutent pas les primitives non expansibles lorsqu’ils construisent une liste de jetons lors d’activités de traitement par expansion uniquement.

**Réécriture de notre macro pour utiliser l’API Lua de LuaTeX**

Nous pouvons réécrire la macro `\setcountreg` en utilisant une fonction de l’API Lua de LuaTeX appelée `tex.setcount()`, évitant ainsi les commandes TeX pour modifier la valeur stockée dans le registre de comptage `100`:

```
   \def\setcount#1#2{\directlua{tex.setcount(#1,#2)}}
   \count100=50
   le registre de comptage 100 contient \the\count100\par
   \setcount{100}{250}
   le registre de comptage 100 contient maintenant \the\count100\par
```

Ce code composera :

```
le registre de comptage 100 contient 50
le registre de comptage 100 contient maintenant 250
```

Ici, nous utilisons `tex.setcount()`, l’une des nombreuses fonctions de l’API Lua de LuaTeX, pour *accéder directement à* la zone de stockage interne de données de LuaTeX afin de placer la valeur `250` dans l’emplacement mémoire représentant le registre de comptage `100`. Nous avons, en effet, *contourné* les méthodes standard de traitement des entrées du moteur TeX de LuaTeX : lecture de l’entrée, création de jetons et exécution de commandes TeX primitives. Cependant, il y a une mise en garde : en utilisant les fonctions de l’API Lua de LuaTeX, l’activité de traitement par expansion uniquement *peut entraîner des effets secondaires*: des modifications des valeurs stockées dans le moteur TeX qui ne seraient autrement pas possibles avec de pures commandes TeX/LaTeX.

**Exemple : effets secondaires inattendus**

Voici un exemple pour démontrer des *effets* secondaires inattendus qui peuvent survenir avec des macros utilisant `\directlua`. Supposons que nous écrivions le code suivant :

```
\def\dochange{\directlua{tex.setcount(999,12345)}}
\edef\careful{\dochange}
\the\count999
```

L’exécution de ce code compose `12345`!

Comment cela est-il possible ? Nous n’avons pas *explicitement* appelé de code ou de macros pour placer cette valeur dans le registre de comptage `999`. Ou l’avons-nous fait ?

Nous avons défini `\dochange` avec une commande `\directlua` qui utilise `tex.setcount()` pour stocker la valeur `12345` dans le registre de comptage `999`: en code TeX, cela équivaut à `\count999=12345`. Nous avons ensuite utilisé la primitive TeX standard `\edef` pour définir la macro `\careful`— c’est l’utilisation de `\edef` qui déclenche l’effet secondaire inattendu.

`\edef` développe entièrement son argument : ici, il détecte une macro expansible `\dochange` et la développe. La macro `\dochange` utilise la commande expansible `\directlua` qui contient un appel d’API Lua ; ainsi, le développement de `\dochange` entraîne le développement de `\directlua` et cela provoque l’appel de `tex.setcount()` qui modifie la valeur dans le registre de comptage `999`.

Si nous redéfinissons `\dochange` pour utiliser des commandes TeX :

```
   Avant : le registre de comptage 999 contient \the\count999.\par
   \def\dochange{\count999=12345\relax}
   \edef\careful{\dochange}
   Après : le registre de comptage 999 contient \the\count999.\par
```

l’exécution de ce code compose

```
Avant : le registre de comptage 999 contient 0.
Après : le registre de comptage 999 contient 0.
```

Il est clair qu’il n’y a eu aucun effet sur `\count999`. Lorsque `\edef` définit `\careful` il développe `\dochange` mais ce développement ne produit que des primitives TeX non expansibles : elles sont *n’est pas exécutée* non exécutées *simplement stockées* dans la liste de jetons constituant la définition de `\careful`.

Pour faire bonne mesure, le même principe explique pourquoi ceci produit une sortie composée :

```
\def\dochange{\directlua{tex.print("Hello")}}
\edef\careful{\dochange}
```

## Brève introduction à l’API Lua de LuaTeX

Comme nous l’avons vu, `\directlua` ne vous permet pas seulement d’écrire du code Lua classique, ou un mélange de code Lua et de code TeX/LaTeX, mais fournit aussi l’accès à toute une série de fonctions Lua supplémentaires (spécifiques à LuaTeX) que vous pouvez utiliser (appeler) pour communiquer avec le fonctionnement interne du logiciel de composition LuaTeX, ou le contrôler directement. Nous avons utilisé plusieurs fonctions Lua dans cet article, `tex.print()`, `texio.write()`, `tex.setcount()` et celles-ci, ainsi que *de nombreuses* autres, sont documentées dans [Le manuel de référence LuaTeX](http://www.pragma-ade.com/general/manuals/luatex.pdf) où les groupes de fonctions associées sont appelés *bibliothèques*.

Vous pouvez considérer ces fonctions Lua comme l’API Lua de LuaTeX (**A**application **P**programmation **I**interface) qui fournissent les outils nécessaires pour construire des solutions sophistiquées de composition et d’ingénierie documentaire en contrôlant le comportement typographique de LuaTeX à l’aide de Lua comme moteur.

Comme indiqué, LuaTeX organise son API en un ensemble de fonctions qu’il appelle des bibliothèques : des groupes de fonctions liés par leur objectif ou leurs actions. Chaque ensemble de fonctions est conçu pour donner accès à un aspect particulier des processus internes, des structures de données, du stockage des données et des algorithmes de composition de LuaTeX. En interne, LuaTeX est constitué de plusieurs composants : des bibliothèques/outils logiciels (pour la plupart écrits en C) qui comprennent non seulement le moteur TeX lui-même, mais aussi d’autres sous-systèmes, notamment Lua, MetaPost, Kpathsea, FontForge, libpng et zlib. Ces bibliothèques sont intégrées pour construire les fonctionnalités et les fonctions du logiciel exécutable LuaTeX, et c’est par l’API Lua que les utilisateurs accèdent aux fonctionnalités de LuaTeX issues de l’intégration et de la coordination de ces multiples composants logiciels.

## Quelques exemples et pièges

Dans cette section, nous présentons quelques exemples supplémentaires qui utilisent les sujets, concepts et explications fournis dans cet article.

### Utilisation du caractère tilde (\~)

La langue Lua utilise le `~` caractère (appelé tilde) dans sa syntaxe, y compris sa syntaxe pour effectuer un test « différent de » ; par exemple, pour tester si une variable `x` est différent de `4` nous pourrions écrire :

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Si nous essayons d’exécuter ce simple code Lua via `\directlua`:

```
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
```

nous obtenons une erreur :

`[\directlua]:1: 'then' expected near '\'.`

C’est étrange car notre code est correct : nous avons utilisé `'then'` et il n’y a aucun `\` caractère dans notre code, alors qu’est-ce qui a mal tourné ? Pour comprendre cela, nous devons nous rappeler que, pour TeX/LaTeX, `~` est généralement défini comme un « caractère spécial » avec le code de catégorie 13 : ce que l’on appelle des caractères actifs, qui sont des mini-macros et donc sujets à expansion. Lorsque `\directlua` détecte le `~` caractère, il est développé par *le supprimer* retirée de l’entrée et *en la remplaçant* et le remplacer `~` par le résultat de son expansion. En utilisant TeX plain, le texte (code) résultant que LuaTeX produit et transmet à l’interpréteur Lua ne contient pas réellement le

`local x=3 if x \penalty \@M \ = 4 then print("x is not equal to 4") end`

Le `~` caractère a été *retirée* et *développé* en ses commandes constitutives — le code Lua ci-dessus résulte de la définition par TeX plain du caractère actif `~`. Nous pouvons maintenant voir pourquoi Lua renvoie l’erreur `'then' expected near '\'`—il commence à analyser ce code mais rencontre le mot `\penalty` qui ne signifie rien pour Lua et génère une erreur de syntaxe.

Pour corriger cela, le `~` caractère doit avoir un code de catégorie sûr au moment où `\directlua` LuaTeX traite votre code ; par exemple, nous pouvons temporairement changer le code de catégorie de `~` à 11 (lettre) en encadrant le code dans un groupe :

```
\begingroup
\catcode`\~=11
\directlua{
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

Ce code fonctionne comme prévu et `x is not equal to 4` est affiché dans la console. Il existe d’autres options : nous pouvons utiliser les commandes expansibles `\noexpand` ou `\string`.

#### Utilisation de \string⟨token⟩

Nous pouvons appliquer `\string` au caractère unique `⟨token⟩` `~` qui a le code de catégorie 13 (caractère actif) ; `\string` convertit la `~` caractère pour générer un jeton de caractère qui a le code de catégorie 12. Si nous faisons

```
\directlua{
   local x=3
   if x \string~= 4 then
   print("x is not equal to 4")
   end
}
```

il produit le code Lua dont nous avons besoin :

`local x=3 if x ~= 4 then tex.print("x is not equal to 4") end`

#### Utilisation de \noexpand⟨token⟩

Nous pouvons utiliser `\noexpand~` pour supprimer l’expansion du caractère actif `~`

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
```

Le `~` jeton non développé passe dans la liste de jetons en cours de construction dans `\directlua` et sera reconverti en texte, ce qui produit du code Lua fonctionnel.

### Utilisation du caractère \#

Dans le langage Lua, le `#` caractère peut être utilisé pour connaître la longueur d’une table. Cependant, si nous essayons le code suivant

```
\directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
```

nous pourrions nous attendre à ce que LuaTeX compose

`Table length is 2`

mais il génère une erreur :

`\directlua]:1: attempt to get length of a number value`

Cette erreur est déclenchée parce que le `#` caractère a généralement le code de catégorie 6 (paramètre de macro) — le `#` caractère a deux usages en TeX/LaTeX : pour indiquer les paramètres de macro (`#1`, `#2`… `#9`) et le texte de remplacement dans les modèles d’alignement (pour `\halign` et `\valign`).

Lorsque `\directlua` génère des jetons pour construire sa liste de jetons, il voit le `#` caractère avec le code de catégorie 6 et crée un jeton de caractère approprié pour le représenter. Quand vient le moment de reconvertir la liste finale de jetons en forme textuelle, le jeton de caractère pour # (avec le code de catégorie 6) reçoit un traitement spécial : il est sorti sous forme de *deux caractères consécutifs*: `##`, ce qui donne le code suivant transmis à Lua :

`local tbl = {} tbl[1] = "Hello" tbl[2] = "World" print(##tbl)`

Lors de la conversion en code Lua, le `#` a été doublé et cela génère une erreur :

`\directlua]:1: attempt to get length of a number value`

Ce problème survient à cause de la syntaxe de TeX qui utilise un symbole dièse double `##` pour représenter ou générer un seul `#` jeton ; cette syntaxe est utilisée dans les macros qui définissent d’autres macros prenant des paramètres, ou dans les macros utilisées pour créer des modèles pour les commandes de construction de tables. Cela est assez déroutant, alors regardons un exemple. `\halign` ou `\valign` Supposons que nous définissions une macro

#### Exemple

qui prend un seul paramètre, `\mymacro` , mais elle définit aussi une deuxième macro `#1`qui prend elle-même un seul paramètre. Pour distinguer le paramètre `\foo` utilisé avec `#1` et le besoin de définir `\mymacro` pour utiliser son propre paramètre `\foo` la syntaxe TeX exige que vous utilisiez `#1` à l’intérieur de `##1` pour représenter le paramètre à utiliser avec `\mymacro` \def\mymacro#1{\def\foo##1{#1 Hello##1}} `\foo`:

`\def\mymacro#1{\def\foo##1{#1 Hello##1}}`

Si vous écriviez `\mymacro{Hey!}` cela définirait la macro `\foo` comme étant

`\def\foo#1{Hey! Hello#1}`

Notez que le `\mymacro`’s parameter `#1` (`Hey!`a été incorporé dans la définition de `\foo` et la séquence `##1` a été convertie en `#1` dans la définition de `\foo`. Nous pouvons donc utiliser `\foo` comme ceci :

`\foo{, World!}`

de composer `Hey! Hello, World!`

Nous pouvons résoudre `\directlua`le traitement par `#` du caractère # en changeant temporairement son code de catégorie avant que LuaTeX ne traite le code. Par exemple :

```
\begingroup
   \catcode`\#=11
   \directlua{
   local tbl = {}
   tbl[1] = "Hello"
   tbl[2] = "World"
   tex.print("Table length is "..#tbl)
}
\endgroup
```

Cela génère le code Lua

```
local tbl = {} tbl[1] = "Hello" tbl[2] = "World" tex.print("Table length is "..#tbl)
```

qui compose le résultat attendu :

`Table length is 2`

### Utilisation du caractère %

Dans TeX/LaTeX, le `%` caractère est généralement utilisé pour inclure des commentaires sur une seule ligne dans votre code : pour signaler au moteur TeX qu’il doit ignorer tout ce qui se trouve à partir de ce point jusqu’à la fin de la ligne sur laquelle le `%` est écrit. Cependant, dans le langage Lua, le `%` caractère est utilisé dans certaines fonctions de traitement de chaînes très utiles, telles que `string.format(...)`, `string.gmatch(...)`, et `string.gsub(...)` dans lesquelles le `%` caractère joue un rôle important dans la syntaxe de ces fonctions.

Lorsqu’il est utilisé avec TeX/LaTeX, `%` agit comme caractère de commentaire parce qu’il se voit attribuer le code de catégorie 14. Pour qu’il se comporte comme un caractère ordinaire, et pour désactiver son comportement habituel dans TeX/LaTeX, nous devons changer son code de catégorie en quelque chose de sûr, tel que 12. L’ `\directlua` exemple ci-dessous utilise un certain nombre de techniques discutées plus tôt dans l’article, ainsi qu’une que nous n’avons pas encore mentionnée : ``\catcode`\^^M=12``, ce qui nous permet d’utiliser des commentaires Lua dans notre code ; ceci est discuté ci-dessous.

#### Exemple

Les exemples suivants sont empruntés à [lua-users.org](http://lua-users.org/wiki/StringLibraryTutorial), modifiés de manière appropriée pour être utilisés dans `\directlua`.

```
\documentclass{article}
\begin{document}
\begingroup
\ttfamily
\let\\\relax
\catcode`\^^M=12 %<---we further explore this below!
\catcode`\%=12
\directlua{
   local str -- declare a local variable to hold the result

   tex.print("Using string.format():".."\\par")

   str=string.format("%s %q", "Hello", "Lua user!") -- string and quoted string
   tex.print(str.."\\par")
   str = string.format("%c%c%c", 76, 117, 97) -- char
   tex.print(str.."\\par")
   str=string.format("%e, %E", math.pi, math.pi) -- exponent
   tex.print(str.."\\par")
   str=string.format("%f", math.pi) -- float
   tex.print(str.."\\par")
   str=string.format("%g, %g", math.pi, 10^9) -- float or exponent
   tex.print(str.."\\par")
   str = string.format("%o, %x, %X", 99, 125, 125)  -- octal, hexadecimal, hexadecimal
   tex.print(str.."\\par")

   tex.print("\\vskip3mm".."Using string.gmatch():".."\\par")

   for word in string.gmatch("Hello TeX user", "%a+") do
      tex.print(word.."\\par")
   end

   tex.print("\\vskip3mm".."Using string.gsub():".."\\par")
   str=string.gsub("banana", "(an)", "%1-") -- capture any occurrences of "an" and replace
   tex.print(str.."\\par")
}
\endgroup
\end{document}
```

La capture d’écran suivante montre le résultat typographié du code ci-dessus :

![Utilisation des fonctions de chaînes Lua dans \directlua](/files/f8dda209ffe5a13fa3c66e2795953408f495f6c9)

## Pourquoi le code Lua est-il affiché sur une seule ligne ?

Comme vous avez peut-être remarqué, tous les fragments de code Lua (générés) présentés dans les exemples de cet article sont affichés sous forme d’une seule ligne de texte : les retours à la ligne initialement présents dans les `\directlua` extraits de code ne sont pas respectés. Pourquoi ? C’est parce que les retours à la ligne dans le code Lua ont été *supprimés* lors du prétraitement de LuaTeX dans `\directlua`, ce qui fait que le code Lua devient une longue ligne de texte. Ce comportement peut être attribué à la manière dont les moteurs TeX gèrent les caractères de fin de ligne — désignés par `\r` (retour chariot) et `\n` (saut de ligne) dans la littérature de programmation. Nous verrons pourquoi il pourrait être nécessaire de se soucier de ces détails lorsque nous aborderons l’utilisation des mécanismes de Lua pour commenter des sections de code.

Lorsqu’un logiciel écrit (enregistre) un fichier texte, chaque ligne de texte est terminée par ce que l’on appelle des caractères « nouvelle ligne » — les véritables caractères de nouvelle ligne dépendent de l’application et du système d’exploitation utilisés pour écrire ce fichier. Wikipédia a un [article intéressant](https://en.wikipedia.org/wiki/Newline) qui explore l’histoire/l’évolution des caractères de nouvelle ligne utilisés aujourd’hui.

Dans n’importe quel fichier texte, ses lignes individuelles peuvent se terminer par diverses combinaisons de caractères, appelées retour chariot (caractère ASCII/Unicode 13) et/ou saut de ligne (caractère ASCII/Unicode 10), qui sont désignés par `\r` et `\n` respectivement. Comme les moteurs TeX sont conçus pour être indépendants de la plateforme, ils ont besoin d’une méthode pour contourner la nature intrinsèquement dépendante de la plateforme des fins de ligne utilisées dans les fichiers texte. Naturellement, les moteurs TeX disposent d’une méthode intégrée (mais configurable) pour gérer les caractères de fin de ligne.

### Comment les moteurs TeX gèrent les fins de ligne

Lorsque LuaTeX traite `\directlua{⟨code⟩}` il lit le texte contenu dans votre `⟨code⟩` et applique les méthodes standard du moteur TeX pour traiter toute fin de ligne contenue dans votre `⟨code⟩`. Par défaut, ces méthodes standard de TeX font que tous les caractères de fin de ligne (retours chariot et sauts de ligne) sont supprimés et remplacés par des caractères espace. Nous disons « par défaut » parce que la gestion des caractères de fin de ligne par un moteur TeX peut être modifiée via un paramètre configurable par l’utilisateur appelé `\endlinechar`. Ici, nous proposerons un court aperçu en deux étapes, mais vous trouverez davantage de détails dans l’article Overleaf [Une introduction à \endlinechar : comment TeX lit les lignes à partir de fichiers texte](/latex/fr/articles-approfondis/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

#### Étape 1 : TeX insère son propre caractère de fin de ligne

Après avoir lu une ligne de texte dans votre fichier d’entrée, les moteurs TeX suppriment immédiatement tous les `\r` ou `\n` caractères à la fin de cette ligne. Ensuite, les moteurs TeX *insèrent* (rajoutent) leur propre caractère de fin de ligne à la fin de cette ligne. Ce caractère est déterminé par la valeur d’un paramètre TeX configurable par l’utilisateur appelé `\endlinechar` et c’est grâce à ce mécanisme que les moteurs TeX peuvent traiter les caractères de fin de ligne de manière indépendante de la plateforme : ils choisissent et définissent le caractère de fin de ligne, indépendamment de ce qui se trouvait à l’origine dans le fichier texte d’entrée.

En général, les moteurs TeX utilisent le réglage

`\endlinechar=13`

qui est le caractère de retour chariot (`\r`). Toutefois, les utilisateurs peuvent toujours attribuer un autre code de caractère comme valeur de `\endlinechar`—ce que nous verrons plus loin dans cet article.

Par conséquent, tout caractère(s) de fin de ligne contenu(s) dans votre `⟨code⟩` à traiter par `\directlua{⟨code⟩}` sont supprimés et remplacés par un seul caractère déterminé par le moteur TeX lui-même. Notez que les moteurs TeX effectuent ce traitement de fin de ligne immédiatement après la lecture d’une nouvelle ligne de texte à partir d’un fichier et *avant* le traitement de tous les caractères de cette ligne (pour générer des jetons). Cependant, ce n’est pas la fin de l’histoire : ce que le moteur TeX *contient* fait de ces caractères de fin de ligne (qu’il a insérés) explique pourquoi le code Lua devient une seule ligne.

#### Étape 2 : TeX convertit son caractère de fin de ligne en espace

En plus d’insérer son propre caractère de fin de ligne, défini par la valeur de `\endlinechar`, les moteurs TeX utilisent également le code de catégorie 5 pour les caractères qui doivent être *traités comme* un caractère de fin de ligne. Cela fait que les moteurs TeX travaillent généralement avec :

1. un caractère de fin de ligne défini par `\endlinechar`;
2. ce même caractère *généralement* se voyant attribuer le code de catégorie 5.

C’est ce que TeX fait à ce caractère de fin de ligne qui explique notre dilemme concernant les lignes uniques de code Lua. Lorsqu’un moteur TeX traite une ligne d’entrée, il détecte finalement le dernier caractère de cette ligne : le caractère défini par `\endlinechar`. Habituellement, ce caractère a le code de catégorie 5, ce qui amène TeX à *le remplacer* par un caractère espace : autrement dit, en fin de ligne, TeX supprime en effet son caractère de fin de ligne et le remplace par un espace. À titre d’information, les moteurs TeX utilisent aussi les caractères de code de catégorie 5 pour détecter les lignes vides et commencer un nouveau paragraphe, mais nous n’aborderons pas cela ici.

Bien sûr, parce que c’est TeX, vous pouvez réaliser toutes sortes d’astuces spéciales de programmation par macros en réinitialisant le `\endlinechar` à un autre caractère, et/ou en donnant au caractère attribué à `\endlinechar` une valeur de code de catégorie de votre choix.

Si vous voulez empêcher que le code Lua devienne une seule ligne de texte, vous pouvez soit modifier (temporairement) la valeur attribuée à `\endlinechar` soit changer le code de catégorie du terminateur de fin de ligne standard `\r`.

### La bizarre notation ^^ de TeX

Dans les sections suivantes, nous rencontrerons la notation inhabituelle de TeX `^^` qui est connue sous le nom de « mécanisme de caractère étendu ». Elle a été conçue par Knuth comme un moyen de faciliter la saisie de « caractères de contrôle » tels que les terminateurs de fin de ligne, les tabulations, etc. Par exemple :

* `^^J` représente le code de caractère 10 (`\n`, saut de ligne) ;
* `^^M` représente le code de caractère 13 (`\r`, retour chariot).

Des séquences de caractères telles que `^^M` sont converties en leurs codes de caractères correspondants dès le début du processus d’analyse de l’entrée dans TeX, lorsque TeX lit les caractères d’entrée pour générer les jetons de caractères correspondants.

### Changer le caractère attribué à \endlinechar

En gardant à l’esprit que nous devons toujours empêcher l’expansion du `~` caractère, nous pouvons écrire

```
\begingroup
\endlinechar=10 % Change the end-of-line character to \n
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}% don’t want the \n appearing here
\endgroup% or a \n here
```

Le réglage ci-dessus pour `\endlinechar` amène LuaTeX à ajouter le code de caractère 10 (`\n`, saut de ligne) à la fin de chaque ligne qu’il lit. Nous faisons cela parce que `\n` (saut de ligne) a généralement le code de catégorie 12, ce que vous pouvez vérifier en écrivant ``\the\catcode`\^^J``. Parce que `\n` n’a pas le code de catégorie 5, LuaTeX ne le convertira pas en caractère espace, il reste donc à la fin de chaque ligne lue par LuaTeX. Il en résulte qu’un caractère de code 10 reste à la fin de chaque ligne, et se retrouve ainsi dans la liste de jetons en cours de construction par `\directlua` et réapparaît ensuite dans le code Lua une fois que la liste de jetons est convertie en texte. Avec le changement ci-dessus, le code Lua est envoyé à l’interpréteur Lua sous la forme de la séquence de caractères suivante :

**\n**local x=3\*\*\n**if x \~= 4 then**\n**print("x is not equal to 4")**\n**end**\n\*\*

où la **\n** notation est censée représenter le code de caractère 10 *ne* une macro inconnue quelconque `\n`. Désormais, l’interpréteur Lua verra les retours à la ligne dans le code, exactement comme ils étaient écrits à l’origine dans le `\directlua` commande :

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Au passage, notez que le tout premier caractère de la chaîne de code Lua est `\n` (avant le `distribution LaTeX` mot-clé). Ce `\n` provient de la ligne

`\directlua{`

car il y a un retour à la ligne immédiatement après l’ouverture du `{` et celui-ci aussi est conservé. Pour l’empêcher, vous pouvez écrire

`\directlua{%`

### Changer le code de catégorie de \r

Pour conserver les retours à la ligne dans notre code Lua, nous pouvons aussi changer le code de catégorie de `\r` à autre chose que 5, de sorte que `\r` ne soit plus reconnu (traité comme) un caractère de fin de ligne. Avec cette technique, LuaTeX utilise toujours `\endlinechar=13` et continuera d’ajouter un `\r` à la fin de chaque ligne ; toutefois, parce que `\r` n’a plus le code de catégorie 5, LuaTeX ne reconnaîtra pas le `\r` caractère comme fin de ligne : il ne le convertira pas en espace et le transmettra intact pour apparaître dans le code Lua.

En gardant à l’esprit que nous devons toujours empêcher l’expansion du `~` caractère, nous pouvons écrire

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

Dans ce cas, le code Lua est envoyé à l’interpréteur Lua sous la forme :

**\r**local x=3\*\*\r**if x \~= 4 then**\r**print("x is not equal to 4")**\r**end**\r\*\*

où la `\r` la notation est censée représenter le code de caractère 13 et non une macro inconnue quelconque `\r`. Comme avec l’exemple `\endlinechar` , l’interpréteur Lua verra désormais des retours à la ligne dans le code, exactement comme ils étaient écrits à l’origine dans le `\directlua` commande :

```
   local x=3
   if x ~= 4 then
   print("x is not equal to 4")
   end
```

Au passage, notez encore une fois que le tout premier caractère de la chaîne de code Lua est `\r` (avant le mot-clé local) : cela provient aussi de la ligne

`\directlua{`

#### Pourquoi \r a-t-il le code de catégorie 12 et non le code de catégorie 11 ?

La réponse tient au risque d’introduire accidentellement des erreurs déclenchées par `\r` (de code de catégorie 11) ajoutés à la fin des commandes TeX/LaTeX lues depuis notre fichier d’entrée. Prenons cet exemple :

```
\begingroup
\catcode`\^^M=11 % change category code of \r to 11
\directlua{
   local x=3
   if x \noexpand~= 4 then
   print("x is not equal to 4")
   end
}
\endgroup
```

ce qui génère une erreur :

```
   ! Séquence de contrôle indéfinie.
   l.9 \endgroup
```

Comment cela peut-il être vrai puisque `\endgroup` est une commande primitive TeX standard ? La cause de l’erreur est assez subtile : lorsque LuaTeX a lu la dernière ligne de texte — celle contenant `\endgroup`— il a aussi ajouté le `\endlinechar` suivant `\r` à la fin de cette ligne. Maintenant, dans sa mémoire, LuaTeX voit la séquence de caractères

`\endgroup\r`

où nous utilisons `\r` pour indiquer le caractère de code 13 — pas le nom d’une macro TeX inconnue quelconque `\r`.

Au moment où LuaTeX a lu cette ligne depuis notre fichier texte, le `\begingroup` est encore actif : nous sommes dans un groupe qui n’a pas encore été fermé par l’exécution de la commande correspondante `\endgroup` — ce qui ferait que `\r` reviendrait à sa valeur de code de catégorie précédente, à savoir 5.

Lorsque LuaTeX commence à traiter (créer des jetons) la ligne de texte `\endgroup\r` il reconnaît le premier caractère `\` comme le caractère d’échappement, ce qui déclenche LuaTeX pour commencer à chercher le nom d’une commande. Pour identifier un nom de commande, LuaTeX cherche une séquence de caractères ayant le code de catégorie 11, mais parce que `\r` a aussi le code de catégorie 11, LuaTeX pense que le `\r` la forme caractère (toujours avec le code de catégorie 11) *partie d'une commande* nommé `\endgroup\r` qui, bien sûr, n'existe pas, donc LuaTeX signale une `Séquence de contrôle indéfinie` erreur. C’est pourquoi nous avons utilisé le code de catégorie 12 et non 11.

Parce que le message d’erreur de LuaTeX a été écrit dans la console, nous ne pouvions pas facilement voir/remarquer le `\r` caractère, donc il n’était pas évident de savoir ce qui avait causé l’erreur.

### Pourquoi nous préoccupons-nous des fins de ligne ?

La raison est de permettre l’utilisation de la méthode de commentaire de Lua dans votre code ! Vous pouvez utiliser le mécanisme standard de LuaTeX consistant à ajouter `%` des caractères pour commenter des lignes de code ; cependant, le langage Lua possède ses propres mécanismes de commentaire, très utiles, *multi-ligne* dont vous voudrez peut-être tirer parti.

Commençons par voir ce qui se passe si nous essayons d’utiliser des commentaires Lua à une seule ligne sans traiter les problèmes de retours à la ligne. Alors que TeX utilise le `%` caractère pour commenter des lignes de code, Lua utilise un double tiret : `--`.

Que se passe-t-il si nous essayons d’exécuter ceci :

```
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Je vais afficher le résultat de ce test complexe
   print("x is not equal to 4")
   end
}
```

Nous obtenons une erreur :

`[\directlua]:1: 'end' expected near <eof>`

Cette erreur est causée par l’absence de retours à la ligne dans le code Lua transmis à l’interpréteur, qui ne voit qu’une seule chaîne continue dans laquelle le commentaire commence au milieu de cette chaîne :

```

local x=3 if x ~= 4 then -- Je vais afficher le résultat de ce test complexe print("x is not equal to 4") end
```

Tout ce qui suit `**local x=3 if x ~= 4 then**` est traité comme étant commenté, ce qui amène l’interpréteur à voir un fragment incomplet de code Lua, entraînant l’erreur

`'end' expected near <eof>`.

où `<eof>` signifie fin de fichier.

Comme vous l’avez probablement deviné, nous devons remédier à cela en veillant à ce que les retours à la ligne soient transmis au code Lua résultant, ce que nous pouvons accomplir, par exemple, en modifiant le code de catégorie de `\r` à 12 :

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   -- Je vais afficher le résultat de ce test complexe
   print("x is not equal to 4")
   end
}
\endgroup
```

À présent, l’interpréteur Lua voit une chaîne, mais elle contient `\r` des retours à la ligne tels qu’écrits dans le `\directlua` fragment :

**\r**local x=3\*\*\r**if x \~= 4 then**\r\*\*-- Je vais afficher le résultat de ce test complexe\*\*\r**tex.print("x is not equal to 4")**\r**end**\r\*\*

En effet, cela revient à écrire

```
   local x=3
   if x \noexpand~= 4 then
   -- Je vais afficher le résultat de ce test complexe
   print("x is not equal to 4")
   end
```

ce qui signifie que Lua est capable de traiter correctement ce code et d’ignorer la ligne que nous avons commentée.

**Commentaires de bloc**

Le langage Lua prend également en charge une syntaxe qu’il appelle [« commentaire de bloc »](https://www.lua.org/pil/1.3.html) (ou *commentaire long*): ils commencent par `--[[` et restent effectifs jusqu’au `]]`. Nous pouvons utiliser cette syntaxe pratique pour écrire des commentaires sur plusieurs lignes, ou commenter des sections de code que nous voulons supprimer temporairement :

```
\begingroup
\catcode`\^^M=12 % change category code of \r to 12
\directlua{
   local x=3
   if x \noexpand~= 4 then
   --[[ Je vais afficher le résultat de ce test complexe
   simplement parce que c’est vraiment
   une conclusion aussi étonnante]]
   print("x is not equal to 4")
   end
}
\endgroup
```

## En conclusion

Tout d’abord, félicitations si vous êtes parvenu(e) à lire cet article conséquent ! Nous avons essayé de produire un guide raisonnablement complet des concepts et sujets liés à TeX, qui fournissent le contexte nécessaire pour tirer le meilleur parti de LuaTeX via la `\directlua` commande. Nous espérons avoir produit un article instructif et apportant quelque chose d’utile et de précieux à la communauté des utilisateurs d’Overleaf, et au-delà. Comme toujours, nous serons ravis de recevoir vos commentaires, alors n’hésitez pas à [nous contacter](https://www.overleaf.com/contact) avec des commentaires sur cet article ou des suggestions d’autres sujets sur lesquels vous aimeriez que nous écrivions.

Bonne $$\text{Lua}\mathrm{\TeX}\text{-ing!}$$ de Graham Douglas et de l’équipe Overleaf.

### Et enfin... utilisez simplement le package luacode

Bien que TeX et Lua fonctionnent de manière fondamentalement différente, ces langages partagent un certain nombre de caractères ayant des « significations spéciales » dans le contexte de chaque langage — comme \\, %, \~, #, ^, & — bien sûr, Lua et TeX attribuent ces significations spéciales pour *très* des usages différents. Notre exploration des caractères problématiques montre pourquoi des difficultés peuvent surgir et comment vous pouvez les résoudre ; cependant, il pourrait être assez fastidieux de corriger manuellement de nombreux petits fragments de code Lua, si bien que la plupart des utilisateurs préfèrent utiliser des paquets LaTeX qui suppriment ces difficultés. L’un de ces paquets est [`luacode`](https://ctan.org/pkg/luacode?lang=en) qui fournit un ensemble de fonctionnalités conçues pour simplifier le travail avec `\directlua`, mais au moins vous avez peut-être maintenant une meilleure compréhension des problèmes `luacode` qu’il résout pour vous.


---

# 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/09-an-introduction-to-luatex-part-2-understanding-directlua.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.
