I was surprised to find that the argument of an \unexpanded
is expanded if the \unexpanded
is within the first two tokens after an \if
.
Using Knuth TeX's \noexpand
instead works but I am curious where the difference is.
\documentclass{article}
\begin{document}
\def\endtoken{~}
\typeout{! ========== tracing 1 ==========}
\tracingmacros=2
\tracingcommands=3
% \if \expandafter\noexpand\endtoken \noexpand~% this would work
\if \unexpanded\expandafter{\endtoken} \noexpand~% this does not
true
\else
false
\fi
\tracingcommands=0
\tracingmacros=0
\typeout{! ========== tracing 0 ==========}
\end{document}
The \expandafter
which expands the argument of the \unexpanded
once makes no difference.
~
is expanded all the way with or without it and the result is the same.
\tracingmacros
shows how ~
is expanded and \tracingcommands
shows that \if
evaluates to true.
I am assuming that it comes to this result by comparing \protect
and \unhbox
which are both inserted by expanding ~
and are equal because they are both control sequences.
Is there a tracing command which would show which tokens TeX compares when evaluating a conditional?
(I have scanned through the great list of tracing commands but have not found this among it unfortuantely.)
(The exclamation mark at the beginning of the \typeout
makes TeXstudio think there was an error so that it provides me with a link to the position in the log file where the output of the tracing commands begins and ends. This may, however, have the unintended side effect that it does not load the pdf although it has been built correctly.)
Why is the argument of \unexpanded
expanded after an \if
(not inside of an \edef
) but a token following a \noexpand
is not expanded, even after an \if
?
The interesting question Get the lion to run in loops. Tersely. also deals with \if
and \unexpanded
but I think it does not answer this question because there the \fi
is in the <filler>
of \unexpanded
but here after the <balanced text>
and the closing curly brace.
\noexpand
and\unexpanded
is worth detailing, but @egreg is right that the test here is ... not really correct\edef
etc. "hard code"\the\toks
etc. to insert the content verbatim, so • first, # are not halved • even if you do\edef\something{\expandafter\empty\unexpanded{...}}
,\unexpanded
loses its magic even if it's inside an edef.\edef
expands the\expandafter
which expands the\unexpanded
. During this expansion\unexpanded
does it's magic but that has no effect because\expandafter
expands only a single token. Then\edef
continues to expand the remaining tokens, first the\empty
and then the...
which is now unprotected because the\unexpanded
has been removed by the\expandafter
. (The curly braces have been removed when expanding the\unexpanded
.)\expandafter
expands only a single token", it's that "\unexpanded
(like\the\toks
) only protects the content inside when it's in a\edef
". If you do\expandafter\empty\romannumeral ...
, arbitrarily many tokens after\romannumeral
will be expanded until a complete number is formed.\def\bar{2} \romannumeral1\unexpanded{\bar}
expands\bar
and so does\expandafter\show\csname foo\unexpanded{\bar}\endcsname
. Thanks for pointing that out. Guess I still haven't really gotten used to\unexpanded
.