原始问题
我打算使用布尔变量的状态,然后对其进行取反。取反必须延续到下一个评估变量的位置。
这可以正常工作,除了在某些 amsmath 环境(例如 gather)中,其中布尔变量始终具有最终值,无论在环境中的何处进行评估。
梅威瑟:
\documentclass{article}
\usepackage{amsmath}
\newif\ifY\Yfalse
\newif\ifZ\Zfalse
\begin{document}
\begin{equation}
\ifY true \else false \fi
\global\Ytrue
\ifY true \else false \fi
\end{equation}
\begin{equation}
\ifY true \else false \fi
\end{equation}
\begin{gather}
\ifZ true \else false \fi
\global\Ztrue
\ifZ true \else false \fi
\end{gather}
\begin{gather}
\ifZ true \else false \fi
\end{gather}
\end{document}
实际结果:
- 对于
Y
方程环境中的:“false true true” - 对于
Z
聚集环境:“true true true”
期望结果:
无论环境如何,都是“false true true”。
如何才能做到这一点?
更新完善的问题
虽然我想感谢@jasper-habicht为我最初的问题提供了正确的答案,但提出的解决方案在我的实际使用案例中也不太实用。
因此,我编写了第二个 MWE,它更接近我想要在实际应用中实现的目标。
它包括采用的解决方案https://tex.stackexchange.com/a/320586/107497@teepeemm 在下面的评论中指出了这一点。通过使用变量\ifmeasuring@
,布尔变量的状态只能在方程代码的最终评估中切换,因此在多行 amsmath 环境中也能产生所需的输出(例如gather
)。
更新的 MWE与解决方案
\documentclass{article}
\usepackage{amsmath}
\newif\ifY\Ytrue
\newif\ifZ\Ztrue
% Original code
\newcommand{\SpecialCommandY}{\ifY Y_\text{first} \global\Yfalse \else Y_\text{subsequent} \fi}
\newcommand{\SpecialCommandZ}{\ifZ Y_\text{first} \global\Zfalse \else Y_\text{subsequent} \fi}
% Improved code (produces desired result)
%\makeatletter
%\newcommand{\SpecialCommandY}{\ifY Y_\text{first} \ifmeasuring@\else\global\Yfalse\fi \else Y_\text{subsequent} \fi}
%\newcommand{\SpecialCommandZ}{\ifZ Y_\text{first} \ifmeasuring@\else\global\Zfalse\fi \else Y_\text{subsequent} \fi}
%\makeatother
\begin{document}
Desired:
\begin{equation}
\SpecialCommandY
\SpecialCommandY
\end{equation}
\begin{equation}
\SpecialCommandY
\end{equation}
Result of multi-line math environment:
\begin{gather}
\SpecialCommandZ
\SpecialCommandZ
\end{gather}
\begin{gather}
\SpecialCommandZ
\end{gather}
\end{document}
答案1
说实话,我不太确定,但我认为gather
环境会收集其内容以进行一些测量或类似操作,然后才对其进行排版。显然,在此过程中,\globalZtrue
在实际排版开始之前就已经执行了。
似乎您可以在环境的最末端添加一个钩子,全局设置布尔值,然后它仍然在相关范围内,但只执行一次:
\documentclass{article}
\usepackage{amsmath}
\newif\ifZ\Zfalse
\AddToHook{env/gather/end}{\ifZ\global\Ztrue\else\global\Zfalse\fi}
\begin{document}
\ifZ true \else false \fi
\begin{gather}
\ifZ true \else false \fi
\Ztrue
\ifZ true \else false \fi
\end{gather}
\ifZ true \else false \fi
\begin{gather}
\ifZ true \else false \fi
\Zfalse
\ifZ true \else false \fi
\end{gather}
\ifZ true \else false \fi
\end{document}