amsmath 对齐环境:使用 tbtags 在最后一行正确定位方程编号

amsmath 对齐环境:使用 tbtags 在最后一行正确定位方程编号

总结

如何将方程编号放在{aligned}[t]环境的最后一行?
(在最后一行后的对齐环境中的方程编号如何定位“嵌套”对齐环境的标签?,但我在这里描述的情况比较复杂,不能通过那里发布的答案轻易解决。)

情况

考虑以下情况:包tbtags的选项amsmath正在使用中,即右侧的标签应始终放在每个方程的最底行。我在单个align环境中有多个方程。所有关系符号都需要对齐。在每个方程中,我可能需要额外的对齐点。(在下面的例子中,左括号将对齐。)次要对齐点不会位于同一水平位置。(即,alignat不能在这里使用。)方程式通过嵌套alignedsplit和内进行排版align

这个例子

\documentclass{article}
\usepackage[tbtags]{amsmath}
\begin{document}
\begin{align}
 x &= 1234[\!\begin{aligned}[t]
          &(a+b)\\
          &(c+d+e)\\
          &(f+g)]\end{aligned}\\
\begin{split}
 y &= 5[(h+i)+j]\\
   &= 6[\!\begin{aligned}[t]
       &(k+l)\\
       &(m+n+o)]\end{aligned}
\end{split}
\end{align}
\end{document}

编译示例

图中黑色字体显示了编译示例代码时的输出。方程式本身的排版完全符合我的要求,但我不同意方程式编号的位置。红色数字显示了我希望标签的位置。

问题

方程编号为不是放在数学上被认为是方程的最后一行,即第 3 行和第 6 行。相反,它们被放在第 1 行和第 5 行。(我认为发生这种情况是因为 LaTeX 内部只有第 1、4 和 5 行实际上被视为行。)

解决方案?

  1. aligned完全不要使用。(split也不要使用。)\notag在第 1、2、4 和 5行使用。\hphantom{{}=prefactor[}在第 2、3 和 6 行使用类似的内容。
  2. 将每个方程式放在 a 中split并使用类似的方法\end{aligned}\\[-XXpt]&\end{split}\\[YYpt],从而引入一个 LaTeX 认为值得编号的新行,但将其向上移动,以便打印的标签不出现在其自己的行上,而是出现在前一行上。
  3. 我讨厌解决方案 1 和 2。解决方案 1 需要多次重复前因子(我能做的最好的事情是将其存储在每个方程的宏中,并在需要前导空格的每一行上调用它),解决方案 2 需要微调垂直空间 XX 和 YY(我不知道是否可以测量并自动插入它们)。两者都很乏味,可能会产生我不知道的意外副作用,在排版大量方程时会非常烦人,如果由于行太长而必须将标签从其默认位置移动,它可能会失败。

有人能想到更好、更自动化或更优雅的解决方案吗?

附加问题

如果您对上述问题有一个很好的解决方案,那么您可能也能回答这个问题:当cases使用 (而不是aligned)时,如何解决同样的问题,即如何将标签放在最后一种情况的行上?在这种情况下,解决方案 1 无法使用,而解决方案 2 的计算变得更加复杂。

奖金奖金问题

aligned如果您有内部cases内部split内部,如何解决同样的问题align

答案1

这用于tikz放置(覆盖)标签,因此需要两次运行才能正确定位标签。

它忽略方程是否太宽,因为标签所在的位置可能不会太宽。 \taghere确实提供了一个可选参数来应用额外的垂直偏移。

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}

\makeatletter
\newif\iftag@here

\newcommand*{\taghere}[1][0pt]% #1 = additional vertical offset (optional)
{\ifmeasuring@\else% do not expand until displayed
  \global\tag@heretrue
  \tikz[remember picture,overlay]{\coordinate (taghere) at (0pt,#1);}%
\fi}

\def\place@tag{%
    \iftagsleft@
      \kern-\tagshift@
      \iftag@here
        \global\tag@herefalse
        \tikz[remember picture,overlay]%
          {\path (taghere) -| node[anchor=base]{\rlap{\boxz@}} (0pt,0pt);}%
      \else
        \if1\shift@tag\row@\relax
            \rlap{\vbox{%
                \normalbaselines
                \boxz@
                \vbox to\lineht@{}%
                \raise@tag
            }}%
        \else
            \rlap{\boxz@}%
        \fi
        \kern\displaywidth@
      \fi% end of \iftag@here
    \else
      \kern-\tagshift@
      \iftag@here
        \global\tag@herefalse
        \tikz[remember picture,overlay]%
          {\path  (taghere) -|  node[anchor=base]{\llap{\boxz@}} (0pt,0pt);}%
      \else
        \if1\shift@tag\row@\relax
            \llap{\vtop{%
                \raise@tag
                \normalbaselines
                \setbox\@ne\null
                \dp\@ne\lineht@
                \box\@ne
                \boxz@
            }}%
        \else \llap{\boxz@}%
        \fi
      \fi% end of \iftas@here
    \fi
}
\makeatother

\begin{document}
\begin{align}
 x &= 1234[\!\begin{aligned}[t]
          &(a+b)\\
          &(c+d+e)\\
          &(f+g)\taghere]
          \end{aligned}\\
\begin{split}
 y &= 5[(h+i)+j]\\
   &= 6[\!\begin{aligned}[t]
       &(k+l)\\
       &(m+n+o)\taghere]
      \end{aligned}
\end{split}\\
z &= \begin{cases}
       1 & x>0\\
       0 & \textrm{otherwise}\taghere
    \end{cases}
\end{align}

\end{document}

演示

答案2

split仅允许一个对齐点。使用幻影:

\documentclass{article}
\usepackage[tbtags]{amsmath}

\newcommand\?[1]{\mathopen{\hphantom{#1}}}

\begin{document}

\begin{align}
\begin{split}
 x ={}& 1234[(a+b)\\
      & (c+d+e)\\
      & (f+g)]
\end{split}\\
\begin{split}
 y ={}& 5[(h+i)+j]\\
   ={}& 6[(k+l)\\
      & (m+n+o)]
\end{split}
\end{align}

\begin{align}
\begin{split}
 x ={}& 1234[(a+b)\\
      & \?{1234[}(c+d+e)\\
      & \?{1234[}(f+g)]
\end{split}\\
\begin{split}
 y ={}& 5[(h+i)+j]\\
   ={}& 6[(k+l)\\
      & \?{[}(m+n+o)]
\end{split}
\end{align}

\end{document}

在此处输入图片描述

答案3

我被指向\pdfsavepos并找到了该zref-savepos包。我尝试基于此功能构建替代解决方案。它对aligned和有效(至少在某种程度上) cases。实现基本上测量中心和底线的位置差异,然后\raiseboxes 除&符号标记之外的所有内容。

  1. 对于长线,方程编号有时(但并非总是)有点太远。它似乎取决于周围的方程。(我完全不理解这种行为。)
  2. 如果线条很大,则标签位于所需的基线上。
  3. 它在里面工作split
  4. 如果最后一种情况是,那么我的替代方案cases将无法正常工作。aligned

我对我的新命令的语法很不满意。它不灵活,而且与标准环境非常不同,但这是我目前能想到的最好的方法。

有没有办法垂直移动数学内容而不必诉诸\raisebox{len}{$inline-math$}? 有没有办法提高或降低 & 符号的位置? (它不能放在内联数学中。)

\documentclass{article}
\usepackage[tbtags]{amsmath}
\usepackage{zref-savepos}

\newcounter{index}

% Three arguments:
% #1 terms left of the relation symbol
% #2 relation symbol and prefactors
% #3 content to be put in aligned/cases

\newcommand{\myaligned}[3]{%
\stepcounter{index}%
\raisebox{\dimexpr\zposy{c\theindex}sp-\zposy{b\theindex}sp}{$\displaystyle#1$}%
&%
\raisebox{\dimexpr\zposy{c\theindex}sp-\zposy{b\theindex}sp}{$\displaystyle{}#2\zsaveposy{c\theindex}\!\begin{aligned}[t]#3\zsaveposy{b\theindex}\end{aligned}$}%
}

\newcommand{\mycases}[3]{%
\stepcounter{index}%
\raisebox{\dimexpr\zposy{c\theindex}sp-\zposy{b\theindex}sp}{$\displaystyle#1$}%
&%
\raisebox{\dimexpr\zposy{c\theindex}sp-\zposy{b\theindex}sp}{$\displaystyle{}#2\zsaveposy{c\theindex}\begin{cases}#3\zsaveposy{b\theindex}\end{cases}$}%
}

\begin{document}
\begin{minipage}{.4\textwidth}
\begin{align}
%  uncommenting this somehow fixes the too large separation of the first tag
%  a&=a\\
 \myaligned{x}{=1234[}{
  &(a+b)\\
  &(c+d+e)\\
  &(f+g)loooooooong]
 }\\
\begin{split}
 y&=5[(h+i)+j]\\
  \myaligned{}{=6[}{
   &\biggl(k+l\biggr)\\
   &\biggl(m+n+o\biggr)]
  }
\end{split}
\end{align}

\begin{align}
 x&=1\\
\begin{split}
 y&=first\ line\ in\ split\\
  \mycases{}{=prefactor}{
   blah\\
   blah\\
   blah\\
   blah
  }
\end{split}\\
 z&=3
\end{align}

\begin{align}
 \mycases{y}{=2}{
  blah\\
  blah\\
  aligned\!\begin{aligned}[t]&first\\&second\end{aligned}
 }
\end{align}
\end{minipage}
\end{document}

在此处输入图片描述

相关内容