I've been banging my head against this for days. I have a macro which takes a macro name and its arguments. It then re-arranges the arguments a bit and then calls the passed macro with the re-arranged arguments and so ends like this:
#1{\arga}{\argb}{\argc}
where arga ... \argc
are the processed arguments. However. I need to have \arga ... \argc
fully expanded before the macro stored in #1
is called. I cannot for the life of me work this out after days of playing with \expandafter
, \noexpand
, etextools
etc. I can't use expl3
and I'd really prefer not to use etextools
but etoolbox
is available. Here is a 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}
This results in "\arga \argb \argc" but I want "arg1arg2arg3". \expandafter
will do this in \x
but not for three arguments in a row. etextools
has some macros to do this but I really want to avoid it (it clashes with etoolbox
in some ways and I must have etoolbox
). I couldn't get the etextools
macros to work even when I tried (\ExpandNextTwo
etc.)
UPDATE: I realised that in my case, the args can contain robust macros like:
\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@edef\z{\noexpand#1{\arga}{\argb}{\argc}}\z}}
\def\y#1#2#3{\detokenize{#1#2#3}}
\x\y{arg1}{arg2}{arg3}
\end{document}
In which case (using egreg's answer as an example), it isn't fully expanded. As Joseph and egreg mention below, this isn't doable, you just have to use non-robust macros in such cases, for example. I'll let the question stand as it because it is informative.
Best Answer
The 'classical' approach is to use
\expandafter
where we need so many of them to expand
arg3
thenarg2
and finallyarg1
. (This is what is effectively wrapped up inexpl3
's\exp_args:Nooo
).The rule of the number of
\expandafter
s we need is 2n – 1, where n is how many tokens we want to expand. So for one token somewhere ahead, we need just one\expandafter
in each place to be 'skipped', to expand two tokens (second one then the first one) we need three\expandafter
s, for three tokens (as in the current case) we need seven\expandafter
s, and so one. This is easiest to see if you write/print out a short second and cross off the commands as TeX would read them: you'll find everything works out.With e-TeX available, we can use an
\edef
and\unexpanded
:(You can do the same without e-TeX using a series of toks, but that gets a bit confusing so I'd not normally do it.)
The question says no
expl3
, but for contrast the approach using a minimium of the functions it provides would readwhich is I hope a lot more readable. (I'd probably want to use
\exp_args:NVVV
as we are using 'value stored in a variable', but that function is not pre-defined so I've avoided it here.)