![即使在数学环境中调用,如何强制自定义命令生效?](https://linux22.com/image/381272/%E5%8D%B3%E4%BD%BF%E5%9C%A8%E6%95%B0%E5%AD%A6%E7%8E%AF%E5%A2%83%E4%B8%AD%E8%B0%83%E7%94%A8%EF%BC%8C%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%E8%87%AA%E5%AE%9A%E4%B9%89%E5%91%BD%E4%BB%A4%E7%94%9F%E6%95%88%EF%BC%9F.png)
我想定义一个新命令,它类似于\addstackgap
fromstackengine
包,只是它有一个可选参数。该命令修改小堆栈间隙,以便首选的填充量添加到参数的上方和下方。但是,在命令结束后,分配给小堆栈间隙的量必须恢复到其正常值,这是通过使用\stackgapSdefault
此处定义的命令来完成的。以下是一个例子:
\documentclass{IEEEtran}
\usepackage{array}
\usepackage{amsmath,amsfonts}
\usepackage{stackengine}
\newlength{\stackgapSdefaultl}
\setlength{\stackgapSdefaultl}{10mm}
\newcommand{\stackgapLdefault}{
\setstackgap{L}{\stackgapLdefaultl}
}
\newcommand{\stackgapSdefault}{
\setstackgap{S}{\stackgapSdefaultl}
}
\newcommand{\stackgapadd}[2][\stackgapSdefaultl]{
\renewcommand{\stacktype}{S} \setstackgap{S}{#1} \addstackgap{#2} \stackgapSdefault
}
\begin{document}
\begin{equation}
\left[
\stackgapadd{$e = m c^{2}$}
\right]
\end{equation}
\stackanchor{Top}{Bottom}
\end{document}
中的间隙\stackanchor{Top}{Bottom}
必须10mm
与默认设置中指定的一样。如果我们\stackgapSdefault
在方程环境后放置,间隙将重置为其默认值,但它应该会自动重置,因为\stackgapSdefault
已经包含在中\stackgapadd
。stackgapSdefault
即使处于数学模式中,我怎样才能强制它生效?
答案1
这里的问题是\setstackgap
内部调用 ,\@namedef
而后者又使用 TeX 原语 定义了一个新的宏名\def
。此类(重新)定义仅在本地组中可用(有关分组的更多信息这里\begin
),就像/隐式引入的一样\end
。这意味着当\end
执行时,对堆栈间隙的旧定义将被恢复。
作为一个简单的解决方案,我们可以重新定义\setstackgap
,以便所有定义都在全局范围内进行。将以下代码放在后面\usepackage{stackengine}
:
\renewcommand{\setstackgap}[2]{%
\expandafter\gdef\csname#1stackgap\endcsname{#2}%
}
(如果您确实需要本地和全局定义,您可以保留\setstackgap
原样的命令并定义一个新命令,如上面的全局定义命令。)
答案2
#1
由于参数的唯一两个有效选项\setstackgap
是S
和L
(分别用于“短”堆栈和“长”堆栈),因此您可以使用以下方式手动\gdef
设置所需的全局设置:
\gdef\Sstackgap{<gap>}
代替当地\setstackgap{S}{<gap>}
或
\gdef\Lstackgap{<baseline skip>}
代替当地的\setstackgap{L}{<baseline skip>}
。
但是,就OP的代码而言,您需要一个\xdef
,因为您希望默认参数是\stackgapadd
的当前值\Sstackgap
,并且\def
或\gdef
参数不能包含其自身:
\documentclass{IEEEtran}
\usepackage{array}
\usepackage{amsmath,amsfonts}
\usepackage{stackengine}
\setstackgap{L}{10mm}
\setstackgap{S}{10mm}
\newcommand{\stackgapadd}[2][\Sstackgap]{
\renewcommand{\stacktype}{S}\xdef\Sstackgap{#1}\addstackgap{#2}}
\begin{document}
\begin{equation}
\left[
\stackgapadd{$e = m c^{2}$}
\right]
\end{equation}
\stackanchor{Top}{Bottom}
\end{document}
现在,我不推荐以下做法,但似乎您确实希望这些堆栈间隙是不可变的,不受范围和组变化的影响。在包的原始版本中stackengine
,\Sstackgap
和\Lstackgap
被定义为长度,而不是\def
s。在 LaTeX 中,长度是一个全局设置。因此,另一个选项是调用[oldsyntax]
包的选项,并将这些设置用作长度,而不是 def。
\documentclass{IEEEtran}
\usepackage{array}
\usepackage{amsmath,amsfonts}
\usepackage[oldsyntax]{stackengine}
\setlength{\Lstackgap}{10mm}
\setlength{\Sstackgap}{10mm}
\newcommand{\stackgapadd}[2][\Sstackgap]{
\renewcommand{\stacktype}{S}\setlength\Sstackgap{#1}\addstackgap{#2}}
\begin{document}
\begin{equation}
\left[
\stackgapadd{$e = m c^{2}$}
\right]
\end{equation}
\stackanchor{Top}{Bottom}
\end{document}