3

This is the code, it compiles (please, don't ask me what it's for):

\documentclass{minimal}
\begin{document}
\ExplSyntaxOn
\newcommand\foo[1]{
  \tl_set:Nn \l_ebnf_tl { }
  \tl_set_rescan:Nno \l_ebnf_tl {}{#1}
  \l_ebnf_tl
}
\ExplSyntaxOff
\foo{ \textdollar}
\end{document}

However, if I modify the line with textdollar to this one (I just remove the leading space):

\foo{\textdollar}

It prints this:

! Undefined control sequence.
\l_ebnf_tl ->\?
               -cmd \textdollar \?\textdollar
l.10 \foo{\textdollar}

What is this about and how to fix? I don't need this space character over there.

yegor256
  • 12,021

1 Answers1

5

The expansion of \textdollar is (courtesy of \tl_analysis_show:N)

The token list \textdollar contains the tokens:
>  \?-cmd (control sequence=macro:#1#2->\ifx \protect \@typeset@protect \ETC.)
>  \textdollar (control sequence=macro:->\?-cmd \textdollar \?\textdollar )
>  \?\textdollar (control sequence=\long macro:->\UseTextSymbol {TS1}\te\ETC.).

The first control sequence cannot ordinarily be obtained, but it obviously can with \csname ?-cmd\endcsname. Also the third control sequence has been obtained with \csname ?\string\textdollar\endcsname.

You're applying \tl_set_rescan:no {} {\textdollar} and TeX duly expands once \textdollar before performing \tl_set_rescan:nn and you get

\tl_set_rescan:nn {} {\?-cmd \textdollar \?\textdollar}

But at this point, category codes are the standard ones, so the rescanning interprets the input as

\?•-•c•m•d• •\textdollar•\?•\textdollar

(where is used to separate one token from another)

Now \? is usually undefined and you get the error.

If you add a space like in

\foo{ \textdollar}

the o specifier means that the first token in the argument is tried for expansion. It's not expandable, so nothing happens and the rescanning produces a space followed by \textdollar.

egreg
  • 1,121,712