我正在尝试在 LaTeX3 函数中使用全局布尔变量b
。我希望我的函数F
在b
为 false 时打印,在为 trueT
时打印。b
这在文本和常规数学中效果很好,但T
如果我尝试在或amsmath
等环境中使用它,它总是会打印出来。它看起来像是在最终渲染之前至少扩展/评估一次其环境的内容。我该如何避免这种情况/修复我的功能?gather
align
amsmath
下面是一个 MWE,我去掉了一些好的做法,例如\NewDocumentCommand
并\cs_new_protected:Npn
使其尽可能最小化:
\documentclass{minimal}
\usepackage{amsmath}
\usepackage{etoolbox}
\ExplSyntaxOn
\NewDocumentCommand{\defit}{m}{
\bool_new:c { g_it_#1_used }
}
\NewDocumentCommand{\getit}{m}{
\bool_if:cTF { g_it_#1_used } { T } { F\bool_gset_true:c { g_it_#1_used } }
}
\ExplSyntaxOff
\begin{document}
\defit{test}\getit{test}\getit{test}\getit{test}
\defit{eqn}
\[
\getit{eqn} \getit{eqn} \getit{eqn}
\]
\defit{ams}
\begin{gather*}
\getit{ams} \getit{ams} \getit{ams}
\end{gather*}
\end{document}
预期输出是FTT
三次。但我得到的是FTT
,,FTT
。TTT
答案1
某些amsmath
环境(例如gather
或align
)不会仅排版其内容一次:排版一次用于测量(然后丢弃),另一次用于实际排版。
但是,您的\getit
函数在第一次使用时(对于环境而言,这gather
发生在测量时)会全局设置布尔值,并且测量运行的输出(这是 FTT
) 被丢弃,然后您只能看到TTT
排版运行。
您可以使用\ifmeasuring@
条件来检测您是否处于测量运行中,在这种情况下跳过更改布尔值:
\documentclass{minimal}
\usepackage{amsmath}
\usepackage{etoolbox}
\ExplSyntaxOn
\NewDocumentCommand \defit { m }
{ \bool_new:c { g_it_#1_used_bool } }
\NewDocumentCommand \getit { m }
{
\bool_if:cTF { g_it_#1_used_bool }
{ T }
{
F
\legacy_if:nF { measuring@ }
{ \bool_gset_true:c { g_it_#1_used_bool } }
}
}
\ExplSyntaxOff
\begin{document}
\defit{test}\getit{test}\getit{test}\getit{test}
\defit{eqn}
\[
\getit{eqn} \getit{eqn} \getit{eqn}
\]
\defit{ams}
\begin{gather*}
\getit{ams} \getit{ams} \getit{ams}
\end{gather*}
\end{document}
请注意,测量时的输出应与排版时的输出宽度相同,否则输出可能看起来未对齐。