macros

Expansion des arguments avant l'appel de la macro

Cela fait des jours que je me cogne la tête contre ce problème.J'ai une macro qui prend un nom de macro et ses arguments.Elle réorganise ensuite un peu les arguments,puis appelle la macro passée avec les arguments réorganisés et se termine ainsi :

#1{\arga}{\argb}{\argc}

arga ... \argc sont les arguments traités. Cependant. J'ai besoin d'avoir \arga ... \argc complètement développé avant que la macro stockée dans #1 ne soit appelée. Je ne peux pas pour la vie de moi résoudre ce problème après des jours de jeu avec \expandafter , \noexpand , etextools etc. Je ne peux pas utiliser expl3 et je préférerais vraiment ne pas utiliser etextools mais etoolbox est disponible. Voici un MWE :

\documentclass{article}
\begin{document}

\def\x#1#2#3#4{%
  \def\arga{#2}%
  \def\argb{#3}%
  \def\argc{#4}%
  #1{\arga}{\argb}{\argc}}

\def\y#1#2#3{\detokenize{#1#2#3}}

\x\y{arg1}{arg2}{arg3}

\end{document}

Cela se traduit par "\arga \argb \argc" mais je veux "arg1arg2arg3". \expandafter le fera dans \x mais pas pour trois arguments de suite. etextools a quelques macros pour le faire mais je veux vraiment l'éviter (il se heurte à etoolbox à certains égards et je dois avoir etoolbox ). Je n'ai pas pu faire fonctionner les macros etextools même lorsque j'ai essayé ( \ExpandNextTwo etc.)

UPDATE:Je me suis rendu compte que dans mon cas,les args peuvent contenir des macros robustes comme :

\documentclass{article}
\usepackage{etoolbox}
\begin{document}

\def\x#1#2#3#4{%
  \def\arga{#2}%
  \edef\argb{\ifstrequal{#3}{arg2}{arg2}{}}%
  \def\argc{#4}%
  {\protected\z{\noexpand#1{\arga}{\argb}{\argc}}\z}}

\def\y#1#2#3{\detokenize{#1#2#3}}

\x\y{arg1}{arg2}{arg3}

\end{document}

Dans ce cas (en utilisant la réponse d'egreg comme exemple),il n'est pas complètement étendu.Comme Joseph et egreg le mentionnent ci-dessous,ce n'est pas faisable,il suffit d'utiliser des macros non robustes dans ces cas-là,par exemple.Je vais laisser la question en l'état car elle est instructive.

L'approche "classique" consiste à utiliser \expandafter

\documentclass{article}
\begin{document}

\def\x#1#2#3#4{%
  \def\arga{#2}%
  \def\argb{#3}%
  \def\argc{#4}%
  \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter#1%
    \expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
      {\expandafter\expandafter\expandafter\arga\expandafter\expandafter\expandafter}%
        \expandafter\expandafter\expandafter{\expandafter\argb\expandafter}\expandafter
          {\argc}}

\def\y#1#2#3{\detokenize{#1#2#3}}

\x\y{arg1}{arg2}{arg3}

\end{document}

où nous avons besoin d'un si grand nombre d'entre eux pour développer arg3 puis arg2 et enfin arg1 . (C'est ce qui est effectivement expl3 dans le \exp_args:Nooo de expl3 ).

La règle du nombre de \expandafter s dont nous avons besoin est 2 n – 1, où n est le nombre de jetons que nous voulons développer. Donc pour un jeton quelque part devant, nous avons besoin d'un seul \expandafter à chaque endroit pour être "sauté", pour développer deux jetons (le second puis le premier) nous avons besoin de trois \expandafter s, pour trois jetons (comme dans le cas actuel ) nous avons besoin de sept \expandafter s, et ainsi de suite. C'est plus facile à voir si vous écrivez/imprimez une courte seconde et rayez les commandes comme TeX les lirait : vous constaterez que tout fonctionne.

Avec e-TeX disponible, nous pouvons utiliser un \edef et \unexpanded unexpanded :

\documentclass{article}
\begin{document}

\def\x#1#2#3#4{%
  \def\arga{#2}%
  \def\argb{#3}%
  \def\argc{#4}%
  \begingroup
    \edef\x{%
      \endgroup
      \noexpand#1
        {\unexpanded\expandafter{\arga}}%
        {\unexpanded\expandafter{\argb}}%
        {\unexpanded\expandafter{\argc}}%
    }%
  \x
}    

\def\y#1#2#3{\detokenize{#1#2#3}}

\x\y{arg1}{arg2}{arg3}

\end{document}

(Vous pouvez faire la même chose sans e-TeX en utilisant une série de toks, mais cela devient un peu déroutant donc je ne le ferais pas normalement.)


La question ne dit pas expl3 , mais par contraste, l'approche utilisant un minimum des fonctions qu'elle fournit se lirait

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\def\x#1#2#3#4{
  \def\arga{#2}
  \def\argb{#3}
  \def\argc{#4}
  \exp_args:Nooo#1\arga\argb\argc
}    
\ExplSyntaxOff
\def\y#1#2#3{\detokenize{#1#2#3}}

\x\y{arg1}{arg2}{arg3}

\end{document}

qui est je l'espère beaucoup plus lisible. (Je voudrais probablement utiliser \exp_args:NVVV car nous utilisons 'valeur stockée dans une variable', mais cette fonction n'est pas prédéfinie, donc je l'ai évitée ici.)




Si vous voulez vraiment que les arguments soient complètement développés, alors

\documentclass{article}
\begin{document}

\def\x#1#2#3#4{%
  \begingroup\edef\z{\endgroup\noexpand#1{#2}{#3}{#4}}\z
}

\def\y#1#2#3{\detokenize{#1#2#3}}

\def\foo{This is foo}

\texttt{\x\y{arg1}{arg2}{arg3\foo}}

\end{document}

entraînera l'impression

arg1arg2arg3This is foo

alors que les solutions basées \expandafter imprimeraient

arg1arg2arg\foo