1

The packages environ and newenviron both provide an alternative to the standard environment macros included with LaTeX. The main difference is that they make it possible to refer to the environment body using a macro, but another difference is that macro expansion is affected as can be seen by (un)commenting the relevant lines in the following document:

\documentclass{article}
\usepackage{environ}
\usepackage{newenviron}

\def\speakify#1: #2\par{{\bfseries#1}: {\itshape``#2\unskip''}\par}
\newenvironment{interview}{\everypar{\speakify}}{\par}
%\NewEnviron{interview}{\everypar{\speakify}\BODY\par}
%\newenviron{interview}{}{\everypar{\speakify}\envbody\par}

\begin{document}
\begin{interview}
I: I have a question for you that I would really like to know the answer to. Could you please explain it in your own words while the moon is still high in the sky? That would be lovely thank you very much!

L: Of course I will answer gladly all questions you might have no matter how silly I feel they may be provided payment is made in full before commencement of the answering phase.
\end{interview}
\end{document}

What exactly is the change in macro expansion that occurs?

16
  • 4
    The main point of environ is that you can access the content of an environment with the command \BODY. Standard environments do not have such a facility. – Arash Esbati Jul 8 '15 at 12:19
  • 3
    A feature of NewDocumentEnvironment from xparse package is, that the arguments can be accessed in the end code section as well, which is not possible for the standard \newenvironment – user31729 Jul 8 '15 at 18:08
  • I haven't heard of newenviron previously but I am a big fan of \NewDocumentEnvironment from xparse and \NewEnviron from environ. The former gives much more control over the arguments to the environment and the latter makes it possible to work with the body of the environment. – user30471 Jul 9 '15 at 14:13
  • The site really works better if you ask one question per... well, per question. Aside from the fact that you are asking multiple questions, even some of the individual questions are simply huge. Please edit your question to ask a single, specific question which people can answer in this format. You can ask other questions and link to this one if that would be helpful. – cfr Jul 10 '15 at 1:31
  • 2
    There is no change in macro expansion; the environ or newenviron codes just grab the environment's contents. You don't need them in this application. – egreg Jul 10 '15 at 9:56
1

After the \everypar processing of the second paragraph, with the document as posted you have essentially

\speakify L: Of course I will answer gladly all questions you might have no matter how
             silly I feel they may be provided payment is made in full before commencement
             of the answering phase.\end{interview} \end{document}

Now \speakify sees L as #1 but runs off the end of the document looking for \par to delimit #2. So you get:

! File ended while scanning use of \speakify.
<inserted text> 
                \par 
<*>

If you edit the document so there is a paragraph break after the environment so the file ends

phase.
\end{interview}

\end{document}

Then \speakify would include \end{interview} in #2 so the above error is avoided but the grouping logic is messed up and you get:

! Missing } inserted.
<inserted text> 
                }
l.16 

? 

If you edit the document to put a paragraph break before the end of the envitonment, so the file ends:

 phase.

\end{interview}
\end{document}

Then the document works without error.


The expansion logic is different in the forms using \BODY as you have added an explicit \par so \BODY is expanded and when the final paragraph is processed, \par is already in the input stream so the processing is equivalent to

\speakify L: Of course I will answer gladly all questions you might have no matter how
             silly I feel they may be provided payment is made in full before commencement
             of the answering phase.\par

and \speakify sees its argument delimiter as intended.

2
  • So are you saying that the standard environment only adds the closing argument (\par in my case) when \end{interview} is expanded, while the non-standard environments first determine the entire extent of the environment and so (can) put in the closing par straight away? – hkBst Sep 8 '19 at 17:35
  • @hkBst yes, in your neweviron forms you have \BODY\par so in fact the closing \par is first into the input stream and the actual paragraph is added at the next step, after \BODY is expanded. – David Carlisle Sep 8 '19 at 17:38

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.