根据其他条件设置条件

根据其他条件设置条件

我正在尝试根据另一个条件将条件设置\if...为 true 或 false。类似于以下内容:

\documentclass{article}

\newif\iffirst

\iftrue
  \let\iffirst\iftrue% ... similar to \firsttrue
\else
  \let\iffirst\iffalse% ... similar to \firstfalse
\fi

\begin{document}

\iffirst
  First
\else
  Not first
\fi

\end{document}

从逻辑上讲,输出应该是First,因为\iffirst设置为\iftrue。但是,它不起作用。为什么不行?我以为一旦评估了条件(\iftrue\iffalse),它就会执行真/假子句,并且\let<cmdA><cmdB>有效。

可以使用\let\iffirst\iftrue/代替/ 。但是,它们具有相同的含义(即reveals和类似reveals )。那么,为什么/有效,而明确指定/无效?\let\iffirst\iffalse\firsttrue\firstfalse\show\firsttrue\let\iffirst\iftrue\show\firstfalse\let\iffirst\iffalse\firsttrue\firstfalse\let\iffirst\iftrue\let\iffirst\iffalse

以下解决方法也有帮助,但不能回答问题:

\documentclass{article}

\newcommand{\firstoftwo}[2]{#1}% Similar to \@firstoftwo
\newcommand{\secondoftwo}[2]{#2}% Similar to \@secondoftwo

\iftrue
  \let\firstsecond\firstoftwo
\else
  \let\firstsecond\secondoftwo
\fi

\begin{document}

\firstsecond{%
  First
}{%
  Not first
}

\end{document}

答案1

TeX 在跳过块时不会查看代码的语法\if..\else..\fi,因此它不知道\let应该使用两个标记。这意味着在\let\iffirst\iftrue\iffirst等于\iffalse)中有两个\if但没有\fi,因此当 TeX 尝试平衡它们时,它不会按照您的预期执行。根据 TeX 看到的内容重新缩进您的代码,它看起来像这样:

\iftrue % \if level 1
  \let\iffirst\iftrue
\else % \else level 1
  \let
  \iffirst % \if level 2
    \iffalse % \if level 3
    \fi % \fi level 3

这显然是错误的。执行代码时,\iftrue\if level 1)为真,因此\let\iffirst\iftrue执行。然后\else看到,并且 TeX 开始寻找\fi level 1,但这里\iffirst\iffalse被误解,并且\fi缺少两个。

设置条件时解决此问题的一个好方法是首先完全评估该\iftrue..\else..\fi块,然后仅然后执行\let\iffirst\if<something>,然后确保两者都不会被解释为开始另一个\if级别(这大致是expl3条件的实现方式,因此它们可以轻松嵌套而不必担心平衡\if..\else..\fi):

\documentclass{article}

\newif\iffirst

\makeatletter
\iftrue
  \expandafter\@firstoftwo
\else
  \expandafter\@secondoftwo
\fi
  {\let\iffirst\iftrue}%
  {\let\iffirst\iffalse}%
\makeatother

\begin{document}

\iffirst
  First
\else
  Not first
\fi

\end{document}

这个特性,在平衡条件时不看代码的含义,允许附录 D 中介绍的带括号的肮脏技巧。这是一个明显不平衡的代码的例子,它实际上工作正常(请注意,text没有用粗体打印):

{\bfseries
  bold
  \iffalse {\fi }
  text

相关内容