Comment définir des commandes dans des commandes?

Si vous souhaitez créer des commandes qui définissent automatiquement d'autres commandes, la règle à retenir est que lorsque vous allez écrire ##, il sera remplacé par # de la même manière que #1 est remplacé par « le premier argument passé à la commande ».

Aussi, si vous définissez la commande suivante (on met ici la manière de le faire respectivement en \LaTeX pour la commande \un et en \TeX pour la commande \one) :

\newcommand\un[1]{+#1+#1+#1+}
\def\one#1{+#1+#1+#1+}

Dans les deux, que vous saisissiez \un{trois} ou \one{trois}, le développement de la commande va vous donner : +trois+trois+trois+.

Modifions maintenant naïvement ces commandes pour qu'elles définissent une autre commande :

\newcommand\un[1]{+#1+\newcommand\deux[1]{xx#1}}
\def\one#1{+#1+\def\two #1{xx#1}}

Ici, \un{trois} va afficher +trois+ puis exécuter la commande \newcommand{deux}[1]{xxtrois} qui définira une commande \deux qui ignore son argument et restitue systématiquement xxtrois. En effet #1 est remplacé systématiquement par le premier argument.

La commande \one{trois} sera encore plus insidieuse car, après avoir affiché +trois+, elle va exécuter la commande \def\two trois{xxtrois}}… autrement dit créer une commande \two qui demandera d'être appelée en saisissant toujours \two trois et qui restituera toujours xxtrois.

De fait, pour obtenir le bon comportement, nous devons utiliser la définition suivante :

\newcommand\un[1]{+#1+\newcommand\deux[1]{xx##1}}
\def\one#1{+#1+\def\two ##1{xx##1}}

La commande \un{trois} exécutera \newcommand\deux[1]{xx#1} tandis que \one{trois} exécutera bien \def\two #1{xx#1}}. Ici ##1 a bien été remplacé par #1.

Pour imbriquer une définition dans une définition à l'intérieur d'une définition, vous avez besoin de ####, en doublant le nombre de signes #. Au niveau d'imbrication suivant, vous avez besoin de 8 #, et ainsi de suite.


Source : Defining macros within macros

2_programmation/macros/definir_une_macro_a_l_interieur_d_une_autre_macro.txt · Dernière modification: 2021/04/21 14:20 par yannick.tanguy
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0