Äquivalent für \bgroup \egroup in LaTeX3

Äquivalent für \bgroup \egroup in LaTeX3

expl3Ich versuche, eine Funktion auf den Inhalt einer Umgebung anzuwenden . In LaTeX2e kann dies durch die Verwendung von \bgroupund erreicht werden \egroup. In expl3funktioniert etwas nicht.

Ich würde erwarten, dass der folgende Code „AAA hey BBB“ ausgibt. Stattdessen wird „AAA BBB hey“ ausgegeben.

\ExplSyntaxOn

\cs_new:Npn \bar:n #1 {
    AAA #1 BBB
}

\NewDocumentEnvironment{foo}{}{
    \bar:n \bgroup
}{
    \egroup
}

\ExplSyntaxOff

\begin{document}

\begin{foo}
    hey
\end{foo}

\end{document}

Gibt es irgendwelche Ideen, warum das passiert und welche Problemumgehungen es gibt?

Bearbeiten

Dies ist mein aktueller Ansatz:

\cs_new:Npn \env_new:Nn #1#2 {
    \tl_new:N #1
    \tl_set:Nn #1 { #2 }
}

\cs_new:Npn \env_begin:N #1 {}
\cs_new:Npn \env_end:N #1 {}

\cs_new:Npn \env_capture_on: {
    \global \let \env_begin:N \group_begin:
    \global \let \env_end:N   \group_end:
}

\cs_new:Npn \env_capture_off: {
    \global\let\env_begin:N\env_original_begin:N
    \global\let\env_end:N\env_original_end:N
}

\cs_new:Npn \env_original_begin:N #1 {
    \env_capture_on:
    \tl_use:N #1
    \group_begin:
    \env_capture_off:
}

\cs_new:Npn \env_original_end:N #1 {
}

\env_capture_off:


\cs_new:Npn \foo:n #1 {
    AAA #1 BBB
}

\env_new:Nn \baf {
    \foo:n
}

\env_begin:N \baf
    hey
\env_end:N \baf

Dies funktioniert nicht, da \group_begin: und \group_end: nicht zum Erfassen von Funktionsargumenten verwendet werden können (d. h. \foo \group_begin: A \group_end:anders funktioniert als \foo { A }).

Gibt es eine Möglichkeit, eine Steuersequenz vorübergehend so zu zwingen, sich so zu verhalten, als wäre sie eine explizite Klammer?

Eine Lösung

Ich glaube, ich habe eine Lösung. Wie ich in den Kommentaren erwähnt habe, könnte man Mustervergleich mit dem Zählen der Anzahl von \begins kombinieren, um den Inhalt einer Umgebung zu erfassen. Es war ein wenig überraschend für mich, dass diesgenauwas ist los in environ, knapp unter einemVIELder Notation.

Da ich weiß, dass dies environbei meiner beabsichtigten Anwendung fehlschlug, habe ich beschlossen, es auf möglichst einfache Weise neu zu implementieren, damit ich herausfinden kann, wo mein Code fehlschlägt (jetzt habe ich eine Idee, was schiefgelaufen ist, aber darum geht es nicht). Unten finden Sie eine Implementierung in expl3. Ich habe sie nicht gründlich getestet, aber ich glaube, sie funktioniert.

Wir freuen uns über alle Kommentare und Bewertungen.

\int_new:N \env_count
\cs_new:Npn \env_new:Nn #1#2 {
    \cs_new:cpn { env_defined@ \cs_to_str:N #1 :nn } ##1##2 {
        #2
    }
}

\cs_new:Npn \env_countbegin:w #1\xbegin#2 {
    \cs_if_free:NTF #2 {
        \int_incr:N \env_count
        \env_countbegin:w
    } {
        \cs_if_eq:NNTF #2 \xend {} {
            \int_incr:N \env_count
            \env_countbegin:w
        }
    }
}

\cs_new:Npn \env_collect:w #1#2#3#4\xend#5 {
    \env_countbegin:w #4\xbegin\xend
    \int_compare:nTF { \env_count = 0 } {
        \use:c { env_defined@ \cs_to_str:N #1 :nn } { #3 #4 } { #2 }
    }{
        \int_decr:N \env_count
        \env_collect:w {#1} {#2} { #3 #4 \xend{#5} }
    }
}

\NewDocumentCommand \xbegin {mo} {
    \int_zero:N \env_count
    \env_collect:w {#1} {#2} {}
}

\NewDocumentCommand \xend {} {}

\env_new:Nn \foo {
    AAA #1 BBB
}

\xbegin{\foo}
\xbegin{\foo}
hey
\xend{\foo}
\xend{\foo}

Antwort1

Es hatniemals\bgroupwar es möglich, ein Argument mit und zu ergreifen \egroup. Die Version

\newenvironment{foo}{%
  \baz\bgroup
}{%
  \egroup
}
\newcommand{\baz}[1]{AAA #1 BBB}

würde auf genau dieselbe Weise fehlschlagen. Das Argument für \bazwäre \bgroup, also die Ausgabe von

x\begin{foo}
key
\end{foo}y

wäre

xAAA<space><space>BBB<space>key<space>y

Eines der unerwarteten Leerzeichen stammt vom Zeilenende nach \begin{foo}, das andere vom Zeilenende nach key.

Es ist möglich, zu verwenden environ, wie Christian Hupfer zeigt:

\usepackage{xparse,environ}

\ExplSyntaxOn
\NewEnviron{foo}
 {
  \jaeya_baz:V \BODY
 }

\cs_new:Nn \jaeya_baz:n { AAA~#1~BBB }
\cs_generate_variant:Nn \jaeya_baz:n { V }
\ExplSyntaxOff

und die Ausgabe des obigen Codes wäre die erwartete

xAAA<space>key<space}BBBy

Das Hinzufügen ähnlicher Funktionen wie \NewEnvironin xparsesollte auf der To-Do-Liste des LaTeX-Teams stehen.

Antwort2

Dies ist eine Möglichkeit mit environund \NewEnviron, es abzufangen \BODYund innerhalb einer Wrapper-Umgebung anzuwenden, xparsedie mit definiert ist \NewDocumentEnvironment, was bedeutet, dass alle Funktionen aus xparse-Argumentbezeichnern weiterhin verwendet werden können.

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

\ExplSyntaxOn

\cs_new:Nn \bar:n {
  AAA #1 BBB
}


\NewEnviron{foointernal}{
  \bar:n {\BODY}
}

\ExplSyntaxOff

\let\origfoointernal\foointernal
\let\origendfoointernal\endfoointernal

\NewDocumentEnvironment{foo}{}{%
  \origfoointernal%
}{%
  \origendfoointernal%
}

\begin{document}

\begin{foo}
    hey
\end{foo}


\begin{foo}
   \blindtext

   Hello World
\end{foo}

\end{document}

Bildbeschreibung hier eingeben

Antwort3

Sie wissen, dass Sie eine Umgebung verwenden möchten, \bar:num den Inhalt abzurufen. Lassen Sie es also einfach vorausscannen \endund \endam Ende des Ersatztexts erneut einfügen.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new:Npn \bar:n #1 \end {
    AAA #1 BBB \end
}

\NewDocumentEnvironment{foo}{}{\bar:n}{}

\ExplSyntaxOff

\begin{document}

\begin{foo}
    hey
\end{foo}

\end{document}

Bildbeschreibung hier eingeben

Antwort4

Ich weiß ehrlich gesagt nicht, ob es funktioniert, wenn das ganze Paket neu geschrieben ist, aber jetzt verstehe ich zumindest, was vor sich geht. Es gibt ein paar Einschränkungen: Definierte Umgebungen haben nur zwei Parameter. #1 stellt den Inhalt der Umgebung dar; #2 stellt einen Parameter in eckigen Klammern dar, der im Prinzip verwendet werden kann, um Schlüsselwerte zu enthalten und so diese Einschränkung zu überwinden.

Darüber hinaus arbeiten meine Umgebungen mit den Befehlen \xbegin{\foo} und \xend{\foo}. Die zugrunde liegende Struktur dieser Befehle unterscheidet sich von der der LaTeX-Umgebungen, daher habe ich mich entschieden, andere Schlüsselwörter zu verwenden. Ich vermute jedoch, dass der Ansatz erweitert werden könnte, um auf LaTeX-Umgebungen anwendbar zu sein.

Jede Bewertung oder jeder Kommentar zum Code ist herzlich willkommen und wird geschätzt!

\documentclass[10pt]{article}
\usepackage{expl3}

\ExplSyntaxOn

\int_new:N \env_count
\cs_new:Npn \env_new:Nn #1#2 {
    \cs_new:cpn { env_defined@ \cs_to_str:N #1 :nn } ##1##2 {
        #2
    }
}

\cs_new:Npn \env_countbegin:w #1\xbegin#2 {
    \cs_if_free:NTF #2 {
        \int_incr:N \env_count
        \env_countbegin:w
    } {
        \cs_if_eq:NNTF #2 \xend {} {
            \int_incr:N \env_count
            \env_countbegin:w
        }
    }
}

\cs_new:Npn \env_collect:w #1#2#3#4\xend#5 {
    \env_countbegin:w #4\xbegin\xend
    \int_compare:nTF { \env_count = 0 } {
        \use:c { env_defined@ \cs_to_str:N #1 :nn } { #3 #4 } { #2 }
    }{
        \int_decr:N \env_count
        \env_collect:w {#1} {#2} { #3 #4 \xend{#5} }
    }
}

\NewDocumentCommand \xbegin {mo} {
    \int_zero:N \env_count
    \env_collect:w {#1} {#2} {}
}

\NewDocumentCommand \xend {} {}

\env_new:Nn \foo {
    AAA #1 BBB
}

\ExplSyntaxOff

\begin{document}    

\xbegin{\foo}
\xbegin{\foo}
hey
\xend{\foo}
\xend{\foo}

\end{document}

verwandte Informationen