为什么适用于 align 环境的补丁不适用于 flalign 环境?

为什么适用于 align 环境的补丁不适用于 flalign 环境?

我试图当多行公式中间出现分页符时添加边注,使用 egreg 提供的 nice 方法它的答案我的问题:禁用多线环境的 fleqn 选项吗?

align由于分页符可能发生在和环境的中间flalign,我试图按照下面最小化示例的精神对它们进行修补(它具有\\在这些环境中遇到的每个分页符之前和之后分别添加“foo”和“bar”的良好功能)。

问题是,此修补程序对于 运行良好,align但对于 却失败了flalign:一旦后者在文档主体中取消注释,编译就会失败并出现错误:

! Missing } inserted.
<inserted text> 
                }
l.78 \end{flalign}

即使发生这种情况flalign没有修补也会发生这种情况,即如果:

\clist_set:Nn \l_tmpa_clist {align,flalign}

替换为:

\clist_set:Nn \l_tmpa_clist {align}

你知道发生了什么吗?以及如何使这个补丁flalign也能正常工作?(可以问同样的问题alignat。)

\documentclass[fleqn]{report}
\usepackage{amsmath}
\usepackage{xparse,environ}

\ExplSyntaxOn
\makeatletter

\clist_set:Nn \l_tmpa_clist {align,flalign}
\clist_map_inline:Nn \l_tmpa_clist {
  % save the original environments
  \cs_set_eq:cc {db_#1_start:} {#1}
  \cs_set_eq:cc {db_#1_end:} {end#1}
  \cs_set_eq:cc {db_#1_star_start:} {#1*}
  \NewDocumentEnvironment{amsmath#1}{}
  {\cs:w db_#1_start:\cs_end:}
  {\cs:w db_#1_end:\cs_end:}
  \NewDocumentEnvironment{amsmath#1*}{}
  {\cs:w db_#1_star_start:\cs_end:}
  {\cs:w db_#1_end:\cs_end:}
  \RenewEnviron{#1}
  {
    \cs:w db_patch:nV\cs_end: {#1} \BODY
  }
  \RenewEnviron{#1*}
  {
    \cs:w db_patch:nV\cs_end: {#1*} \BODY
  }
}
% redefine them
\seq_new:N \l_db_patch_seq
\cs_new_protected:Nn \db_patch:nn
 {
  \seq_set_split:Nnn \l_db_patch_seq { \\ } { #2 }
  \begin{amsmath#1}
    \seq_use:Nn \l_db_patch_seq { \db@patch } \hfill
  \end{amsmath#1}
 }
\cs_generate_variant:Nn \db_patch:nn { nV }

\NewDocumentCommand{\db@patch}{so}{%
  \quad\text{foo}
  \IfValueTF{#2}{%
    \IfBooleanTF{#1}{\\*[#2]}{\\[#2]}%
  }{%
    \IfBooleanTF{#1}{\\*}{\\}
  }%
  \text{bar}\quad
}

\makeatother
\ExplSyntaxOff

\begin{document}
\begin{align}
  1 + 1 & = 2 \\
  2 + 1 & = 3 \\
  3 + 1 & = 4 \\
  4 + 1 & = 5 \\
  5 + 1 & = 6 \\
  6 + 1 & = 7 \\
  7 + 1 & = 8 \\
  8 + 1 & = 9 \\
  9 + 1 & = 10
\end{align}

% \begin{flalign}
%   1 + 1 & = 2 \\
%   2 + 1 & = 3 \\
%   3 + 1 & = 4 \\
%   4 + 1 & = 5 \\
%   5 + 1 & = 6 \\
%   6 + 1 & = 7 \\
%   7 + 1 & = 8 \\
%   8 + 1 & = 9 \\
%   9 + 1 & = 10
% \end{flalign}
\end{document}

答案1

问题是,当您重新定义时align,也会重新定义命令\endalign,该命令(如果您检查 amsmath 的源代码)将用作所有对齐环境的结束。

解决方案是以不同的方式进行修补,如下所示:

\usepackage{xparse,etoolbox}

%Beggining Same as in the question
\ExplSyntaxOn
\makeatletter
\clist_set:Nn \l_tmpa_clist {flalign,align}
\clist_map_inline:Nn \l_tmpa_clist {
%We use collect@body, which is what's used internally by NewEnviron
%It takes in the environment body, and then calls the next cs
  \AtBeginEnvironment{#1}{\collect@body\db_patch:n}
}
% redefine them
\seq_new:N
\l_db_patch_seq
\cs_new_protected:Nn
\db_patch:n
{
  \seq_set_split:Nnn
  \l_db_patch_seq {
  \\ } { #1 }
    \seq_use:Nn
    \l_db_patch_seq
    { \db@patch
    } 
}
%The remainder as in the question

在这里,我们仅修补环境的开始部分,使用来自的老式工具etoolbox,避免重新定义\endalign

还值得注意的是,您不需要该environ包,因为 amsmath 还定义了\collect@body我们在环境中用来读取的命令。

相关内容