3

This problem is distilled from an environment that needs to use its body either wrapped in a minipage or not. Furthermore, this environment is to be automatically wrapped around all uses of another environment (e.g. flushleft in the following).

Explicitly wrapping myEnv around another environment works:

\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}

However, if I try to use environment hooks like this:

\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}

then I get this error:

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

l.17 \end {flushleft}

To reiterate, I'd like to have all uses of the flushleft environment to be modified as if they were explicitly wrapped in myEnv. What's wrong with the above? Maybe the myEnv hooks are invoked for more times than I expect them to?

melisgl
  • 183

1 Answers1

2

The problem here is that the +b argument is not correctly recognized by myEnv when flushleft is redefined with the hooks. I think what happens is that flushleft can't pass the body as an argument to myEnv, because it simply does not take it as an argument in the first place. I see two solutions here.

  1. Remove the body from myEnv's definition if you don't really need it.
\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. Redefine flushleft so that it understands the body as an argument. In that case you don't need the hooks, because you already redefine flushleft so you can just add myEnv in the new definition.
\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}

Vincent
  • 20,157
  • I don't understand how I'm "trying to use the +b argument, which is the body of the environment, inside of the flushleft environment". I thought that the point of the BeforeBegin and AfterEnd hooks was that they are run outside the flushleft? – melisgl Jan 22 '23 at 15:01
  • @melisgl Yes you're right, maybe it was not the best choice of words. What I meant was that with the hooks, the body is not correctly recognized by myEnv. I don't know much about how the hooks and the +b argument work under the hood, but a similar example without the +b argument works with the hooks so I figured this was causing the problem. Anyway, I changed the wording. – Vincent Jan 22 '23 at 15:22
  • Thank you. Something is not quite right though because if I do replace flushleft with equation I get this error: Extra }, or forgotten $. \environment myEnv code #1#2->B {#2} l.17 \end{equation}. – melisgl Jan 23 '23 at 11:31
  • It may be this: https://tex.stackexchange.com/questions/162885/errors-when-trying-to-define-a-custom-align-environment. – melisgl Jan 23 '23 at 11:43