% ======================================================================
% scrlfile.tex
% Copyright (c) Markus Kohm, 2001-2011
%
% This file is part of the LaTeX2e KOMA-Script bundle.
%
% This work may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, version 1.3c of the license.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX 
% version 2005/12/01 or later and of this work.
%
% This work has the LPPL maintenance status "author-maintained".
%
% The Current Maintainer and author of this work is Markus Kohm.
%
% This work consists of all files listed in manifest.txt.
% ----------------------------------------------------------------------
% scrlfile.tex
% Copyright (c) Markus Kohm, 2001-2011
%
% Dieses Werk darf nach den Bedingungen der LaTeX Project Public Lizenz,
% Version 1.3c, verteilt und/oder veraendert werden.
% Die neuste Version dieser Lizenz ist
%   http://www.latex-project.org/lppl.txt
% und Version 1.3c ist Teil aller Verteilungen von LaTeX
% Version 2005/12/01 oder spaeter und dieses Werks.
%
% Dieses Werk hat den LPPL-Verwaltungs-Status "author-maintained"
% (allein durch den Autor verwaltet).
%
% Der Aktuelle Verwalter und Autor dieses Werkes ist Markus Kohm.
% 
% Dieses Werk besteht aus den in manifest.txt aufgefuehrten Dateien.
% ======================================================================
%
% Chapter about scrlfile of the KOMA-Script guide
% Maintained by Markus Kohm
%
% ----------------------------------------------------------------------------
%
% Kapitel über scrlfile in der KOMA-Script-Anleitung
% Verwaltet von Markus Kohm
%
% ============================================================================

\ProvidesFile{scrlfile.tex}[2011/03/09 KOMA-Script guide (chapter: scrlfile)]

\chapter{Paketabhängigkeiten mit \Package{scrlfile} 
  beherrschen}
\labelbase{scrlfile}

\BeginIndex{Package}{scrlfile}

Die Einführung von \LaTeXe{} brachte 1994 eine Menge Neuerungen im Umgang mit
\LaTeX-Erweiterungen. So stehen dem Paketautor heute eine ganze Reihe von
Befehlen zur Verfügung, um festzustellen, ob ein anderes Paket oder eine
bestimmte Klasse verwendet wird und ob dabei bestimmte Optionen zur Anwendung
kommen. Der Paketautor kann selbst andere Pakete laden oder diesen Optionen
mit auf den Weg geben für den Fall, dass sie später noch geladen werden. Es
bestand daher die Hoffnung, dass es künftig unerheblich wäre, in welcher
Reihenfolge Pakete geladen werden. Diese Hoffnung hat sich leider nicht
erfüllt.

\section{Die Sache mit den Paketabhängigkeiten}
\label{sec:scrlfile.dependency}
%\begin{Explain}
  Immer häufiger definieren unterschiedliche Pakete den gleichen
  Befehl neu oder um. Dabei ist es dann sehr entscheidend, in welcher
  Reihenfolge die Pakete geladen werden. Manchmal ist das für den
  Anwender kaum zu überschauen. In manchen Fällen ist es auch
  notwendig, einfach nur in irgendeiner Form auf das Laden eines
  anderen Paketes zu reagieren. Auch das ist nicht immer ganz einfach.

  Nehmen wir als einfaches Beispiel das Laden des
  \Package{longtable}-Paketes bei Verwendung von \KOMAScript{}. Das
  \Package{longtable}-Paket definiert seine eigene Form von
  Tabellenüberschriften. Diese passen perfekt zu den
  Tabellenüberschriften der Standardklassen. Sie passen aber überhaupt
  nicht zu den Voreinstellungen für die Tabellenüberschriften von
  \KOMAScript{} und reagieren auch nicht auf die entsprechenden
  Möglichkeiten der Konfiguration. Um dieses Problem zu lösen, müssen
  die Befehle von \Package{longtable}, die für die
  Tabellenüberschriften zuständig sind, von \KOMAScript{} umdefiniert
  werden. Allerdings sind die \KOMAScript{}-Klassen bereits
  abgearbeitet, wenn das Paket geladen wird.

  Bisher bestand die einzige Möglichkeit, dieses Problem zu lösen
  darin, die Umdefinierung mit Hilfe von \Macro{AtBeginDocument} auf
  einen späteren Zeitpunkt zu verschieben. Will der Anwender die
  entsprechende Anweisung jedoch selbst umdefinieren, so sollte er
  dies eigentlich ebenfalls in der Präambel tun. Das kann er jedoch
  nicht, weil \KOMAScript{} ihm dabei in die Quere kommt. Er müsste
  die Umdefinierung also ebenfalls mit Hilfe von
  \Macro{AtBeginDocument} durchführen.

  Aber eigentlich müsste \KOMAScript{} die Abarbeitung gar nicht auf
  den Zeitpunkt von \Macro{begin}\PParameter{document} verschieben. Es
  würde genügen, wenn sie bis unmittelbar nach dem Laden von
  \Package{longtable} verzögert werden könnte. Leider fehlen
  entsprechende Anweisungen im \LaTeX-Kern. Das Paket
  \Package{scrlfile} bringt hier Abhilfe.

  Ebenso wäre es denkbar, dass man vor dem Laden eines bestimmten
  Paketes gerne die Bedeutung eines Makros in einem Hilfsmakro retten
  und nach dem Laden des Paketes wieder restaurieren will. Auch das
  geht mit \Package{scrlfile}.

  Die Anwendung von \Package{scrlfile} ist nicht auf die Abhängigkeit
  von Paketen beschränkt. Auch Abhängigkeiten von anderen Dateien
  können berücksichtigt werden. So kann beispielsweise dafür gesorgt
  werden, dass das nicht unkritische Laden einer Datei wie
  \File{french.ldf} automatisch zu einer Warnung führt.

  Obwohl das Paket in erster Linie für andere Paketautoren interessant
  sein dürfte, gibt es durchaus auch Anwendungen für normale
  \LaTeX-Benutzer. Deshalb sind in diesem Kapitel auch für beide
  Gruppen Beispiele aufgeführt.
%\end{Explain}


\section{Aktionen vor und nach dem Laden}
\label{sec:scrlfile.macros}

Mit \Package{scrlfile} können vor und nach dem Laden von Dateien Aktionen
ausgelöst werden. Bei den dazu verwendeten Befehlen wird zwischen allgemeinen
Dateien, Klassen und Paketen unterschieden.


\BeginIndex{Cmd}{BeforeFile}%
\BeginIndex{Cmd}{AfterFile}%
\begin{Declaration}
  \Macro{BeforeFile}\Parameter{Datei}\Parameter{Anweisungen}\\
  \Macro{AfterFile}\Parameter{Datei}\Parameter{Anweisungen}
\end{Declaration}%
Mit Hilfe von \Macro{BeforeFile} kann dafür gesorgt werden, dass
\PName{Anweisungen} erst vor dem nächsten Laden einer bestimmten
\PName{Datei} ausgeführt werden. Vergleichbar arbeitet
\Macro{AfterFile}. Nur werden die \PName{Anweisungen} hier erst nach
dem Laden der \PName{Datei} ausgeführt. Wird die Datei nie geladen, so
werden die \PName{Anweisungen} auch nie ausgeführt. Beim Dateinamen sind
etwaige Endungen wie bei \Macro{input} anzugeben.

%\begin{Explain}
  Um die Funktionalität bereitstellen zu können, bedient sich
  \Package{scrlfile} der bekannten \LaTeX-Anweisung
  \Macro{InputIfFileExists}. Diese wird hierzu umdefiniert.  Falls die
  Anweisung nicht die erwartete Definition hat, gibt
  \Package{scrlfile} eine Warnung aus.  Dies geschieht für den Fall,
  dass die Anweisung in späteren \LaTeX-Versionen geändert wird oder
  bereits von einem anderen Paket umdefiniert wurde.
  
  Die Anweisung \Macro{InputIfFileExists} wird von \LaTeX{} immer
  verwendet, wenn eine Datei geladen werden soll. Dies geschieht
  unabhängig davon, ob die Datei mit \Macro{include}, \Macro{LoadClass},
  \Macro{documentclass}, \Macro{usepackage}, \Macro{RequirePackage},
  oder vergleichbaren Anweisungen geladen wird. Lediglich
% Umbruchkorrektur: listings korrigieren
\begin{lstcode}[belowskip=\dp\strutbox]
  \input foo
\end{lstcode}
  lädt die Datei \texttt{foo} ohne Verwendung von
  \Macro{InputIfFileExists}. Sie sollten daher stattdessen immer
% Umbruchkorrektur: listings korrigieren
\begin{lstcode}[belowskip=\dp\strutbox]
  \input{foo}
\end{lstcode}
  verwenden. Beachten Sie die Klammern um den Dateinamen!%
%\end{Explain}
%
\EndIndex{Cmd}{BeforeFile}%
\EndIndex{Cmd}{AfterFile}%


\BeginIndex{Cmd}{BeforeClass}%
\BeginIndex{Cmd}{BeforePackage}%
\begin{Declaration}
  \Macro{BeforeClass}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{BeforePackage}\Parameter{Paket}\Parameter{Anweisungen}
\end{Declaration}%
Diese beiden Befehle arbeiten vergleichbar zu \Macro{BeforeFile} mit dem einen
Unterschied, dass die \PName{Klasse} beziehungsweise das \PName{Paket} mit
seinem Namen und nicht mit seinem Dateinamen angegeben wird. Die Endungen
»\File{.cls}« und »\File{.sty}« entfallen hier also.%
%
\EndIndex{Cmd}{BeforeClass}%
\EndIndex{Cmd}{BeforePackage}%


\BeginIndex{Cmd}{AfterClass}%
\BeginIndex{Cmd}{AfterClass*}%
\BeginIndex{Cmd}{AfterClass+}%
\BeginIndex{Cmd}{AfterClass!}%
\BeginIndex{Cmd}{AfterAtEndOfClass}%
\BeginIndex{Cmd}{AfterPackage}%
\BeginIndex{Cmd}{AfterPackage*}%
\BeginIndex{Cmd}{AfterPackage+}%
\BeginIndex{Cmd}{AfterPackage!}%
\BeginIndex{Cmd}{AfterAtEndOfPackage}%
\begin{Declaration}
  \Macro{AfterClass}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{AfterAtEndOfClass}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{AfterClass*}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{AfterClass+}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{AfterClass!}\Parameter{Klasse}\Parameter{Anweisungen}\\
  \Macro{AfterPackage}\Parameter{Paket}\Parameter{Anweisungen}\\
  \Macro{AfterPackage*}\Parameter{Paket}\Parameter{Anweisungen}\\
  \Macro{AfterPackage+}\Parameter{Paket}\Parameter{Anweisungen}\\
  \Macro{AfterPackage!}\Parameter{Paket}\Parameter{Anweisungen}\\
  \Macro{AfterAtEndOfPackage}\Parameter{Klasse}\Parameter{Anweisungen}
\end{Declaration}%
Die Anweisungen \Macro{AfterClass} und \Macro{AfterPackage} arbeiten
weitgehend wie \Macro{AfterFile} mit dem winzigen Unterschied, dass die
\PName{Klasse} beziehungsweise das \PName{Paket} mit seinem Namen und nicht
mit seinem Dateinamen angegeben wird. Die Endungen »\File{.cls}« und
»\File{.sty}« entfallen hier also. Bei den Sternvarianten gibt es eine
zusätzliche Funktionalität. Wurde oder wird die entsprechende Klasse oder das
entsprechende Paket bereits geladen, so werden die \PName{Anweisungen} nicht
nach dem nächsten Laden, sondern unmittelbar ausgeführt. Bei der
Plusvariante\ChangedAt{v3.09}{\Package{scrlfile}} werden die
\PName{Anweisungen} sicher erst dann ausgeführt, wenn die Klasse oder das
Paket vollständig geladen wurden. Der Unterschied zwischen der Stern- und der
Plusvariante kommt nur zum Tragen, wenn die Anweisung verwendet wird, wenn das
Laden der Klassen bzw. des Pakets zwar bereits begonnen hat, aber noch nicht
beendet wurde. Wenn das Laden der Klasse bzw. des Pakets noch nicht
abgeschlossen wurde, werden die \PName{Anweisungen} in allen Fällen vor den
in der Klasse bzw. dem Paket mit \Macro{AtEndOfClass} oder
\Macro{AtEndOfPackage} verzögerten Anweisungen ausgeführt. Um stattdessen
eine Ausführung danach sicher zu stellen, ist die Variante mit Ausrufezeichen
zu verwenden. In diesem Fall werden die \PName{Anweisungen} nicht mehr im
Kontext der angegebenen Klasse bzw. des angegebenen Pakets ausgeführt. Will
man genau dies nur für den Fall erreichen, dass die Klasse bzw. das Paket
noch nicht geladen wurde, so verwendet man die Anweisung
\Macro{AfterAtEndOfClass}\ChangedAt{v3.09}{\Package{scrlfile}}
bzw. \Macro{AfterAtEndOfPackage}.%
%
\begin{Example}
  Als Beispiel für Paket- oder Klassenautoren will ich zunächst
  erklären, wie \KOMAScript{} selbst Gebrauch von den neuen
  Anweisungen macht. Dazu findet sich in \Class{scrbook}
  beispielsweise Folgendes:
\begin{lstcode}
  \AfterPackage{hyperref}{%
    \@ifpackagelater{hyperref}{2001/02/19}{}{%
      \ClassWarningNoLine{scrbook}{%
        You are using an old version of hyperref 
        package!\MessageBreak%
        This version has a buggy hack at many drivers%
        \MessageBreak%
        causing \string\addchap\space to behave 
        strange.\MessageBreak%
        Please update hyperref to at least version
        6.71b}}}
\end{lstcode}
  Alte Versionen von \Package{hyperref} definierten ein Makro von
  \Class{scrbook} in einer Weise um, so dass es mit neueren Versionen
  von \KOMAScript{} nicht mehr funktioniert. Neuere Versionen von
  \Package{hyperref} unterlassen dies, wenn sie eine neuere Version
  von \KOMAScript{} erkennen. Für den Fall, dass \Package{hyperref}
  zu einem späteren Zeitpunkt geladen wird, sorgt also \Class{scrbook}
  dafür, dass unmittelbar nach dem Laden des Paketes überprüft wird, ob
  es sich um eine verträgliche Version handelt. Falls dies nicht der
  Fall ist, wird eine Warnung ausgegeben.

  An anderer Stelle findet sich in drei \KOMAScript-Klassen Folgendes:
\begin{lstcode}
  \AfterPackage{caption2}{%
    \renewcommand*{\setcapindent}{%
\end{lstcode}% }}
  Nach dem Laden von \Package{caption2} und nur falls das Paket
  geladen wird, wird hier die \KOMAScript-Anweisung
  \Macro{setcapindent} umdefiniert. Der Inhalt der Umdefinierung ist
  für dieses Beispiel unerheblich. Es sei nur erwähnt, dass
  \Package{caption2} die Kontrolle über die \Macro{caption}-Anweisung
  übernimmt und daher die normale Definition von \Macro{setcapindent}
  keinerlei Wirkung mehr hätte. Die Umdefinierung verbessert dann die
  Zusammenarbeit mit \Package{caption2}.

  Es gibt aber auch Beispiele für den sinnvollen Einsatz der neuen
  Anweisungen durch normale Anwender. Angenommen, Sie erstellen ein
  Dokument, aus dem sowohl eine PS-Datei mit \LaTeX{} und dvips als auch
  eine PDF-Datei mit pdf\LaTeX{} erstellt werden soll. Das Dokument soll
  außerdem Hyperlinks aufweisen. Im Tabellenverzeichnis haben Sie
  Einträge, die über mehrere Zeilen gehen. Nun gibt es zwar mit
  pdf\LaTeX{} bei der PDF-Ausgabe keine Probleme, da dort Links
  umbrochen werden können. Bei Verwendung des
  \Package{hyperref}-Treibers für dvips oder
  hyper\TeX{} ist dies jedoch nicht
  möglich. In diesem Fall hätten Sie gerne, dass bei
  \Package{hyperref} die Einstellung \Option{linktocpage} verwendet
  wird. Die Entscheidung, welcher Treiber geladen wird, wird bei Ihnen
  automatisch von \File{hyperref.cfg} erledigt. Dazu sieht die Datei
  beispielsweise wie folgt aus:
\begin{lstcode}
  \ProvidesFile{hyperref.cfg}
  \@ifundefined{pdfoutput}{\ExecuteOptions{dvips}}
                          {\ExecuteOptions{pdftex}}
  \endinput
\end{lstcode}

  Alles weitere kann nun \Macro{AfterFile} überlassen werden:
  \begin{lstcode}[moretexcs={hypersetup}]
  \documentclass{article}
  \usepackage{scrlfile,ngerman}
  \AfterFile{hdvips.def}{\hypersetup{linktocpage}}
  \AfterFile{hypertex.def}{\hypersetup{linktocpage}}
  \usepackage{hyperref}
  \begin{document}
  \listoffigures
  \clearpage
  \begin{figure}
    \caption{Dies ist ein Beispiel mit einer
      Abbildungsunterschrift, die etwas länglich ist
      und bei der trotzdem auf die Verwendung des 
      optionalen Arguments verzichtet wurde}
  \end{figure}
  \end{document}
  \end{lstcode}
  Egal, ob nun der \Package{hyperref}-Treiber \Option{hypertex} oder
  \Option{dvips} zu Anwendung kommt, wird die dann nützliche Einstellung
  \Option{linktocpage} verwendet. Wenn Sie jedoch mit pdf\LaTeX{} eine
  PDF-Datei erstellen, wird darauf verzichtet, da in diesem Fall der
  \Package{hyperref}-Treiber \File{hpdftex.def} verwendet wird. Das bedeutet,
  dass weder die Treiberdatei \File{hdvips.def} noch \File{hypertex.def}
  geladen wird.
\end{Example}

Übrigens können Sie das Laden von \Package{scrlfile} und die obigen
\Macro{AfterFile}-Anweisungen auch in Ihre private \File{hyperref.cfg}
einfügen. Verwenden Sie dabei jedoch zum Laden des Paketes besser
\Macro{RequirePackage} an Stelle von \Macro{usepackage} (siehe
\cite{latex:clsguide}). Die neuen Zeilen müssen in obigem Beispiel unmittelbar
nach der \Macro{ProvidesFile}-Zeile, also unbedingt vor der Ausführung der
Optionen \Option{dvips} oder \Option{pdftex}, eingefügt werden.%
%
\EndIndex{Cmd}{AfterClass}%
\EndIndex{Cmd}{AfterClass*}%
\EndIndex{Cmd}{AfterClass+}%
\EndIndex{Cmd}{AfterClass!}%
\EndIndex{Cmd}{AfterAtEndOfClass}%
\EndIndex{Cmd}{AfterPackage}%
\EndIndex{Cmd}{AfterPackage*}%
\EndIndex{Cmd}{AfterPackage+}%
\EndIndex{Cmd}{AfterPackage!}%
\EndIndex{Cmd}{AfterAtEndOfPackage}%


\BeginIndex{Cmd}{BeforeClosingMainAux}%
\BeginIndex{Cmd}{AfterReadingMainAux}%
\begin{Declaration}
  \Macro{BeforeClosingMainAux}\Parameter{Anweisungen}\\
  \Macro{AfterReadingMainAux}\Parameter{Anweisungen}
\end{Declaration}
Diese Anweisungen unterscheidet sich in einem Detail von den zuvor erklärten
Anweisungen. Jene ermöglichen Aktionen vor und nach dem Laden von
Dateien. Dies ist hier nicht der Fall. Paketautoren haben des Öfteren das
Problem, dass Sie Anweisungen in die \File{aux}-Datei schreiben wollen,
nachdem die letzte Seite des Dokuments ausgegeben wurde. Dies wird häufig mit
\begin{lstcode}
  \AtEndDocument{%
    \if@filesw
      \write\@auxout{%
        \protect\writethistoaux%
      }%
    \fi
  } 
\end{lstcode}
versucht. Dies ist jedoch keine echte Lösung des Problems. Wurde die letzte
Seite vor \Macro{end}\PParameter{document} bereits ausgegeben, so führt obiges
zu keiner Ausgabe in die \File{aux}-Datei mehr. Würde man zur Lösung dieses
Problems nun ein \Macro{immediate} vor \Macro{write} setzen, so hätte man das
umgekehrte Problem: wurde die letzte Seite bei
\Macro{end}\PParameter{document} noch nicht ausgegeben, so wird
\Macro{writethistoaux} zu früh in die \File{aux}-Datei geschrieben. Man sieht
daher häufig Lösungsversuche wie:
\begin{lstcode}
  \AtEndDocument{%
    \if@filesw
      \clearpage
      \immediate\write\@auxout{%
        \protect\writethistoaux%
      }%
    \fi
  } 
\end{lstcode}
Diese Lösung hat jedoch den Nachteil, dass damit die Ausgabe der letzten Seite
erzwungen wird. Eine Anweisung wie:
\begin{lstcode}
  \AtEndDocument{%
    \par\vspace*{\fill}%
    Hinweis am Ende des Dokuments.\par
  }
\end{lstcode}
führt dann nicht mehr dazu, dass der Hinweis am Ende der letzten Seite des
Dokuments ausgegeben wird, sie würde stattdessen am Ende der nächsten Seite
ausgegeben. Gleichzeitig würde \Macro{writethistoaux} wieder eine Seite zu
früh in der \File{aux}-Datei landen.

Die beste Lösung des Problems wäre nun, wenn man unmittelbar in die
\File{aux}-Datei schreiben könnte, nachdem das finale \Macro{clearpage}
innerhalb von \Macro{end}\PParameter{document} ausgeführt und bevor die
\File{aux}-Datei geschlossen wird. Genau dies ist das Ziel von
\Macro{BeforeClosingMainAux}:
\begin{lstcode}
  \BeforeClosingMainAux{%
    \if@filesw
      \immediate\write\@auxout{%
        \protect\writethistoaux%
      }%
    \fi
  }
\end{lstcode}
Dies ist auch dann erfolgreich, wenn das finale \Macro{clearpage} innerhalb
von \Macro{end}\PParameter{document} tatsächlich zu keiner Ausgabe einer Seite
mehr führt oder wenn \Macro{clearpage} innerhalb einer
\Macro{AtEndDocument}-Anweisung verwendet wurde.

Es gibt jedoch für \Macro{BeforeClosingMainAux} eine Einschränkung: Im
Argument \Macro{Anweisungen} sollte keine eine Satzanweisung verwendet
werden. Es darf also mit \Macro{BeforeClosingMainAux} kein zusätzliches
Material gesetzt werden! Wird diese Einschränkung nicht beachtet, so ist das
Ergebnis ebenso unvorhersehbarer wie bei den gezeigten Problemen mit
\Macro{AtEndDocument}.

Die Anweisung \Macro{AfterReadingMainAux}\ChangedAt{v3.03}{\Package{scrlfile}}
führt sogar \PName{Anweisungen} nach dem Schließen und Einlesen der
\File{aux}-Datei innerhalb von \Macro{end}\PParameter{document} aus. Dies ist
nur in einigen wenigen, sehr seltenen Fällen sinnvoll, beispielsweise, wenn
man statistische Informationen in die \File{log}-Datei schreiben will, die
erst nach dem Einlesen der \File{aux}-Datei gültig sind oder zur
Implementierung zusätzlicher \emph{Rerun}-Aufforderungen. Satzanweisungen sind
an dieser Stelle noch kritischer zu betrachten als bei
\Macro{BeforeClosingMainAux}.%
%
\EndIndex{Cmd}{AfterReadingMainAux}%
\EndIndex{Cmd}{BeforeClosingMainAux}%


\section{Dateien beim Einlesen ersetzen}
\label{sec:scrlfile.replace}

In den bisherigen Abschnitten wurden Anweisungen erklärt, mit denen es möglich
ist, vor oder nach dem Einlesen einer bestimmten Datei, eines bestimmten
Pakets oder einer Klasse, Aktionen auszuführen. Es ist mit \Package{scrlfile}
aber auch möglich, eine ganz andere Datei als die angeforderte einzulesen.

\BeginIndex{Cmd}{ReplaceInput}%
\begin{Declaration}
  \Macro{ReplaceInput}\Parameter{Dateiname}\Parameter{Ersatzdatei}
\end{Declaration}
Mit\ChangedAt{v2.96}{\Package{scrlfile}} dieser Anweisung wird eine Ersetzung
der Datei mit dem als erstes angegebenen \PName{Dateiname} definiert. Wenn
\LaTeX{} anschließend angewiesen wird, diese Datei zu laden, wird stattdessen
die \PName{Ersatzdatei} geladen. Die Definition der Ersatzdatei wirkt sich auf
alle Dateien aus, die vom Anwender oder intern von \LaTeX{} mit Hilfe von
\Macro{InputIfFileExists} geladen werden. Dazu ist es allerdings erforderlich,
dass \Package{scrlfile} diese Anweisung umdefiniert.

\begin{Example}
  Sie wollen, dass an Stelle der Datei \File{\Macro{jobname}.aux}, die Datei
  \File{\Macro{jobname}.xua} geladen wird. Dazu verwenden Sie:
  \begin{lstcode}
  \ReplaceInput{\jobname.aux}{\jobname.xua}
  \end{lstcode}
  Wenn Sie nun außerdem \File{\Macro{jobname}.xua} durch
  \File{\Macro{jobname}.uxa} ersetzen:
  \begin{lstcode}
  \ReplaceInput{\jobname.xua}{\jobname.uxa}
  \end{lstcode}
  dann wird \File{\Macro{jobname}.aux} in Wirklichkeit durch
  \File{\Macro{jobname}.uxa} ersetzt. Es wird also die komplette
  Ersetzungskette abgearbeitet.

  Einer Ersetzung im Kreis:
  \begin{lstcode}
  \ReplaceInput{\jobname.aux}{\jobname.xua}
  \ReplaceInput{\jobname.xua}{\jobname.aux}
  \end{lstcode}
  würde jedoch zu einem \emph{stack size error} führen. Es ist also nicht
  möglich, eine einmal ersetzte Datei wieder durch ihren Ursprung zu ersetzen.
\end{Example}

Theoretisch wäre es auch möglich, auf diesem Wege ein Paket durch ein anderes
oder eine Klasse durch eine andere zu ersetzen. Dabei würde \LaTeX{} aber
erkennen, dass die angeforderten Dateinamen nicht zum Namen des Pakets oder
der Klasse passen. Eine Lösung dieses Problems finden Sie nachfolgend.
%
\EndIndex{Cmd}{ReplaceInput}%


\BeginIndex{Cmd}{ReplaceClass}%
\BeginIndex{Cmd}{ReplacePackage}%
\begin{Declaration}
  \Macro{ReplaceClass}\Parameter{Klasse}\Parameter{Ersatzklasse}\\
  \Macro{ReplacePackage}\Parameter{Paket}\Parameter{Ersatzpaket}
\end{Declaration}
Eine\ChangedAt{v2.96}{\Package{scrlfile}} Klasse oder ein Paket sollte niemals
mit Hilfe von \Macro{ReplaceInput} ersetzt werden. In diesem Fall würde
\LaTeX{} eine Warnung über nicht übereinstimmende Klassen- oder Paketnamen
melden.
\begin{Example}
  Sie ersetzen das Paket \Package{fancyhdr} leichtfertig durch das nicht
  kompatible Paket \Package{scrpage2}, indem Sie
  \begin{lstcode}
  \ReplaceInput{fancyhdr.sty}{scrpage2.sty}
  \end{lstcode}
  verwenden. Dies führt zu der Warnung
  \begin{lstcode}
  LaTeX warning: You have requested `scrpage2',
                 but the package provides `fancyhdr'.}
  \end{lstcode}
  führen. Für den Anwender wäre diese Warnung mehr als verwirrend, hat er doch
  gar nicht \Package{scrpage2}, sondern tatsächlich \Package{fancyhdr}
  angefordert, das jedoch durch \Package{scrpage2} ersetzt wurde.
\end{Example}
Eine Lösung dieses Problems besteht nun darin, statt \Macro{ReplaceInput} eine
der Anweisungen \Macro{ReplaceClass} oder \Macro{ReplacePackage} zu
verwenden. Es ist zu beachten, dass dabei wie bei \Macro{documentclass} und
\Macro{usepackage} der Name der Klasse oder des Pakets und nicht deren
kompletter Dateiname anzugeben ist.

Die Ersetzung funktioniert mit diesen Anweisungen für Klassen, die mit
\Macro{LoadClass}, \Macro{LoadClassWithOptions} oder \Macro{documentclass}
geladen werden. Für Pakete funktioniert die Ersetzung beim Laden mit
\Macro{RequirePackage}, \Macro{RequirePackageWithOptions} und
\Macro{usepackage}.

Es ist zu beachten, dass die \PName{Ersatzklasse} oder das \PName{Ersatzpaket}
mit denselben Optionen geladen wird, mit denen die ursprünglich geforderte
Klasse oder das ursprünglich geforderte Paket geladen würden. Wird ein Paket
oder eine Klasse durch ein Paket oder eine Klasse ersetzt, das eine geforderte
Option nicht unterstützt, würde dies zu den üblichen Warnungen und Fehlern
führen. Es ist jedoch möglich, solche in der \PName{Ersatzklasse} oder dem
\PName{Ersatzpaket} fehlenden Optionen per \Macro{BeforeClass} oder
\Macro{BeforePackage} neu zu definieren.

\begin{Example}
  Angenommen, das Paket \Package{oldfoo} soll beim Laden durch das
  Paket{newfoo} ersetzt werden. Dies wird mit:
  \begin{lstcode}
  \ReplacePackage{oldfoo}{newfoo}
  \end{lstcode}
  erreicht. Das alte Paket hat eine Option \Option{oldopt}, die das neue Paket
  jedoch nicht hat. Mit
  \begin{lstcode}
  \BeforePackage{newfoo}{%
    \DeclareOption{oldopt}{%
      \PackageInfo{newfoo}{option `oldopt' not supported}%
    }%
  }
  \end{lstcode}
  wird diese Option nun für das Paket \Package{newfoo} nachdefiniert. Dadurch
  wird vermieden, dass beim Laden des Pakets \Package{oldfoo} ein Fehler über
  die im Paket \Package{newfoo} nicht unterstützte Option gemeldet wird.

  Existiert hingegen eine Option \Option{newopt}, die an Stelle der Option
  \Option{oldopt} verwendet werden soll, so kann dies ebenfalls erreicht
  werden:
  \begin{lstcode}
  \BeforePackage{newfoo}{%
    \DeclareOption{oldopt}{%
      \ExecuteOptions{newopt}%
    }%
  }
  \end{lstcode}
  Es ist sogar möglich, festzulegen, dass beim Laden des neuen Pakets
  andere Voreinstellung gelten sollen:
  \begin{lstcode}
  \BeforePackage{newfoo}{%
    \DeclareOption{oldopt}{%
      \ExecuteOptions{newopt}%
    }%
    \PassOptionsToPackage{newdefoptA,newdefoptB}{newfoo}%
  }
  \end{lstcode}
  oder auch direkt:
  \begin{lstcode}
  \BeforePackage{newfoo}{%
    \DeclareOption{oldopt}{%
      \ExecuteOptions{newopt}%
    }%
  }
  \PassOptionsToPackage{newdefoptA,newdefoptB}{newfoo}%
  \end{lstcode}
\end{Example}

Damit Klassen ersetzt werden können, ist es erforderlich \Package{scrlfile}
mit Hilfe von \Macro{RequirePackage} vor der Klasse zu laden.
%
\EndIndex{Cmd}{ReplacePackage}%
\EndIndex{Cmd}{ReplaceClass}%

\section{Dateien gar nicht erst einlesen}
\label{sec:scrlfile.prevent}

Gerade\ChangedAt{v3.08}{\Package{scrlfile}} in Klassen und Paketen, die
innerhalb von Firmen oder Instituten verwendet werden, findet man häufig, dass
sehr viele Pakete nur deshalb geladen werden, weil die Anwender diese Pakete
häufig verwenden. Wenn es dann mit einem dieser automatisch geladenen Paketen
zu einem Problem kommt, muss man irgendwie das Laden des problematischen Paketes
verhindern. Auch hier bietet \Package{scrlfile} eine einfache Lösung.

\begin{Declaration}
  \Macro{PreventPackageFromLoading}\Parameter{Paketliste}
\end{Declaration}
\BeginIndex{Cmd}{PreventPackageFromLoading}%
Wird diese Anweisung\ChangedAt{v3.08}{\Package{scrlfile}} irgendwann vor dem
Laden eines Paket mit \Macro{usepackage}\IndexCmd{usepackage},
\Macro{RequirePackage}\IndexCmd{RequirePackage} oder
\Macro{RequirePackageWithOptions}\IndexCmd{RequirePackageWithOptions}
aufgerufen, so wird das Laden des Pakets effektiv verhindert, falls es in
\PValue{Paketliste} zu finden ist.
%
\begin{Example}
  Angenommen Sie arbeiten in einer Firma, in der alle Dokumente mit
  Latin~Modern erzeugt werden. In der Firmenklasse, \Class{firmenci}, befinden
  sich daher die Zeilen:
  \begin{lstcode}
  \RequirePackage[T1]{fontenc}
  \RequirePackage{lmodern}
  \end{lstcode}
  Nun wollen Sie zum ersten Mal ein Dokument mit
  X\kern-.125em\lower.5ex\hbox{\reflectbox{E}}\LaTeX{} oder Lua\LaTeX{}
  setzen. Da hierbei ohnehin Latin-Modern voreingestellt ist und das Laden von
  \Package{fontenc} eher störend wäre, wollen Sie das Laden beider Pakete
  verhindern. Sie laden die Klasse deshalb nun in Ihrem eigenen Dokument wie
  folgt:
  \begin{lstcode}
  \RequirePackage{scrlfile}
  \PreventPackageFromLoading{fontenc,lmodern}
  \documentclass{firmenci}
  \end{lstcode}
\end{Example}
Wie im Beispiel zu sehen ist, kann man das Paket \Package{scrlfile} auch
bereits vor der Klasse laden. In diesem Fall muss das Laden dann aber mit
Hilfe von \Macro{RequirePackage}\IndexCmd{RequirePackage} erfolgen, da
\Macro{usepackage} vor \Macro{documentclass} verboten ist.
%
\EndIndex{Cmd}{PreventPackageFromLoading}

\begin{Declaration}
  \Macro{StorePreventPackageFromLoading}\Parameter{\Macro{Anweisung}}\\
  \Macro{ResetPreventPackageFromLoading}
\end{Declaration}
\BeginIndex{Cmd}{StorePreventPackageFromLoading}%
\BeginIndex{Cmd}{ResetPreventPackageFromLoading}%
\PName{Anweisung} wird mit Hilfe von
\Macro{StorePreventPackageFromLoading}\ChangedAt{v3.08}{\Package{scrlfile}}
als die aktuelle Liste der Pakete definiert, für die das Laden verhindert
werden soll. Im Gegensatz dazu setzt
\Macro{ResetPreventPackageFromLoading}\ChangedAt{v3.08}{\Package{scrlfile}}
die Liste der Pakete, für die das Laden verhindert werden soll, zurück. Danach
können wieder alle Pakete geladen werden.
\begin{Example}
  Angenommen, Sie sind innerhalb eines Pakets unbedingt auf das Laden eines
  anderen Pakets angewiesen und wollen nicht, dass der Anwender das Laden
  dieses Pakets mit
  \Macro{PreventPackageFromLoading}\IndexCmd{PreventPackageFromLoading}
  verhindern kann. Also setzen Sie die Paketliste für die Ausnahmen zuvor
  zurück:
  \begin{lstcode}
  \ResetPreventPackageFromLoading
  \RequirePackage{foo}
  \end{lstcode}
  Allerdings hat dies den Nachteil, dass ab diesem Zeitpunkt die komplette
  Ausnahmeliste des Anwenders verloren ist. Also speichern Sie die Liste
  zunächst zwischen und reaktivieren Sie später wieder:
  \begin{lstcode}
  \newcommand*{\Users@PreventList}{}%
  \StorePreventPackageFromLoading\Users@PreventList
  \ResetPreventPackageFromLoading
  \RequirePackage{foo}
  \PreventPackageFromLoading{\Users@PreventList}
  \end{lstcode}
  \Macro{StorePreventPackageFromLoading} würde die Anweisung
  \Macro{Users@PreventList} auch dann definieren, wenn diese bereits
  anderweitig definiert wäre. In diesem Beispiel wurde deshalb mit einem
  vorherigen \Macro{newcommand*} sichergestellt, dass in diesem Fall zur
  Sicherheit eine Fehlermeldung ausgegeben wird.
\end{Example}
An dieser Stelle sei darauf hingewiesen, dass Sie bei Manipulationen an der mit
\Macro{StorePreventPackageFromLoading} zwischengespeicherten Liste selbst die
Verantwortung für eine korrekte Wiederherstellbarkeit tragen. So muss die
Liste unbedingt mit Komma separiert sein, sollte keine Leerzeichen oder
Gruppenklammern enthalten und muss voll expandierbar sein.
%
\EndIndex{Cmd}{ResetPreventPackageFromLoading}%
\EndIndex{Cmd}{StorePreventPackageFromLoading}%
%
\EndIndex{Package}{scrlfile}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "../guide"
%%% End: 
