Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Often I find myself in the need of expanding some macro, whose contents should be given as an argument to another command. The usual solution is to invoke some \expandafter concoctions to somehow control the expansion, but I wonder if (at least for some common cases) there is an easier way.

As an example, imagine that I want to write something like the following

\somecommand{Some Argument}{\secondarg}

But I want to expand \secondarg before actually attempting to process \somecommand.

For this kind of scenarions, would it be possible to define a command so that

\expandafterallthat{\somecommand{Some Argument}}{\secondarg}

expands to something like

\somecommand{SomeArgument}{Contents of secondarg macro}
share|improve this question
1  
I think either etoolbox or etextools provides some macros like this. I think it is the latter. –  Martin Scharrer Jul 4 '11 at 14:05

3 Answers 3

up vote 18 down vote accepted

This is provided by etextools as \expandnext:

\usepackage{etextools}
\expandnext{\somecommand{Some Argument}}{\secondarg}

But if you only like to expand the second argument once you can use a double argument swapping, a trick I use in some of my packages:

\documentclass{article}
%% Implementation
\def\myswap#1#2{#2{#1}}

\def\expandafterallthat#1#2{%
    \expandafter\myswap\expandafter{#2}{#1}%
}
%%%%%%%%%%%%%%%%

% Test case:
%
\makeatletter
\def\somecommand#1#2{%
    \def\first{#1}%
    \@onelevel@sanitize\first
    \par\texttt{First argument: \first}%
    \def\second{#2}%
    \@onelevel@sanitize\second
    \par\texttt{Second argument: \second}%
}
\makeatother

\def\secondarg{\empty Some stuff\empty}

\begin{document}

\expandafterallthat{\somecommand{\empty Some Argument\empty}}{\secondarg}

\end{document}

This correctly prints: (the \emptys are to see if the argument got expanded further)

first argument: \empty Some Argument\empty
Second argument: \empty Some stuff\empty
share|improve this answer
    
This is nice! I'm now having a look at etextools, seems very useful! –  Juan A. Navarro Jul 4 '11 at 14:28

Since Joseph did not mention expl3 yet, let me do that: the LaTeX3 bundle includes a module for expansion control, l3expan. In particular, this includes functions to expand arguments of a command, of the form \exp_args:N... where the dots are letters corresponding to how the various arguments should be treated.

Many letters are in use: n for a brace group which should be passed with no modification, o to expand once, f to expand fully from the left, stopping at the first non-expandable token, x to expand fully throughout, like in an \edef. There is also N for a single non-braced token which should be passed as is, c for text that should be made into a control sequence, then treated as an N argument, and V and v for variables (see the l3expan documentation for details).

Here, you want to expand the second argument once, and leave the first unchanged, so the variant you need is \exp_args:Nno: leave the function unchanged (N), the first argument, braced, unchanged (n), and the second expanded once (o).

\newcommand{\foo}[2]{\showtokens{#1... #2}}
\newcommand{\sometext}{Some text.}
\RequirePackage{expl3}
\ExplSyntaxOn
\exp_args:Nno \foo {\error} {\sometext}
\ExplSyntaxOff
share|improve this answer
1  
And to extend the example, if you wanted to recursively expand \sometext as in Joseph's answer, you'd use \exp_args:Nnx instead. –  Will Robertson Jul 5 '11 at 14:20
1  
Actually, you'd want \exp_args:Nnf to get the same effect as my answer :-). –  Joseph Wright Apr 13 '12 at 6:23

Written without a package

\documentclass{article}
\newcommand\expandafterallthat[2]{%
  \expandafter\expandafterallthataux\expandafter{\romannumeral -`0#2 }{#1}%
}
\newcommand\expandafterallthataux[2]{#2{#1}}
\newcommand\somecommand[2]{\detokenize{#1:::#2}}
\newcommand\secondarg{\thirdarg}
\newcommand\thirdarg{\fourtharg}
\newcommand\fourtharg{example}
\begin{document}
\expandafterallthat{\somecommand{Some Argument}}{\secondarg}

\end{document}

will multiply-expand input. (You don't say whether to expand #2 once or several times.)

share|improve this answer
    
Just seeing now that my added solution is the almost the same as yours. (I really should use \detokenize more often; I still use \@onelevel@sanitize!). The second argument should actually only be expanded once, i.e. contain \thirdarg, shouldn't it? If not, then the \romannumeral` trick is nice1 –  Martin Scharrer Jul 4 '11 at 14:29
    
@Martin From the context in the question I was not sure, so I've gone for full expansion. (The \detokenize here is just a nice way to show quickly what the macro received.) –  Joseph Wright Jul 4 '11 at 14:37
    
Why does \romannumeral-`0 still expands afterwards, but does not actually consume following numbers? I thought if #2 would start with numbers these would be consumed, but then figured that `0 actually already provides a full number (ASCII code of character 0). But why is it still expanding, i.e. in look-for-a-number mode? –  Martin Scharrer Jul 4 '11 at 14:40
    
@Martin Scharrer You see the same for \number. Try for example \def\test{1}\detokenize\expandafter{\number-`0\test}. I've never been quite clear why, but as it works ... –  Joseph Wright Jul 4 '11 at 14:54
4  
@Martin, @Joseph: TeX is looking for an optional space. –  Hendrik Vogt Jul 4 '11 at 15:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.