Collecting environment content with support for xparse arguments












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 uq_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?










share|improve this question



























    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 uq_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?










    share|improve this question

























      19












      19








      19


      4






      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 uq_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?










      share|improve this question














      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 uq_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?







      environments latex3 xparse






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Apr 19 '14 at 19:27









      stev47stev47

      983




      983






















          1 Answer
          1






          active

          oldest

          votes


















          13














          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”.






          share|improve this answer


























          • 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 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 at 13:03













          • @sgmoye Use tlmgr to update it.

            – egreg
            Mar 8 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 at 14:04











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "85"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f172398%2fcollecting-environment-content-with-support-for-xparse-arguments%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          13














          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”.






          share|improve this answer


























          • 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 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 at 13:03













          • @sgmoye Use tlmgr to update it.

            – egreg
            Mar 8 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 at 14:04
















          13














          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”.






          share|improve this answer


























          • 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 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 at 13:03













          • @sgmoye Use tlmgr to update it.

            – egreg
            Mar 8 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 at 14:04














          13












          13








          13







          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”.






          share|improve this answer















          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”.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 8 at 13:01

























          answered Apr 19 '14 at 22:57









          egregegreg

          727k8819223231




          727k8819223231













          • 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 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 at 13:03













          • @sgmoye Use tlmgr to update it.

            – egreg
            Mar 8 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 at 14:04



















          • 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 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 at 13:03













          • @sgmoye Use tlmgr to update it.

            – egreg
            Mar 8 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 at 14:04

















          Is there an 'xparse only' approach now (3 years later)?

          – Andy
          Nov 11 '17 at 19:03





          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 at 12:49





          @Andy Now there is news! :-)

          – egreg
          Mar 8 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 at 13:03







          @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 at 13:03















          @sgmoye Use tlmgr to update it.

          – egreg
          Mar 8 at 13:54





          @sgmoye Use tlmgr to update it.

          – egreg
          Mar 8 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 at 14:04





          @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 at 14:04


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f172398%2fcollecting-environment-content-with-support-for-xparse-arguments%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

          ComboBox Display Member on multiple fields

          Is it possible to collect Nectar points via Trainline?