„Ausuferndes Argument?“-Fehler mit \NewEnviron

„Ausuferndes Argument?“-Fehler mit \NewEnviron

Ich habe zwei Dateien. Im Grunde lädt die Hauptdatei nur das Umgebungspaket und gibt die sekundäre Datei ein. Die sekundäre Datei erstellt eine Umgebung, die im Grunde nichts tut, und erstellt eine Instanz dieser Umgebung:

main.tex:

\documentclass{scrartcl}
\usepackage{environ}
\begin{document}
  \input{secondary.tex}
\end{document}

sekundär.tex:

\NewEnviron{myenv}{\BODY}
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup

Ich erhalte folgende Fehlermeldung:

Runaway argument?
Hello \endmyenv \endgroup \par
! File ended while scanning use of \document.
<inserted text>
                \par
l.5 \input{secondary.tex}

Das Beispiel funktioniert wie erwartet, wenn ich eine (!) der folgenden Änderungen vornehme:

  • Verwenden Sie \newenvironmentanstelle von\NewEnviron
  • Verwenden Sie \begin{myenv}...\end{myenv}anstelle von\begingroup\myenv...\endmyenv\endgroup
  • Platzieren Sie den Inhalt von second.tex direkt in main.tex, anstatt second.tex einzugeben

Warum funktioniert das nicht?

Antwort1

environerstellt eine Umgebung, die TeX-Parametertext in Definitionen verwendet, um den Umgebungsinhalt zu erfassen. Diese Definition im Parametertextstil ermöglicht es dem Paket, den Umgebungsinhalt zu erfassen, erfordert aber auch eine sehr strikte Verwendung der Makros/Definitionen... etwas, an das Sie sich nicht halten, wenn Sie eine Umgebung im Befehlsstil verwenden ( \myenv... \endmyenvstatt \begin{myenv}... \end{myenv}).

Im Großen und Ganzen \NewEnviron{myenv}erstellt es ein Makro \myenv, das den Start der Umgebung bezeichnet, und dieses Makro ist auf der Suche nachgenau \end{myenv}... nichts anderes.

Das Beispiel schlägt fehl, \inputda es keineexplizit \end{<something>}das \myenvsucht. Es erreicht das Ende von , secondary.texbevor es überhaupt eine Ähnlichkeit mit findet \end. Es sucht tatsächlich nach \end{document}(siehe unten).

Sehen wir uns die drei von Ihnen genannten Fälle an, in denen das Problem behoben wurde, und finden wir heraus, warum das so ist:

  • Verwenden Sie \newenvironmentanstelle von\NewEnviron

    Es sollte offensichtlich sein, warum dies funktioniert. \newenvironment{myenv}definiert sowohl als \myenvauch \endmyenv, daher sollte die Verwendung der Befehlsdefinition der Umgebung problemlos funktionieren;

  • Verwenden Sie \begin{myenv}...\end{myenv}anstelle von\begingroup\myenv...\endmyenv\endgroup

    Dies ist genau das, was environSie verwenden sollten, wenn Sie eine Umgebung mit definieren \NewEnviron. Dies funktioniert also sofort, da Sieausdrücklichverwendet die Umgebungsbeendigung \end{myenv};

  • Platzieren Sie den Inhalt von secondary.texdirekt in main.texstatt einzugebensecondary.tex

    Da Sie die Befehlsform einer Umgebung verwenden, \@currenvirändert sich die „aktuelle Umgebung“ (in LaTeX als bekannt) nie wirklich. Das heißt, sie bleibt innerhalb der documentUmgebung (aufgrund eines Aufrufs \begin{document}). Ihre Erfassung des Endes der Umgebung erfolgt also tatsächlich \end{document}gemäß dem newenvironSetup von . IhreUmfeld„beginnt“ mit \myenvund endet mit \end{document}. Merkwürdig, aber so funktioniert es, wenn Sie nicht den erwarteten Umgebungsbereich verwenden \begin{...}\end{...}.

Damit es im Kontext von ordnungsgemäß funktioniert newenviron, verwenden Sie den Bereich \begin{myenv}\end{myenv}. Dieser Bereich bietet die erforderliche Gruppierung, die Sie durch \begingroup… implementieren \endgroup.

Alternativ können Sie definieren, \myenvdass Daten erfasst werden, bis sie Folgendes erreichen \endmyenv:

\documentclass{scrartcl}
\usepackage{filecontents}
\begin{filecontents*}{secondary.tex}
\long\def\myenv #1\endmyenv{#1}% Fake myenv environment that captures its body
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup
\end{filecontents*}
\begin{document}
\input{secondary.tex}
\end{document}

Antwort2

Es tutnichtfunktioniert, wenn Sie den Inhalt in die Hauptdatei einfügen. Es tritt nur kein Fehler auf. Versuchen Sie Folgendes:

\documentclass{scrartcl}
\usepackage{environ}
\begin{document}
\NewEnviron{myenv}{BEGIN\BODY END}
\begingroup
  \myenv
    Hello
  \endmyenv
\endgroup

World

\end{document}

Environ muss \end{myenv} finden, um die Analyse zu stoppen.

verwandte Informationen