Sie sind hier

KOMA-Variable "verschwindet"

Guten Tag,

ich kämpfe hier seit einer Weile mit einem Problem, das ich mir einfach nicht erklären kann. Es geht darum, dass eine mit newkomavar deklarierte Variable nach dem Aufruf von document nicht mehr erkannt wird.

Im Koma-Script-Handbuch konnte ich zu dem Problem leider nichts finden, auch nicht in anderen Orten im Web.

Zunächst mal ein Minimalbeispiel:

\documentclass{scrlttr2}
 
\newenvironment{test}{
  \newkomavar{myVar}
  \ifkomavarempty{myVar}{\typeout{========= empty 1}}{\typeout{========= not empty 1}}
  \document
  \ifkomavarempty{myVar}{\typeout{========= empty 2}}{\typeout{========= not empty 2}}
  \begin{letter}{}
}{
  \end{letter}
  \enddocument
}
 
\begin{test}
XYZ.
\end{test}

Ich hoffe, es ist ok, dass ich ein paar Debug-Ausgaben reingebaut habe.

Das compiliere ich mit pdflatex unter MikTeX 2.9 mit KOMA-Script v3.08.
Die erwartete Ausgabe (unter Auslassung der ganzen LaTeX-Ausgaben, die immer beim Compilieren erscheinen) meinerseits wäre:

========= empty 1
========= empty 2

Tatsächlich aber erscheint nur die erste jener zwei Zeilen:

========= empty 1

An der Stelle, an der eigentlich die zweite Ausgabe verarbeitet werden sollte, kommt es dann zu folgender Fehlermeldung (wie ihr seht, schon mit angeforderter Zusatzinformation via H):

! Class scrlttr2 Error: KOMA-Script variable not defined.

See the scrlttr2 class documentation for explanation.
Type H for immediate help.
...

l.14 \begin{test}

? H
You've tried to use the not defined KOMA-Script variable `myVar'.
You have to define the variable using \newkomavar before
you do this.
? X

Offenbar hört die KOMA-Variable myVar also beim Aufruf von \document auf, zu existieren. Ich würde gern wissen, warum.

Und jetzt noch eine kurze Erklärung, wie ich zu dieser Situation komme/warum ich das so mache:

Hier existiert eine recht umfangreiche Briefvorlage in unserem Corporate Design ("Vorlage" = ein Satz von Dateien, den man sich bei jeder Verwendung in ein neues Verzeichnis kopieren und dann anpassen kann), die auf KOMA-Script basiert. Diese möchte ich in eine Dokumentklasse überführen. Um den Aufwand gering und die Wiederverwendung hoch zu halten, möchte ich am bisherigen Code also möglichst wenig ändern.

Mein Wunsch an die entstehende Klasse ist es, dass man möglichst wenig falsch machen kann, wenn man versucht, einen Brief auf Grundlage der Vorlage zu erstellen. Dazu gehört natürlich auch die Vermeidung von Redundanzen. Für jedes Dokument zwei Environments zu definieren, die immer auf dieselbe Weise verschachtelt werden, ist mit Sicherheit redundant. Daher würde ich

\begin{document}
\begin{letter}{...}
...
\end{letter}
\end{document}

gerne durch so etwas wie

\begin{myletter}
...
\end{myletter}

ersetzen. Also definiere ich sinngemäß:

\newenvironment{myletter}{
\document
\begin{letter}{...}
}{
\end{letter}
\enddocument
}

Unter Verwendung von \document und \enddocument, da man \begin{document} und \end{document} meiner Erfahrung nach nicht in einem \newenvironment benutzen kann.

Vielen Dank schon mal fürs Lesen; ich hoffe jemand hat einen Tipp :-)
Grüße

Bild von Markus Kohm

Das kann so nicht funktionieren. document ist keine normale Umgebung. Wenn man dann auch noch \document und \enddocument an Stelle von \begin{document} und \end{document} verwendet, dann bringt man LaTeX völlig durcheinander. U. a. wird in \document die aktuelle Gruppe beendet, damit man sich eben innerhalb eines Dokuments nicht innerhalb einer Gruppen-Ebene befindet. Das führt in Deinem Fall aber dazu, dass die Umgebung test (ohne Prüfung) beendet wird. Damit ist dann natürlich auch die zu dieser Gruppe lokale Definition von myVar verloren.

Eigentlich würde ich dringend davon abraten, diese vermeintliche Redundanz zu vermeiden und wirklich zur Abgrenzung des Dokuments immer explizit \begin{document}...\end{document} zu schreiben. Weit einfacher wäre beispielsweise eine Variable für den Empfänger zu definieren und dann etwas wie (ungetestet)

\AtBeginDocument{\begin{letter}{\usekomavar{letteraddresse}}
\AtEndDocument{\end{letter}}

zu verwenden, wenn man unbedingt eine Umgebung einsparen will.

Da man aber auch mehr als einen Brief in einem Dokument haben darf (und das bei Serienbriefen durchaus sinnvoll ist) würde ich auch diese Einsparung nicht vornehmen, sondern explizit beide Umgebungen dem Anwender abverlangen. Das \opening wird ihm ja normalerweise auch noch abverlangt.

Natürlich hat mich dann noch gereizt, wie wohl das Problem trotzdem so zu lösen ist, wie Du Dir das vorstellst. Mein Hack dazu sieht so aus:

% Dieser Hack sei nur angegeben, weil das Problem meinen sportlichen Ehrgeiz
% heraiusgefordert hat. Bei Nebenwirkungen lehne ich jede Verantwortung ab!
\documentclass{scrlttr2}
 
\makeatletter
\newcommand*{\doenddocument}{\end{document}}
\newenvironment{test}{
  \endgroup
  \newkomavar{myVar}
  \ifkomavarempty{myVar}{\typeout{========= empty 1}}{\typeout{========= not empty 1}}
  \begin{document}
  \begingroup
  \def\@currenvir{test}%
  \edef\@currenvline{\on@line}%
  \ifkomavarempty{myVar}{\typeout{========= empty 2}}{\typeout{========= not empty 2}}
  \letter{}
}{
  \endletter
  \aftergroup\doenddocument
}
\makeatother
 
\begin{test}
XYZ.
\end{test}

PS: Wer eine eigene Klasse schreibt, ist entweder kein Anfänger oder mutig genug, um erst einmal als Anwender betrachtet zu werden.

Hallo,
gleich mal vielen Dank für die Antwort. Das sieht ja schon mal sehr vielversprechend aus. Ich werde die Sache mit den mehreren Briefen in einem Dokument mal überdenken.

Bin jetzt erst mal verreist und melde mich eventuell nach meiner Rückkehr nochmal, wenn ich dann noch Fragen dazu habe.

Grüße

Comments for "KOMA-Variable "verschwindet"" abonnieren