Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 5 down vote accepted

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.)

share|improve this answer
    
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}
share|improve this answer
    
Or the easier \texttt{\char`\\iftrue}. –  egreg Jun 28 '12 at 17:41
2  
@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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.