# Error using \string

Consider

\documentclass{article}

\usepackage{lmodern}

\usepackage[T1]{fontenc}

\begin{document}

\texttt{\string\iftrue}

%% \texttt =\long macro:
%% #1->\ifmmode
%%       \nfss@text{\ttfamily#1}
%%     \else
%%       \hmode@bgroup\text@command{#1}\ttfamily\check@icl#1\check@icr\expandafter\egroup
%%     \fi

\end{document}


Processing this minimal example with pdflatex results in a rather nasty Incomplete \ifmmode error during the expansion of \texttt{\string\iftrue}. It seems to me that \string does not totally prevent TeX from taking account of \iftrue as a conditional. (The same is true for \detokenize, by the way.)

Can anybody explain what is precisely going on?

Addendum: Note that the error would disappear if \texttt stored its argument in an auxiliary macro before processing it.

-

Consider:

\iffalse
\string\iftrue
\fi


On seeing the \iffalse TeX scans ahead matching tokens with definitions \if (or the other primitive if tokens such as \ifx \iftrue etc) \else and \fi to get to a matching \fi when normal operation re-starts. In particular it does not execute any assignments or expand any tokens. So \string is simply skipped over but the inner \iftrue is seen so the \fi matches the \iftrue and things go wrong.

Depending what you want to do

\iffalse
\textbackslash iftrue
\fi


or

\iffalse
\csname iftrue\endcsname
\fi


or

\iffalse
\expandafter\string\csname iftrue\endcsname
\fi


are all safe. (Or similarly and more usefully perhaps the same with \iftrue as the first token.)

-
OK, I think I understand: The key point is that TeX parses conditionals in a totally context-free manner. –  mhp Jun 29 '12 at 7:53

You need to bear in mind that TeX is a macro expansion language. Thus

\texttt{\string\iftrue}


expands the definition of \texttt with an argument containing two tokens, \string and \iftrue. That leads to

\ifmmode
\nfss@text{\ttfamily\string\iftrue}
\else
\hmode@bgroup
\text@command{\string\iftrue}%
\ttfamily
\check@icl\string\iftrue\check@icr
\expandafter\egroup
\fi


(formatting mine). TeX then scans the conditional, finds more tokens which start \if... statements than end them, and complains.

What you presumably want to do is pass the string \iftrue to \texttt:

\expandafter\texttt\expandafter{\string\iftrue}

-
Or the easier \texttt{\char\\iftrue}. –  egreg Jun 28 '12 at 17:41
@egreg That's not a string: iftrue is made of catcode 11 tokens :-) –  Joseph Wright Jun 28 '12 at 17:46
(Of course, that might be important in some contexts, but not here) –  Joseph Wright Jun 28 '12 at 17:58
@JosephWright: Expanding the argument in advance is definitely a useful remedy. Is there, actually, a more general argument processor capable of expanding an arbitrary brace-delimited argument such as {text \string\iftrue text}? –  mhp Jun 29 '12 at 8:41
@mhp Depending on the context, you could either \edef everything into a temporary variable or use \romannumeral` to force expansion; the latter method is itself expandable. –  Joseph Wright Jun 29 '12 at 8:43