\newif 条件导致 \typeout 或 \edef 出现问题

\newif 条件导致 \typeout 或 \edef 出现问题

以下代码产生预期的结果,即

假 真

在排版文档上。

\documentclass{minimal}

\newif\iftest

\newcommand{\test}[2]{
\iftest
  #1
\else
  #2
\fi
}
\newcommand{\ex}{\test{True}{False}\testtrue\test{True}{False}}

\begin{document}
\ex
\end{document}

但是,如果我\ex用 来包装\typeout,或者尝试用\edef\ex来代替,\newcommand我会得到:

! Incomplete \iffalse; all text was ignored after line...

答案1

这里的问题是\testtrue不可扩展且不受保护,因此很脆弱。它被定义为\let\iftrue\iftrue。在可扩展上下文中,例如\edef或 ,\typeout赋值\let被忽略,并且两个 if 开关都被扩展。因为只有一个\fi(被视为 的一部分\iftrue),所以编译器会抱怨缺少\fi

您可以\test{<true>}{<false>}在此上下文中使用,但不能使用\testtrue\testfalse。因此,您需要执行以下操作:

\typeset{\test{True}{False}}
\testtrue
\typeset{\test{True}{False}}

我想再给你一个建议。我将\test宏定义如下:

\makeatletter
\newcommand{\test}{%
  \iftest
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\makeatother

这样,if 语句在处理两个参数之一之前就已完全处理。这避免了在 if-switch 中使用代码时可能出现的一些问题。例如,使用\newif 如果要跳过该参数,则在这样的参数内使用它将会中断。\@firstoftwo\@secondoftwo宏只需接受两个参数并扩展为第一个或第二个。 先扩展\expandafter(即在本例中移除)\else\fi。 还请注意,%后面的{是必需的,以避免换行符在那里添加空格。

相关内容