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
\newenvironment
anstelle 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
environ
erstellt 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
... \endmyenv
statt \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, \input
da es keineexplizit \end{<something>}
das \myenv
sucht. Es erreicht das Ende von , secondary.tex
bevor 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
\newenvironment
anstelle von\NewEnviron
Es sollte offensichtlich sein, warum dies funktioniert.
\newenvironment{myenv}
definiert sowohl als\myenv
auch\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
environ
Sie 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.tex
direkt inmain.tex
statt 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 derdocument
Umgebung (aufgrund eines Aufrufs\begin{document}
). Ihre Erfassung des Endes der Umgebung erfolgt also tatsächlich\end{document}
gemäß demnewenviron
Setup von . IhreUmfeld„beginnt“ mit\myenv
und 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, \myenv
dass 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.