使用钩子将环境包装在另一个环境中

使用钩子将环境包装在另一个环境中

这个问题源于一个环境,该环境需要使用其主体,无论是否包装在迷你页面中。此外,此环境将自动包装在另一个环境的所有使用中(例如flushleft在下文中)。

明确地myEnv环绕另一个环境有效:

\documentclass{article}

\usepackage{xparse}
\usepackage{amsmath}

\NewDocumentEnvironment{myEnv}{O{}+b}
  {B {#2}}
  {{#2} E}

\begin{document}

\begin{myEnv}
\begin{flushleft}
  flushleft
\end{flushleft}
\end{myEnv}

\end{document}

但是,如果我尝试使用这样的环境钩子:

\documentclass{article}

\usepackage{xparse}
\usepackage{amsmath}

\NewDocumentEnvironment{myEnv}{O{}+b}
  {B {#2}}
  {{#2} E}

\BeforeBeginEnvironment{flushleft}{\begin{myEnv}}
\AfterEndEnvironment{flushleft}{\end{myEnv}}

\begin{document}

\begin{flushleft}
  body
\end{flushleft}

\end{document}

然后我收到这个错误:

Extra }, or forgotten \endgroup.
\environment myEnv code #1#2->B {#2}
                                    
l.17 \end
         {flushleft}

重申一下,我希望flushleft修改环境的所有用途,就像它们被明确包装在 中一样myEnv。 上面有什么问题? 也许myEnv钩子的调用次数比我预期的要多?

答案1

这里的问题是,当使用钩子重新定义时,参数无法正确识别。我认为发生的事情是无法+b将主体作为参数传递给,因为它根本不将其作为参数。我在这里看到两个解决方案。myEnvflushleftflushleftmyEnv

  1. myEnv如果确实不需要,请从定义中删除主体。
\documentclass{article}
\usepackage{amsmath}

\NewDocumentEnvironment{myEnv}{O{}}
  {B}
  {E}
\BeforeBeginEnvironment{flushleft}{\begin{myEnv}}
\AfterEndEnvironment{flushleft}{\end{myEnv}}

\begin{document}

\begin{flushleft}
  body
\end{flushleft}

\end{document}
  1. 重新定义flushleft,以便它将主体理解为参数。在这种情况下,您不需要钩子,因为您已经重新定义,因此您只需添加新定义flushleft即可。myEnv
\documentclass{article}
\usepackage{amsmath}

\NewDocumentEnvironment{myEnv}{O{} +b}
  {B {#2}}
  {{#2} E}
\let\oldflushleft\flushleft
\let\endoldflushleft\endflushleft
\RenewDocumentEnvironment{flushleft}{+b}
    {\begin{myEnv}\oldflushleft #1}
    {\endoldflushleft\end{myEnv}}

\begin{document}

\begin{flushleft}
  body
\end{flushleft}

\end{document}

相关内容