我正在尝试根据另一个条件将条件设置\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