Comment créer une commande qui permet de définir de nouvelles commandes en les nommant d'après un argument ?
Il est courant de vouloir qu'une commande crée une autre commande et, souvent, on peut souhaiter que le nom de la nouvelle commande dérive d'un des arguments. fait cela tout le temps : par exemple, \newenvironment
crée des commandes d'environnement de début et de fin dont les noms sont dérivés du nom de la commande d'environnement.
Voici un exemple d'approche qui pourrait sembler logique :
\def\creatrice#1#2{\def\#1{#2}}
Cela ne fonctionne pas (le moteur l'interprète en fait comme une redéfinition assez étrange de #
). L'astuce consiste à utiliser \csname
, qui est une primitive pour générer des noms de commandes à partir de texte aléatoire, en lien avec la commade \expandafter
. La définition ci-dessus doit se corriger en :
\def\creatrice#1#2{\expandafter\def\csname #1\endcsname{#2}}
Avec cette définition, \creatrice{test}{efficace}
équivaut à \def\test{efficace}
.
Notez que la définition de \creatrice
omet les accolades autour du « nom de la commande ». C'est parce qu'elles ne sont pas nécessaires (en fait elles ne le sont que rarement) et rendent le code de la commande un peu plus lourd.
Par ailleurs, le nom créé n'a pas besoin de se limiter uniquement à l'argument :
\def\doublecreatrice#1#2#3{% \expandafter\def\csname debut#1\endcsname{% #2% }% \expandafter\def\csname fin#1\endcsname{% #3% }% }
Dans ce cas, si vous utiliser \doublecreatrice{alphabet}{a}{z}
, vous obtiendrez deux nouvelles commandes, une nommée \debutalphabet
(qui affichera a
) et l'autre \finalphabet
(qui affichera z
). De là à obtenir des commandes assez proches des environnements , il n'y a qu'un pas, consistant à ajouter à notre définition corrigée deux définitions suivantes :
\def\debut#1{\csname debut#1\endcsname} \def\fin#1{\csname fin#1\endcsname}
Vous pouvez dès lors utiliser une commande \debut{alphabet}
et \fin{alphabet}
, au lieu de \debutalphabet
et \finalphabet
.
Source : Defining a macro from an argument