macros

Expansión de los argumentos antes de la llamada a la macro

Llevo días dándome de bruces con esto.Tengo una macro que toma un nombre de macro y sus argumentos.Luego reordena los argumentos un poco y luego llama a la macro pasada con los argumentos reordenados y así termina así:

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

donde arga ... \argc son los argumentos procesados. Sin embargo. Necesito tener \arga ... \argc completamente expandido antes de llamar a la macro almacenada en #1 . Por mi vida, no puedo resolver esto después de días de jugar con \expandafter , \noexpand , etextools , etc. No puedo usar expl3 y realmente preferiría no usar etextools , pero etoolbox está disponible. Aquí hay 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}

Esto da como resultado "\arga \argb \argc" pero quiero "arg1arg2arg3". \expandafter hará esto en \x pero no para tres argumentos seguidos. etextools tiene algunas macros para hacer esto, pero realmente quiero evitarlo (choca con etoolbox de alguna manera y debo tener etoolbox ). No pude hacer funcionar las macros de etextools incluso cuando lo intenté ( \ExpandNextTwo , etc.)

ACTUALIZACIÓN:Me he dado cuenta de que,en mi caso,los args pueden contener macros robustas como

\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}

En cuyo caso (usando la respuesta de egreg como ejemplo),no está completamente expandido.Como Joseph y egreg mencionan más abajo,esto no es posible,sólo hay que utilizar macros no robustas en estos casos,por ejemplo.Dejaré la pregunta como está porque es informativa.

El enfoque 'clásico' es usar \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}

donde necesitamos muchos de ellos para expandir arg3 , luego arg2 y finalmente arg1 . (Esto es lo que se envuelve efectivamente en \ expl3 \exp_args:Nooo de expl3 ).

La regla del número de \expandafter s que necesitamos es 2 n – 1, donde n es cuántos tokens queremos expandir. Entonces, para un token en algún lugar adelante, solo necesitamos un \expandafter en cada lugar para ser 'omitido', para expandir dos tokens (el segundo y luego el primero) necesitamos tres \expandafter s, para tres tokens (como en el caso actual ) necesitamos siete \expandafter s, y así uno. Esto es más fácil de ver si escribe/imprime un breve segundo y tacha los comandos como los leería TeX: encontrará que todo funciona.

Con e-TeX disponible, podemos usar \edef y \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}

(Puede hacer lo mismo sin e-TeX usando una serie de toks, pero eso se vuelve un poco confuso, por lo que normalmente no lo haría).


La pregunta dice no expl3 , pero por el contrario, el enfoque que usa un mínimo de las funciones que proporciona sería

\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}

que es espero mucho más legible. (Probablemente me gustaría usar \exp_args:NVVV ya que estamos usando 'valor almacenado en una variable', pero esa función no está predefinida, así que la he evitado aquí).




Si realmente desea que los argumentos se expandan por completo , entonces

\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}

dará lugar a la impresión de

arg1arg2arg3This is foo

mientras que las soluciones basadas \expandafter imprimirían

arg1arg2arg\foo