19

I'm trying to create an environment which uses xparse style arguments but I have to be able to use the whole environment content in the environment definition, e.g. as an argument.

Ideally I'd like to write something like

\DeclareCollectedDocumentEnvironment { env } { o } {
    Make use of optional Argument #1 and Content \CollectedBody.
}
\begin{env}[optional]
    content
\end{env}

Is there a reason, why xparse doesn't provide something like this?

Using \NewEnviron from the environ package does not work for me, because I'm reliant on some of the argument-parsing features xparse provides.

Currently I've got this working:

\documentclass{article}
\usepackage{xparse}
\usepackage{environ}

\ExplSyntaxOn

\DeclareDocumentCommand { \myenv } { o u\q_nil } {
    opt:~#1 \\
    content:~#2
}
\cs_set:Npn \myenv_collect:n #1 {
    \myenv #1 \q_nil
}
\makeatletter
\DeclareDocumentEnvironment { env } { } {
    \Collect@Body \myenv_collect:n
} { }
\makeatother

\ExplSyntaxOff

\begin{document}

\begin{env}[99]
    With optional argument
\end{env}

\begin{env}
    Without optional argument
\end{env}

\end{document}

This however has some flaws:

  • Multiple paragraphs inside the environment cause an infinite loop
  • Nesting does not work as expected

I've also tried to declare the arguments for \DeclareDocumentEnvironment and somehow pass them onto \myenv_collect:n, but the behaviour of \Collect@Body made it difficult.

Is there a solution to my problem, preferably a latex3 one?

14

An interface similar to \NewEnviron would be a welcome addition to xparse; but you can use it indirectly:

\documentclass{article}
\usepackage{xparse,environ}

\NewDocumentEnvironment{env}{ O{default} }
 {\Environenv{#1}}
 {\endEnvironenv}

\NewEnviron{Environenv}[1]
 {Do something with #1 and \BODY}

\begin{document}

\begin{env}
What is this?

Another paragraph.
\end{env}

\begin{env}[foo]
What is this?

Another paragraph.
\end{env}

\end{document}

If you call the command form of Environenv, it will know what environment it's been called in. That's the same trick for defining environments containing align in amsmath.

enter image description here

Important news (March 2019)

With the release 2019-03-05 release of xparse, the functionality of environ has been implemented, with some adaptations. See below for a description.

Due to freezing of TeX Live, it is currently only available in TL2019/pretest or MiKTeX.

The above code can be reduced to

\documentclass{article}
\usepackage{xparse}

\NewDocumentEnvironment{env}{O{default}+b}
 {Do something with #1 and #2}
 {}

\begin{document}

\begin{env}
What is this?

Another paragraph.
\end{env}

\begin{env}[foo]
What is this?

Another paragraph.
\end{env}

\end{document}

Some notes: the argument specifier b denotes the body of the environment, which will be then collected as a macro argument, just like environ did. There is no \BODY to use: in this case b is the second argument, so one refers to it as #2.

The “end part” is to be specified, although it will be usually empty.

If paragraphs are expected in the body, the argument should be specified as +b, like all other “long arguments”.

  • Is there an 'xparse only' approach now (3 years later)? – Andy Nov 11 '17 at 19:03
  • @Andy Now there is news! :-) – egreg Mar 8 '19 at 12:49
  • @egreg I saw the announcement of this on comp.text.tex, but the announcement has since disappeared. I'm using the 2019 TeXLive pretest, though I don't believe the new version has been installed. – sgmoye Mar 8 '19 at 13:03
  • @sgmoye Use tlmgr to update it. – egreg Mar 8 '19 at 13:54
  • @egreg Well, I have been doing just that (for 2019), successfully, though tlmgr.log makes no mention of xparse. Just ran sudo tlmgr update xparse and got this back: tlmgr: xparse mentioned, but neither new nor forcibly removed. This is certainly not critical, just curious. The fact that the announcement is now missing on CTT suggests that it was withdrawn? – sgmoye Mar 8 '19 at 14:04

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.