3

Consider the following:

\def\foo#1#2 {%
  \if#1a%
    \message{#2}
  \fi}
\def\x{abc}
\edef\y{\foo\x}
\y

The result: ! Argument of \foo has an extra }.

The expected result: bc

0

1 Answer 1

5

TeX doesn't expand tokens when it's absorbing arguments to a macro. So \foo finds } when still looking for its second argument after having decided that \x is the first one.

If your aim is to have the second argument to \foo delimited by a space you should do

\def\foo#1#2 {%
  \if#1a%
    \message{#2}
  \fi}
\def\x{abc }
\edef\y{\expandafter\foo\x}
\y

so that \x is expanded before \foo starts looking for its arguments.

The macro \y will expand to \message{bc}. Note the trailing space in the replacement text for \x.


The delimiter you chose is not the best one in this particular occasion. A different strategy is to use a “reserved” token:

\def\foo#1#2\foo{%
  \if#1a%
    \message{#2}
  \fi}
\def\x{abc}
\edef\y{\expandafter\foo\x\foo}
\y

I used \foo because it's unlikely that it appears in the argument to itself.

3
  • Is it possible not to use any delimiter at all, but instead just to take the whole expansion of \x ? Can we do without adding space to \def\x ? What if \def\x{abc } will be \edef\x{\fontname\font} - I don't want this to contain any additional delimiter data. Simply leaving the space out produces just b, but I need bc. Commented Jul 3, 2015 at 23:17
  • @IgorLiferenko An argument is either delimited or undelimited. You can't have both for the same parameter.
    – egreg
    Commented Jul 4, 2015 at 6:53
  • 1
    @IgorLiferenko Maybe you need something like \def\foo#1{\expandafter\fooA#1\fooA} \def\fooA#1#2\fooA{...}. Then you can use \foo\x and \x includes "pure data" without delimiter.
    – wipet
    Commented Jul 16, 2015 at 19:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .