Revtex 的张量宏干扰嵌套的 amsmath 拆分和对齐环境

Revtex 的张量宏干扰嵌套的 amsmath 拆分和对齐环境

我遇到了 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除使用\@ontopofwith之外,还有其他宏\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}

结果

相关内容