5

I try to understand how work the macro named \separator in MWE .

\documentclass[]{article}

\def\separator#1\separator#2{%
\unexpanded{#1}%
\ifx*#2%
\else
, \expandafter\separator\expandafter#2%
\fi
}%



    \def\stcs{\separator One\separator Two\separator three}

    \tracingmacros 1
    \begin{document}

    \stcs\separator*

    \end{document}

Trace of \separator is following:

\stcs ->\separator One\separator Two\separator three

\separator #1\separator #2->\unexpanded {#1}\ifx *#2\else , \expandafter \separator \expandafter #2\fi 
#1<-One
#2<-T

\separator #1\separator #2->\unexpanded {#1}\ifx *#2\else , \expandafter \separator \expandafter #2\fi 
#1<-Two
#2<-t

\separator #1\separator #2->\unexpanded {#1}\ifx *#2\else , \expandafter \separator \expandafter #2\fi 
#1<-three
#2<-*

What have I see.

At the first stage:


First: \separator gets a #1 as 'One' -this is normal for me. Second: \separator gets a #2 only 'T' but not 'Two'. Why?

At the second stage:


First: \separator gets a #1 as 'Two'. Why not 'T', as one can see from the first stage? And what had become of this 'T'? It lost?

\LaTeX pdf output is normal "One, Two, three". Thus, what is happen with #2?

1 Answer 1

5

#1 is a delimited argument that consists of all tokens up to the specified delimiter, \separator here. LaTeX doesn't really support the definition of such arguments (hence the use of \def rather than \newcommand.

#2 is a normal non-delimited argument. So this takes a single token or {} group. In the case you trace it just gets T just as if you go \fbox abc the argument of \fbox is just a.

#2 is just used for testing and if you are not at the end it is put back here:

\expandafter\separator\expandafter#2%

so when that \separator is expanded it sees

Two\separator three

in the input stream The T having been put back, so takes Two as #1 and t as #2 and the loop continues.

7
  • What does it mean "put back"? It is in the stack or what? Jan 24, 2015 at 13:09
  • @sergiokapone tex is a macro expansion language, not a compiled program, the engine works on a stream of tokens, if first token is expandable then it is replaced in the stream by its expansion then processing re-starts at the (new) start of the stream Jan 24, 2015 at 13:28
  • as I read about \expandafter the token #2 is saved without expansion, because it is immediately after \expandafter. Why is it needed? Jan 24, 2015 at 13:49
  • @sergiokapone If #2 is one token then the \expandafter chain will expand the \fi, closing the conditional and making the code tail recursive. If #2 isn't one token then this fails to do anything useful (won't be an issue in a lot of cases).
    – Joseph Wright
    Jan 24, 2015 at 14:24
  • @Joseph Wright as I understand you, the second \expandafter LaTeX consider as \expandafter#2\fi and an expansion of \fi is just a closing a condition. Am I correct? Jan 24, 2015 at 16:50

You must log in to answer this question.

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