使用 \string 时出错

使用 \string 时出错

考虑

\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}

处理这个最小示例会导致在扩展 时pdflatex出现相当严重的错误。在我看来,这并不能完全阻止 TeX 将 视为条件。(顺便说一下, 也是如此。)Incomplete \ifmmode\texttt{\string\iftrue}\string\iftrue\detokenize

有人能解释一下到底发生了什么吗?


附录:\texttt请注意,如果在处理之前将其参数存储在辅助宏中,错误就会消失。

答案1

考虑:

\iffalse
\string\iftrue
\fi

看到\iffalseTeX 扫描匹配的标记与定义 \if(或其他原始 if 标记,如\ifx \iftrue等)\else并在正常操作重新启动时\fi获得匹配。特别是它确实\fi不是执行任何分配或扩展任何标记。因此,\string它只是被跳过,但内部\iftrue可见,因此\fi匹配\iftrue,事情就出错了。

取决于你想做什么

\iffalse
 \textbackslash iftrue
\fi

或者

\iffalse
\csname iftrue\endcsname
\fi

或者

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

都是安全的。(或者类似且更有用,可能与\iftrue第一个标记相同。)

答案2

你需要记住 TeX 是一种宏扩展语言。因此

\texttt{\string\iftrue}

\texttt用包含两个标记的参数扩展了 的定义,\string并且\iftrue。这导致

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

(格式化我的)。然后 TeX 扫描条件,发现启动\if...语句的标记比结束语句的标记多,并且发出警告。

您可能想要做的是将字符串传递\iftrue\texttt

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

相关内容