![多点自动方程对齐](https://linux22.com/image/413104/%E5%A4%9A%E7%82%B9%E8%87%AA%E5%8A%A8%E6%96%B9%E7%A8%8B%E5%AF%B9%E9%BD%90.png)
当我需要写一个很长的方程式,或者把几个密切相关的多行方程式放在一个数字下时,对齐会变得很棘手,因为我需要多个对齐点,而且布局不一定是表格状的,因为彼此上方放置的“单元格”可能有不同的宽度。
我的问题:如何自动的LaTeX 方程式中可以实现多重对齐吗?我希望有不同的对齐符号,如 &1、&2 等,这样 &1 只与 &1 对齐,&2 只与 &2 对齐,依此类推。
\minalignsep
通常,我通过设置to0pt
并使用aligned
nested into来处理多重对齐equation
(我定义了一个自定义环境来自动执行此操作)。当对齐点的数量因行而异时,对齐问题可以通过\mathrlap
frommathtools
包来解决(此时解决方案已经不是自动的,因为\mathrlap
必须在需要的地方手动放置 s)。有时这还不够,我需要使用嵌套aligned
环境或其他东西。
一个例子(红线表示对齐点):
您可以看到布局没有具有明确定义列的表格结构,它是一个“破碎”的表格,这就是为什么它需要嵌套的原因aligned
。是的,我本可以将所有内容对齐到最左边的红线上,但看起来结构不太好。
这是由
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{environ}
\renewcommand\minalignsep{0pt}
\NewEnviron{eq}[1]
{\begin{equation}
\label{eq:#1}
\begin{aligned}
\BODY
\end{aligned}
\end{equation}}
\begin{document}
\begin{eq}{random_label}
\Xi &= 666\sum_{i \in \{ \text{description of a set} \} } && (\text{a long prefactor})\\
&&&\times (\text{a long expression})\\
& \mathrlap{
\begin{aligned}
{}+ 666\sum_{i=0}^{\infty} &(\text{another long prefactor})\\
&\times (\text{another long expression})
\end{aligned}
}
\end{eq}
\end{document}
相反,我宁愿写类似的东西
\begin{eq}{random_label}
\Xi &1 = 666\sum_{i \in \{ \text{description of a set} \} } &2 (\text{a long prefactor})\\
&2 \times (\text{a long expression})\\
&1 + 666\sum_{i=0}^{\infty} &3(\text{another long prefactor})\\
&3 \times (\text{another long expression})
\end{eq}
有没有简单的方法来实现这种语法,或者需要繁琐的自定义宏?
答案1
欢迎!我不了解您的环境,但只需align
一个aligned
就可以了
\documentclass{article}
\usepackage{amsmath}
\begin{document}
\begin{align}
\Xi &= 666\sum_{i \in \{ \text{description of a set} \} }
\begin{aligned}[t]
& (\text{a long prefactor})\\
&\times (\text{a long expression})\\
\end{aligned}\notag\\
&{}+ 666\sum_{i=0}^{\infty}
\begin{aligned}[t]
&(\text{another long prefactor})\\
&\times (\text{another long expression})
\end{aligned}
\end{align}
\end{document}
答案2
你可以,但是你必须使用其他东西来\\
分离各个块,我选择了\newblock
。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{eq}{mb}
{
\seq_set_split:Nnn \l__undefnick_eq_seq { \newblock } { #2 }
\seq_map_function:NN \l__undefnick_eq_seq \__undefnick_eq_block:n
\begin{equation}\label{eq:#1}\begin{aligned}
\tl_use:N \l__undefnick_eq_tl
\end{aligned}\end{equation}
}{}
\seq_new:N \l__undefnick_eq_seq
\seq_new:N \l__undefnick_block_seq
\seq_new:N \l__undefnick_partial_seq
\tl_new:N \l__undefnick_eq_tl
\tl_new:N \l__undefnick_partial_tl
\tl_new:N \l__undefnick_last_tl
\cs_set_protected:Nn \__undefnick_eq_block:n
{
\seq_set_split:Nnn \l__undefnick_block_seq { \\ } { #1 }
\int_compare:nTF { \seq_count:N \l__undefnick_block_seq = 1 }
{% no inner block
\tl_put_right:Nn \l__undefnick_eq_tl { #1 }
}
{% inner block, we need to detach the last item
\seq_pop_left:NN \l__undefnick_block_seq \l__undefnick_partial_tl
\seq_set_split:NnV \l__undefnick_partial_seq { & } \l__undefnick_partial_tl
\seq_pop_right:NN \l__undefnick_partial_seq \l__undefnick_last_tl
% add the first to items to the body
\tl_put_right:Nx \l__undefnick_eq_tl { \seq_use:Nn \l__undefnick_partial_seq { & } }
% start making the inner aligned
\tl_put_right:Nn \l__undefnick_eq_tl { \begin{aligned}[t] }
% reinstate the last item in the partial sequence
\seq_put_left:Nx \l__undefnick_block_seq { & \exp_not:V \l__undefnick_last_tl }
% add the inner block
\tl_put_right:Nx \l__undefnick_eq_tl { \seq_use:Nn \l__undefnick_block_seq { \\ } }
% finish the inner block
\tl_put_right:Nn \l__undefnick_eq_tl { \end{aligned} \\ }
}
}
\ExplSyntaxOff
\begin{document}
\begin{eq}{random_label}
\Xi
&= 666\sum_{i \in \{ \text{some set} \} }
& (\text{a long prefactor})\\
& \times (\text{a long expression})
\newblock
&+ 666\sum_{i=0}^{\infty}
&(\text{another long prefactor})\\
&\times (\text{another long expression})
\end{eq}
\end{document}
答案3
这实际上是对@egreg 的评论,但是它太长了,不能算是评论。
我期望类似这样的算法:
- 检查公式是否具有以下形式:[某物] &[一个或多个数字] [某物] &[一个或多个数字] ... [某物]。如果不是,则发出错误。
- 找到换行符并将方程分成几行。
- 查找所有对齐符号,并按从左到右的顺序排列。如果存在矛盾的约束,则发出错误。示例:如果有三行带有对齐符号“&4 &1 &13”、“&1 &2 &3”和“&2 &4 &6”,则会出现错误,因为 &4 在 &1(第一行)的左侧,&1 在 &2(第二行)的左侧,&2 在 &4(第三行)的左侧,这是不可能的。
- 找到两个连续对齐符号之间每个“单元格”的宽度。
- 每个对齐符号对应于方程式最终布局中的一条假想垂直线。根据“单元格”宽度计算每对连续线之间的距离。例如,如果我们有三条线,形式为“&4 [smth 16mm wide] &1 [smth 5mm wide] &13”,“&1 [smth 7mm wide] &2 [smth 14mm wide] &3”,“&5 [smth 11mm wide] &4 [smth 24mm wide] &6”,则对齐点之间的距离将为“&5 11mm &4 16mm &1 5mm &13 24-16-5=3mm &6”。如果对齐点的图形有循环,则会出现矛盾的约束,并且应该发出错误。例如:三行 '&1 ... &2 ... &3'、'&4 ... &2 ... &5'、'&6 ... &5 ... &3'。其中有一个循环 '&2,第 1 行' - '&3,第 1 行' - '&3,第 3 行' - '&5,第 3 行' - '&5,第 2 行' - '&2,第 2 行' - '&2,第 1 行'。这应该是一个错误。
- 如果一行最左边的对齐符号之前有内容,则应右对齐,其他内容应左对齐。排版方程式时,使其左边界位于适当的位置,对齐点之间的距离为上一步中找到的距离。
但这似乎不太容易在 LaTeX 中实现。例如,当我尝试实现步骤 1 时,我发现\regex_match:nnTF
不能用它来检查正则表达式是否匹配整个表达。