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 pour la commande \un et en pour la commande \one) :

\newcommand{\un}[1]{Joie, quelle #1 !}
\def\one#1{Joie, quelle #1 !}

Dans les deux, que vous saisissiez \un{joie} ou \one{joie}, le développement de la commande va vous donner : « Joie, quelle joie ! ».

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

\newcommand{\un}[1]{Joie, quelle #1 !%
  \newcommand{\deux}[1]{Horreur, quelle #1 !}%
}
\def\one#1{Joie, quelle #1 !\def\two #1{Horreur, quelle #1 !}}

Ici, \un{joie} va afficher « Joie, quelle joie ! » puis exécuter la commande \newcommand{\deux}[1]{Horreur, quelle joie !}, définition d’une commande \deux qui ignore son argument et restitue systématiquement « Horreur, quelle joie ! ». En effet #1 est remplacé systématiquement par le premier argument.

La commande \one{joie} sera encore plus insidieuse car, après avoir affiché « Joie, quelle joie ! », elle va exécuter la commande \def\two joie{Horreur, quelle joie !}}… autrement dit créer une commande \two qui demandera d’être appelée en saisissant toujours \two joie et qui restituera toujours « Horreur, quelle joie ! ».

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

\newcommand{\un}[1]{Joie, quelle #1 !%
  \newcommand{\deux}[1]{Horreur, quelle ##1 !}%
}
\def\one#1{Joie, quelle #1 !\def\two ##1{Horreur, quelle ##1 !}}

La commande \un{joie} exécutera \newcommand{\deux}[1]{Horreur, quelle #1 !} tandis que \one{joie} exécutera bien \def\two #1{Horreur, quelle #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.

Il est aussi à noter que le doublement des signes # est nécessaire que la commande englobante ait ou pas un argument :

\newcommand{\un}{Joie, quelle joie !%
  \newcommand{\deux}[1]{Horreur, quelle ##1 !}%
}