总结
如何将方程编号放在{aligned}[t]
环境的最后一行?
(在最后一行后的对齐环境中的方程编号和如何定位“嵌套”对齐环境的标签?,但我在这里描述的情况比较复杂,不能通过那里发布的答案轻易解决。)
情况
考虑以下情况:包tbtags
的选项amsmath
正在使用中,即右侧的标签应始终放在每个方程的最底行。我在单个align
环境中有多个方程。所有关系符号都需要对齐。在每个方程中,我可能需要额外的对齐点。(在下面的例子中,左括号将对齐。)次要对齐点不会位于同一水平位置。(即,alignat
不能在这里使用。)方程式通过嵌套aligned
在split
和内进行排版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 行实际上被视为行。)
解决方案?
aligned
完全不要使用。(split
也不要使用。)\notag
在第 1、2、4 和 5行使用。\hphantom{{}=prefactor[}
在第 2、3 和 6 行使用类似的内容。- 将每个方程式放在 a 中
split
并使用类似的方法\end{aligned}\\[-XXpt]&\end{split}\\[YYpt]
,从而引入一个 LaTeX 认为值得编号的新行,但将其向上移动,以便打印的标签不出现在其自己的行上,而是出现在前一行上。 - 我讨厌解决方案 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
。实现基本上测量中心和底线的位置差异,然后\raisebox
es 除&符号标记之外的所有内容。
- 对于长线,方程编号有时(但并非总是)有点太远。它似乎取决于周围的方程。(我完全不理解这种行为。)
- 如果线条很大,则标签位于所需的基线上。
- 它在里面工作
split
。 - 如果最后一种情况是,那么我的替代方案
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}