我遇到了 RevTeX 和 AMSLaTeX 之间的奇怪冲突。如果我将一个split
环境嵌套在另一个align
环境中,它会正常工作,但下次我\tensor{}
在文档中使用 RevTeX 宏时,它会重复方程的最后一行split
。
这是一个最小的“工作”示例:
\documentclass[12pt,prd,amsmath]{revtex4}
\begin{document}
Here is a split inside an align
\begin{align}
A &= B \\
\begin{split}
C &= D \\
&= E
\end{split}
\end{align}
And now we write a tensor $\tensor{T}$ which grabs the second line.
\end{document}
答案1
如果您
{\let\protect\show\tensor}
(这让我们看到受保护的命令是如何实现的)。我们得到
> \tensor =\long macro:
#1->\@ontopof {#1}{\leftrightarrow }{1.15}\mathord {\box 2}
关键是\box 2
。发生的事情是\tensor
插入该框中的任何东西。据推测这通常是完全安全的,但 正在使用同一个框align
,您可以通过类似以下内容看到
\begin{align}
A &= B \\
\begin{split}
C &= D \\
&= E
\end{split}
\end{align}
\copy2
这看起来像是 REVTeX 中的一个错误。您可以清空框 2 来解决这个问题。我想这应该作为 的一部分来完成\tensor
,所以类似
\documentclass[12pt,prd,amsmath]{revtex4}
\usepackage{letltxmacro}
\LetLtxMacro{\savedtensor}{\tensor}
\DeclareRobustCommand{\tensor}{%
\setbox2=\hbox{}%
\savedtensor
}
\begin{document}
Here is a split inside an align
\begin{align}
A &= B \\
\begin{split}
C &= D \\
&= E
\end{split}
\end{align}
And now we write a tensor $\tensor{T}$ which grabs the second line.
\end{document}
将是一个合理的解决办法。
答案2
\tensor
在包中定义revsymb
,并由类加载revtex4
:
\DeclareRobustCommand\tensor[1]{\@ontopof{#1}{\leftrightarrow}{1.15}\mathord{\box2}}
宏\@ontopof
用于\mathchoice
获取当前数学样式,并为放置在其上方的双箭头配置数学样式#1
:
\def\@ontopof#1#2#3{%
{%
\mathchoice
{\@@ontopof{#1}{#2}{#3}\displaystyle \scriptstyle }%
{\@@ontopof{#1}{#2}{#3}\textstyle \scriptstyle }%
{\@@ontopof{#1}{#2}{#3}\scriptstyle \scriptscriptstyle}%
{\@@ontopof{#1}{#2}{#3}\scriptscriptstyle\scriptscriptstyle}%
}%
}%
实际工作由 完成\@@ontopof
。
\def\@@ontopof#1#2#3#4#5{%
\setbox\z@\hbox{$#4#1$}%
\setbox\f@ur\hbox{$#5#2$}%
框 0 包含基本符号#1
,框 4 包含将放置在框 0 上的双箭头。
\setbox\tw@\null\ht\tw@\ht\z@ \dp\tw@\dp\z@
框 2 记住了框 0(基本符号)的高度和深度。
\@ifdim{\wd\z@>\wd\f@ur}{%
\setbox\f@ur\hb@xt@\wd\z@{\hss\box\f@ur\hss}%
\mathord{\rlap{\raise#3\ht\z@\box\f@ur}\box\z@}%
}{%
\setbox\f@ur\hb@[email protected]\wd\f@ur{\hss\box\f@ur\hss}%
\setbox\z@\hb@xt@\wd\f@ur{\hss$#4\relax#1$\hss}%
\mathord{\rlap{\copy\z@}\raise#3\ht\z@\box\f@ur}%
}%
}%
问题在于,对框 2 的分配是在组内本地完成的(顺便说一句,偶数寄存器 0、2、4、6 和 8 用于本地分配,奇数寄存器 1、3、5、7 和 9 用于全局分配)。因此,在\@ontopof
完成工作后,框 2 的设置将丢失,并且框 2 的先前内容将用于\tensor
。
我认为这个想法是让复合符号保留基本符号的原始高度和深度。这样可以避免高度较大的符号破坏行距,但存在冲突的风险。
下面的例子实现了这个想法
\m@th
如果不为零,则添加到框设置中以重置\mathsurround
以避免不必要的空间增加。\mathsurround
- 简化了箱体结构的复杂性。
- 修复底部符号的宽度位于顶部符号宽度的 0.9 到 1 之间的情况。
\tensor
除使用\@ontopof
with之外,还有其他宏\box2
。
使用顶部符号宽度 90% 的猜测解释:
根据符号的宽度,较小的符号水平居中,位于与较宽符号宽度相同的框中。虽然取的是底部符号的整个宽度,但只取顶部符号的实际宽度。整个宽度由实际字形宽度和左右侧边距组成。代码假设每侧为 5%,并将字形宽度估计为字符框宽度的 90%。
\documentclass[12pt,prd,amsmath]{revtex4}
\makeatletter
\DeclareRobustCommand\REV@dddot[1]{\@ontopof{#1}{\cdots}{1.0}}
\DeclareRobustCommand\tensor[1]{\@ontopof{#1}{\leftrightarrow}{1.15}}
\DeclareRobustCommand\overstar[1]{\@ontopof{#1}{\ast}{1.15}}
\DeclareRobustCommand\loarrow[1]{\@ontopof{#1}{\leftarrow}{1.15}}
\DeclareRobustCommand\roarrow[1]{\@ontopof{#1}{\rightarrow}{1.15}}
\def\@@ontopof#1#2#3#4#5{%
\setbox\z@\hbox{$\m@th#4#1$}%
\setbox\f@ur\hbox{$\m@th#5#2$}%
\@ifdim{\wd\z@>.9\wd\f@ur}{%
\setbox\f@ur\hb@xt@\wd\z@{%
\hss
\raise#3\ht\z@\box\f@ur
\hss
}%
\wd\f@ur\z@ \ht\f@ur\z@ \dp\f@ur\z@
\setbox\z@\hbox{%
\box\f@ur
\box\z@
}%
}{%
\setbox\f@ur\hb@[email protected]\wd\f@ur{%
\hss \raise#3\ht\z@\box\f@ur \hss
}%
\setbox\z@\hbox to \wd\f@ur{%
\wd\f@ur\z@ \ht\f@ur\z@ \dp\f@ur\z@
\box\f@ur
\hss \box\z@ \hss
}%
}%
\box\z@
}%
\makeatother
\begin{document}
\setlength{\fboxsep}{0pt}
\setlength{\fboxrule}{.1pt}
\newcommand*{\test}[1]{%
\fbox{$#1{T}$}, \fbox{$#1{\mathrm{I}}$}
}
\begin{gather*}
\test\dddot\\
\test\tensor\\
\test\overstar\\
\test\loarrow\\
\test\roarrow
\end{gather*}
Here is a split inside an align
\begin{align}
A &= B \\
\begin{split}
C &= D \\
&= E
\end{split}
\end{align}
And now we write a tensor $\tensor{T}$ which grabs the second line.
\end{document}