6

I have encountered a problem with the environ package. It returns a wrong \BODY value when the content of an environment is empty. Here is an example:

\documentclass[12pt]{article}
\usepackage{environ}
\NewEnviron{env}[1]{\BODY}
\begin{document}
\begin{env}{abc}\end{env}
\end{document}

This code generates \BODY=bc. It can also be checked that #1=a. The results are wrong not only when the content is just empty but also when it evaluates to an empty text, for example when the content is commented out.

The version of the package I work with is 2014/05/04 v0.3.

Best regards, Ryszard

  • Add some content for the body: \begin{env}{abc} Some \end{env} However, you are not using #1 at all. – user11232 Sep 15 '15 at 15:32
  • @HarishKumar, this is obviously a test, environ shouldn't do this – daleif Sep 15 '15 at 15:34
  • I've pinged the author. – daleif Sep 15 '15 at 15:35
  • If \end{env} is on a line by itself or (equivalently) if {abc} and \end{env} are separated by a space, there is no problem. – egreg Sep 15 '15 at 15:46
  • the problem is \def\collect@@body#1\end#2{% which drops braces if #1 is a brace group. You see also the wrong thing with \begin{env}{abc}{xyz}\end{env} it prints OK in that case but \show\BODY would show xyz not {xyz} – David Carlisle Sep 15 '15 at 16:08
4

The problem is

 \def\collect@@body#1\end#2{% 

which drops braces if #1 is a brace group. You see also the wrong thing with

\begin{env}{abc}{xyz}\end{env}

it prints OK in that case but \show\BODY would show xyz not {xyz}

this is part way to a fix, it adds a ! so the #1 is never empty and then removes it later. It isn't complete as it still drops braces in the {jjj} case as seen from the lof generated by the example below which produces

[macro:->abc] [macro:->]
[macro:->abc] [macro:->jjj]
[macro:->abc] [macro:->{}abc]

But it does cover the case in the question as seen by the first line above.

\documentclass[12pt]{article}
\usepackage{environ}

\NewEnviron{env}[1]{%
  \def\arg{#1}\typeout{[\meaning\arg] [\meaning\BODY]}%
  \BODY}

\makeatletter
\long\def\Collect@Body#1{%
  \@envbody{\expandafter#1\expandafter{\the\@envbody}}%
  \edef\process@envbody{\the\@envbody\noexpand\end{\@currenvir}}%
  \@envbody={}%
  \def\begin@stack{b}%
  \begingroup
  \expandafter\let\csname\@currenvir\endcsname\Collect@@Body
  \edef\process@envbody{%
    \expandafter\noexpand\csname\@currenvir\endcsname!}%
  \process@envbody
}
\long\def\Collect@@Body#1\end#2{%
  \edef\begin@stack{%
    \expandafter\Push@Begins\@gobble#1\begin\end\expandafter\@gobble\begin@stack}%
  \ifx\@empty\begin@stack
    \endgroup
    \@checkend{#2}%
    \expandafter\Addto@Envbody\expandafter{\@gobble#1}%
  \else
    \expandafter\Addto@Envbody\expandafter{\@gobble#1\end{#2}}%
  \fi
  \process@envbody}
\makeatletter

\begin{document}
\begin{env}{abc}\end{env}


\begin{env}{abc}{jjj}\end{env}


\begin{env}{abc}{}abc\end{env}


\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.