% ====================================================================== % scrlfile.tex % Copyright (c) Markus Kohm, 2001-2018 % % 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-2018 % % 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 ueber scrlfile in der KOMA-Script-Anleitung % Verwaltet von Markus Kohm % % ============================================================================ \KOMAProvidesFile{scrlfile.tex} [$Date: 2018-03-30 11:57:25 +0200 (Fri, 30 Mar 2018) $ KOMA-Script guide (chapter: scrlfile)] \translator{Gernot Hassenpflug\and Markus Kohm\and Karl Hagen} % Date of the translated German file: 2018-02-15 \chapter{Controlling Package Dependencies with \Package{scrlfile}} \labelbase{scrlfile} \BeginIndexGroup \BeginIndex{Package}{scrlfile} The introduction of \LaTeXe{} in 1994 brought many changes in the handling of \LaTeX{} extensions. The package author today has a whole series of macros available to determine if another package or class has been loaded and whether specific options are being used. The package author can even load other packages or specify certain options in case the package is loaded later. This has led to the expectation that the order in which package are loaded would not be important. Sadly, this hope has not been fulfilled. \section{About Package Dependencies} \seclabel{dependency} %\begin{Explain} More and more often, different packages either newly define or redefine the same macro. In such a case, the order in which a package is loaded becomes very important. Sometimes, users find it very difficult to understand the resulting behaviour. Sometimes it is necessary to react in a specific way when another package is loaded. As a simple example, consider loading the \Package{longtable} package with a \KOMAScript{} document class. The \Package{longtable} package defines its own table captions. These are perfectly suited to the standard classes, but they do not match the default settings for \KOMAScript{} captions, nor do they react to the relevant configuration options. To solve this problem, the \Package{longtable} package commands which are responsible for the table captions need to be redefined. However, by the time the \Package{longtable} package is loaded, the \KOMAScript{} class has already been processed. Previously, the only way to solve this problem was to delay the redefinition until the beginning of the document using \Macro{AtBeginDocument}. However, if users want to change the relevant commands themselves, they should do so in the preamble of the document. But this is impossible because \KOMAScript{} will overwrite the users' definitions at \Macro{begin}\PParameter{document}. They would also need to perform the redefinition with \Macro{AtBeginDocument}. But \KOMAScript{} does not actually need to wait for \Macro{begin}\PParameter{document} to redefine the macros. It would be sufficient to postpone the redefinition until after the \Package{longtable} package has been loaded. Unfortunately, the \LaTeX{} kernel does not define necessary commands. The \Package{scrlfile} package provides a remedy for this problem. It is also conceivable that you would like to save the definition of a macro in a temporary macro before a package is loaded and restore it after the package has been loaded. The \Package{scrlfile} package allows this, too. The use of \Package{scrlfile} is not limited to package dependencies. Dependencies can also be considered for any other file. For example, you can ensure that loading the not unimportant file \File{french.ldf} automatically leads to a warning. Although the package is particularly of interest for package authors, there are also applications for normal \LaTeX{} users. Therefore, this chapter gives examples for both groups. %\end{Explain} \section{Actions Before and After Loading} \seclabel{macros} The \Package{scrlfile} package can execute actions both before and after loading files. The commands used to do so distinguish between ordinary files, classes, and packages. \begin{Declaration} \Macro{BeforeFile}\Parameter{file}\Parameter{commands}% \Macro{AfterFile}\Parameter{file}\Parameter{commands} \end{Declaration}% \Macro{BeforeFile} ensures that the \PName{commands} are executed before the next time \PName{file} is loaded. \Macro{AfterFile} works in a similar fashion, and the \PName{commands} will be executed after the \PName{file} has been loaded. Of course, if \PName{file} is never loaded, the \PName{commands} will never be executed. For \PName{file}, you should specify any extensions as part of the file name, as you would with \Macro{input}. To implement those features, \Package{scrlfile} redefines the well-known \LaTeX{} command \Macro{InputIfFileExists}. If this command does not have the expected definition, \Package{scrlfile} issues a warning. This occurs in case the command is changed in future \LaTeX{} versions or has already been redefined by another package. \LaTeX{} uses the \Macro{InputIfFileExists} command every time it loads a file. This occurs regardless of whether the file is loaded with \Macro{include}, \Macro{LoadClass}, \Macro{documentclass}, \Macro{usepackage}, \Macro{RequirePackage}, or similar commands. Only \begin{lstcode} \input foo \end{lstcode} loads the file \texttt{foo} without using \Macro{InputIfFileExists}. You should therefore always use \begin{lstcode} \input{foo} \end{lstcode} instead. Notice the parentheses surrounding the file name!% % \EndIndexGroup \begin{Declaration} \Macro{BeforeClass}\Parameter{class}\Parameter{commands}% \Macro{BeforePackage}\Parameter{package}\Parameter{commands} \end{Declaration}% These two commands work the same way as \DescRef{\LabelBase.cmd.BeforeFile}. The only difference is that the \PName{class} or \PName{package} is specified with its class or package name and not with its file name. That means you should omit the file extensions \File{.cls} or \File{.sty}.% % \EndIndexGroup \begin{Declaration} \Macro{AfterClass}\Parameter{class}\Parameter{commands}% \Macro{AfterClass*}\Parameter{class}\Parameter{commands}% \Macro{AfterClass+}\Parameter{class}\Parameter{commands}% \Macro{AfterClass!}\Parameter{class}\Parameter{commands}% \Macro{AfterAtEndOfClass}\Parameter{class}\Parameter{commands}% \Macro{AfterPackage}\Parameter{package}\Parameter{commands}% \Macro{AfterPackage*}\Parameter{package}\Parameter{commands}% \Macro{AfterPackage+}\Parameter{package}\Parameter{commands}% \Macro{AfterPackage!}\Parameter{package}\Parameter{commands}% \Macro{AfterAtEndOfPackage}\Parameter{package}\Parameter{commands} \end{Declaration}% The \Macro{AfterClass} and \Macro{AfterPackage} commands work much like \DescRef{\LabelBase.cmd.AfterFile}. The only difference is that the \PName{class} or \PName{package} is specified with its class or package name and not with its file name. That means you should omit the file extensions \File{.cls} or \File{.sty}. The\important[i]{\Macro{AfterClass*}\\\Macro{AfterPackage*}} starred versions function somewhat differently. If the class or package has already been loaded, they execute the \PName{commands} immediately rather than waiting until the next time the class or package is loaded. The\important[i]{\Macro{AfterClass+}\\\Macro{AfterPackage+}} plus\ChangedAt{v3.09}{\Package{scrlfile}} version executes the \PName{commands} after the class or package has been completely loaded. This behaviour differs from that of the starred version only if you use the command when the class or package has begun loading but has not yet finished. If the class or package has not finished loading, the \PName{commands} will always be executed before the commands in \Macro{AtEndOfClass} or \Macro{AtEndOfPackage}. If\important[i]{\Macro{AfterClass!}\\\Macro{AfterPackage!}} a class uses \Macro{AtEndOfClass} or a package uses \Macro{AtEndOfPackage} to execute commands after the class of package file has been loaded completely, and if you want to execute \PName{commands} after these deferred commands have been executed, you can use the exclamation-mark versions \Macro{AfterClass!}\ChangedAt{v3.09}{\Package{scrlfile}} or \Macro{AfterPackage!}. If\important[i]{\Macro{AfterAtEndOfClass}\\\Macro{AfterAtEndOfPackage}} you want to execute the \PName{commands} only when the class or package is loaded later and outside the context of that class or package, you can use \Macro{AfterAtEndOfClass}\ChangedAt{v3.09}{\Package{scrlfile}} for classes and \Macro{AfterAtEndOfPackage} for packages. \begin{Example} The following example for class and package authors shows how \KOMAScript{} itself makes use of the new commands. The class \Class{scrbook} contains the following: % CORRECTED MESSAGE: % You are using an old version of the hyperref % package!\MessageBreak% % This version has a buggy hack in many % drivers,\MessageBreak% % causing \string\addchap\space to behave % strangely.\MessageBreak% % Please update hyperref to at least version % 6.71b}% \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} Old versions of the \Package{hyperref} package redefine a macro of the \Class{scrbook} class in a way that is incompatible with newer \KOMAScript{} versions. Newer versions of \Package{hyperref} refrain from making this change if a newer version of \KOMAScript{} is detected. In case \Package{hyperref} is loaded at a later stage, \Class{scrbook} ensures that a check for an acceptable version of \Package{hyperref} is performed immediately after the package is loaded. If this is not the case, a warning is issued. Elsewhere in three of the \KOMAScript{} classes, you can find the following: \begin{lstcode} \AfterPackage{caption2}{% \renewcommand*{\setcapindent}{% \end{lstcode} After loading \Package{caption2}, and only if it has been loaded, \KOMAScript{} redefines its own \DescRef{maincls.cmd.setcapindent} command. The exact code of the redefinition is irrelevant. The important thing to note is that \Package{caption2} takes control of the \DescRef{maincls.cmd.caption} macro and that therefore the normal definition of the \DescRef{maincls.cmd.setcapindent} command would have no effect. The redefinition thus improves interoperability with \Package{caption2}. There are also, however, instances where these commands are useful to normal \LaTeX{} users. For example, suppose you create a document from which you want to generate both a PostScript file, using \LaTeX{} and dvips, and a PDF file, using \mbox{pdf{\LaTeX}}. The document should also contain hyperlinks. In the table of contents, you have entries that span several lines. This is not a problem for the \mbox{pdf{\LaTeX}} method, since here hyperlinks can be broken across multiple lines. However, this is not possible with the \Package{hyperref} driver for dvips or \mbox{hyper{\TeX}}. In this case, you would like \Package{hyperref} to use the \Option{linktocpage} option. The decision as to which driver is loaded is made automatically by \File{hyperref}. Everything else can now be left to \DescRef{\LabelBase.cmd.AfterFile}: \begin{lstcode} \documentclass{article} \usepackage{scrlfile} \AfterFile{hdvips.def}{\hypersetup{linktocpage}} \AfterFile{hypertex.def}{\hypersetup{linktocpage}} \usepackage{hyperref} \begin{document} \listoffigures \clearpage \begin{figure} \caption{This is an example of a fairly long figure caption, but one that does not use the optional caption argument that would allow you to write a short caption in the list of figures.} \end{figure} \end{document} \end{lstcode} If either of the \Package{hyperref} drivers \Option{hypertex} or \Option{dvips} is used, the useful \Package{hyperref} option \Option{linktocpage} will be set. However, if you create a PDF file with \mbox{pdf{\LaTeX}}, the option will not be set because then the \Package{hyperref} driver \File{hpdftex.def} will be used. This means that neither \File{hdvips.def} nor \File{hypertex.def} will be loaded. \end{Example} \iffalse% Umbruchkorrekturtext (der besser nicht mehr verwendet wird!) Furthermore\textnote{Hint!}, you can also load \Package{scrlfile} and the \DescRef{\LabelBase.cmd.AfterFile} command into a private \File{hyperref.cfg}. In this case, however, you should use \Macro{RequirePackage} instead of \Macro{usepackage} to load the package (see \cite{latex:clsguide}). In the example above, the new lines have to be inserted directly after the \Macro{ProvidesFile} line, that is, immediately before the \Option{dvips} or \Option{pdftex} options are executed.% \fi Incidentally\textnote{Hint!}, you can also load \Package{scrlfile} before \DescRef{maincls.cmd.documentclass}\IndexCmd{documentclass}. In this case, however, you should use \Macro{RequirePackage}\IndexCmd{RequirePackage} instead of \DescRef{maincls.cmd.usepackage} (see \cite{latex:clsguide}).% \EndIndexGroup \begin{Declaration} \Macro{BeforeClosingMainAux}\Parameter{commands}% \Macro{AfterReadingMainAux}\Parameter{commands}% \end{Declaration}% These commands differ in one detail from the commands explained previously. Those commands enable actions before or after loading files. That is not the case here. Package authors often want to write something to the \File{aux} file after the last document page has been shipped out. To do so, ignoring the resulting problems they create, they often use code such as the following: \begin{lstcode} \AtEndDocument{% \if@filesw \write\@auxout{% \protect\writethistoaux% }% \fi } \end{lstcode} However, this does not really solve the problem. If the last page of the document has already been shipped out before \Macro{end}\PParameter{document}, the code above will not result in any output to the \File{aux} file. If you try to fix this new problem using \Macro{immediate} just before \Macro{write}, you would have the opposite problem: if the last page has not yet been shipped out before \Macro{end}\PParameter{document}, \Macro{writethistoaux} would be written to the \File{aux} file too early. Therefore you often see solutions like: \begin{lstcode} \AtEndDocument{% \if@filesw \clearpage \immediate\write\@auxout{% \protect\writethistoaux% }% \fi } \end{lstcode} However, this solution has the disadvantage that it forces the last page to be shipped out. A command such as \begin{lstcode} \AtEndDocument{% \par\vspace*{\fill}% Note at the end of the document.\par } \end{lstcode} will no longer cause the note to appear beneath the text of the last real page of the document but at the end of one additional page. Furthermore, \Macro{writethistoaux} will again be written to the \File{aux} file one page too early. The best solution for this problem would be if you could write directly to the \File{aux} file immediately after the final \DescRef{maincls.cmd.clearpage} that is part of \Macro{end}\PParameter{document} but before closing the \File{aux} file. This is the purpose of \Macro{BeforeClosingMainAux}: \begin{lstcode} \BeforeClosingMainAux{% \if@filesw \immediate\write\@auxout{% \protect\writethistoaux% }% \fi } \end{lstcode} This will be successful even if the final \DescRef{maincls.cmd.clearpage} inside of \Macro{end}\PParameter{document} does not actually ship out any page or if \DescRef{maincls.cmd.clearpage} is used within an \Macro{AtEndDocument} command. However, there one important limitation using \Macro{BeforeClosingMainAux}: you should not use any typesetting commands inside the \PName{commands} of \Macro{BeforeClosingMainAux}! If you ignore this restriction, the result is just as unpredictable as the results of the problematic suggestions above that use \Macro{AtEndDocument}. The \Macro{AfterReadingMainAux}\ChangedAt{v3.03}{\Package{scrlfile}} command actually executes the \PName{commands} after closing and reading the \File{aux} file inside \Macro{end}\PParameter{document}. This is only useful in a few very rare cases, for example to write statistical information to the \File{log} file which is valid only after reading the \File{aux} file, or to implement additional \emph{rerun} requests. Typesetting commands are even more dangerous inside these \PName{commands} than inside the argument of \Macro{BeforeClosingMainAux}.% % \EndIndexGroup \section{Replacing Files at Input} \seclabel{replace} The previous sections in this chapter have explained commands to perform actions before or after loading a particular file, package, or class. You can also use \Package{scrlfile} to input a completely different file than the one that was requested. \begin{Declaration} \Macro{ReplaceInput}\Parameter{original file}% \Parameter{replacement file}% \end{Declaration}% This\ChangedAt{v2.96}{\Package{scrlfile}} command defines a replacement for the file specified in the first argument, \PName{original file}. If \LaTeX{} is instructed to load this file, the \PName{replacement file} will be loaded instead. The replacement-file definition affects all files loaded using \Macro{InputIfFileExists}, whether they are loaded by the user or internally by \LaTeX{}. To do so, \Package{scrlfile} redefines \Macro{InputIfFileExists}. \begin{Example} You want to input the \File{\Macro{jobname}.xua} file instead of the \File{\Macro{jobname.aux}} file. To do this, you use \begin{lstcode} \ReplaceInput{\jobname.aux}{\jobname.xua} \end{lstcode} If additionally you replace \File{\Macro{jobname}.xua} by \File{\Macro{jobname}.uxa} using \begin{lstcode} \ReplaceInput{\jobname.xua}{\jobname.uxa} \end{lstcode} then \File{\Macro{jobname}.aux} will also be replaced by \File{\Macro{jobname}.uxa}. In this way, you can process the whole replacement chain. However, a replacement that results in a loop such as \begin{lstcode} \ReplaceInput{\jobname.aux}{\jobname.xua} \ReplaceInput{\jobname.xua}{\jobname.aux} \end{lstcode} will cause a \emph{stack size error}. So it is not possible to replace a file that has already been replaced once by itself again. \end{Example} In theory, it would also be possible to use this command to replace one package or class with another. But \LaTeX{} would recognize that the requested file name does not match the name of the package or class. You can find a solution for this problem below.% \EndIndexGroup \begin{Declaration} \Macro{ReplaceClass}\Parameter{original class}% \Parameter{replacement class}% \Macro{ReplacePackage}\Parameter{original package}% \Parameter{replacement package}% \end{Declaration}% You\ChangedAt{v2.96}{\Package{scrlfile}}\textnote{Attention!} should never replace a class or package using the \DescRef{\LabelBase.cmd.ReplaceInput} command described above. Doing so would result in a \LaTeX{} warning about mismatched class or package names. Real errors are also possible if a class or package is loaded under an incorrect file name. \begin{Example} You replace the \Package{scrpage2} package with its official successor, \Package{scrlayer-scrpage}, by using \begin{lstcode}[escapechar=\$] \ReplaceInput{scrpage2.sty}{scrlayer-scrpage.sty}$\textnote{Do not try this!}$ \end{lstcode} Loading \Package{scrpage2} will then lead to the following warning: \begin{lstcode} LaTeX warning: You have requested `scrpage2', but the package provides `scrlayer-scrpage'. \end{lstcode} Users may be greatly confused by such a warning because they requested not \Package{scrlayer-scrpage} but \Package{scrpage2}, which was replaced by \Package{scrlayer-scrpage}. \end{Example} One solution to this problem is to use \Macro{ReplaceClass} or \Macro{ReplacePackage} instead of \DescRef{\LabelBase.cmd.ReplaceInput}. Note that in this case, as with \Macro{documentclass} and \Macro{usepackage}, you should give the name of the class or package and not the complete file name. The replacement class works for all classes loaded with \Macro{documentclass}, \Macro{LoadClassWithOptions}, or \Macro{LoadClass}. The replacement package works for all packages loaded with \Macro{usepackage}, \Macro{RequirePackageWithOptions}, or \Macro{RequirePackage}. Please\textnote{Attention!} note that the \PName{replacement class} or the \PName{replacement package} will be loaded with the same options that would have been passed to the \PName{original class} or \PName{original package}. If you replace a class or package with one that does not support a requested option, you will receive the usual warnings and errors. However, you can declare such missing options using \DescRef{\LabelBase.cmd.BeforeClass} or \DescRef{\LabelBase.cmd.BeforePackage}. \begin{Example} Suppose you want to replace the \Package{oldfoo} package with the \Package{newfoo} package when the former package is loaded. You can do this with \begin{lstcode} \ReplacePackage{oldfoo}{newfoo} \end{lstcode} Suppose the old package provides an \Option{oldopt} option, but the new package does not. With \begin{lstcode} \BeforePackage{newfoo}{% \DeclareOption{oldopt}{% \PackageInfo{newfoo}% {option `oldopt' not supported}% }}% \end{lstcode} you can declare this missing option for the \Package{newfoo} package. This avoids an error message when the \Package{oldfoo} package is loaded with the option that is unsupported by \Package{newfoo}. If, on the other hand, the \Package{newfoo} package supports a \Option{newopt} option that should be used instead of the \Option{oldopt} option, you can also achieved this: \begin{lstcode} \BeforePackage{newfoo}{% \DeclareOption{oldopt}{% \ExecuteOptions{newopt}% }}% \end{lstcode} You can even specify different default options that apply when loading the new package: \begin{lstcode} \BeforePackage{newfoo}{% \DeclareOption{oldopt}{% \ExecuteOptions{newopt}% }% \PassOptionsToPackage{newdefoptA,newdefoptB}% {newfoo}% } \end{lstcode} or directly: \begin{lstcode} \BeforePackage{newfoo}{% \DeclareOption{oldopt}{% \ExecuteOptions{newopt}% }% }% \PassOptionsToPackage{newdefoptA,newdefoptB}% {newfoo}% \end{lstcode} Note that in the last example, the call to \Macro{PassOptionsToPackage} occurs not within but after \Macro{BeforePackage} \end{Example} Of course, to replace classes, you must load \Package{scrlfile} before the class using \Macro{RequirePackage} instead of \Macro{usepackage}. % \EndIndexGroup \begin{Declaration} \Macro{UnReplaceInput}\Parameter{file name}% \Macro{UnReplacePackage}\Parameter{package}% \Macro{UnReplaceClass}\Parameter{class}% \end{Declaration} You\ChangedAt{v3.12}{\Package{scrlfile}} can also remove a replacement. You should remove the replacement definition for an input file using \Macro{UnReplaceInput}, for a package using \Macro{UnReplacePackage}, and for a class using \Macro{UnReplaceClass}.% \EndIndexGroup \section{Preventing File Loading} \seclabel{prevent} Classes\ChangedAt{v3.08}{\Package{scrlfile}} and packages written for use within companies or academic institutions often load many packages only because users need them frequently, not because they are required by the class or package itself. If a problem occurs with one of these automatically loaded packages, you somehow have to keep the problematic package from being loaded. Once again, \Package{scrlfile} provides a simple solution. \begin{Declaration} \Macro{PreventPackageFromLoading}\OParameter{alternate code}% \Parameter{package list}% \Macro{PreventPackageFromLoading*}\OParameter{alternate code}% \Parameter{package list} \end{Declaration} Calling this command\ChangedAt{v3.08}{\Package{scrlfile}} before loading a package with \Macro{usepackage}\IndexCmd{usepackage}, \Macro{RequirePackage}\IndexCmd{RequirePackage}, or \Macro{RequirePackageWithOptions}\IndexCmd{RequirePackageWithOptions} effectively prevents the package from being loaded if it is found in the the \PName{package list}. % \begin{Example} Suppose you work at a company where all documents are created using Latin Modern. The company class, \Class{compycls}, therefore contains these lines: \begin{lstcode} \RequirePackage[T1]{fontenc} \RequirePackage{lmodern} \end{lstcode} But now, for the first time, you want to use \XeLaTeX{} or Lua\LaTeX{}. Since the recommended \Package{fontspec} package uses Latin Modern as the default font anyway, and loading \Package{fontenc} would not be a good idea, you want to prevent both packages from being loaded. Therefore, you load the class in your own document as follows: \begin{lstcode} \RequirePackage{scrlfile} \PreventPackageFromLoading{fontenc,lmodern} \documentclass{firmenci} \end{lstcode} \end{Example} The example above also shows that you can load \Package{scrlfile} before the class. In this case, you must use \Macro{RequirePackage}\IndexCmd{RequirePackage} because \Macro{usepackage} before \Macro{documentclass} is not permitted. If you specify an empty \PName{package list} or if it contains a package that has already been loaded, \Macro{PreventPackageFromLoading} issues a warning, while\ChangedAt{v3.12}{\Package{scrlfile}} \Macro{PreventPackageFromLoading*} merely writes a note to the log file only. You\ChangedAt{v3.12}{\Package{scrlfile}} can use the optional argument to execute code instead of loading the package. But you cannot load any other packages or files inside \PName{alternate code}. To load another package, see \DescRef{\LabelBase.cmd.ReplacePackage} in \autoref{sec:scrlfile.macros} on \DescPageRef{\LabelBase.cmd.ReplacePackage}. Note also that the \PName{alternate code} will be executed several times if you try to load the package more than once!% \EndIndexGroup \begin{Declaration} \Macro{StorePreventPackageFromLoading}\Parameter{\textMacro{command}}% \Macro{ResetPreventPackageFromLoading} \end{Declaration} \Macro{StorePreventPackageFromLoad}\ChangedAt{v3.08}{\Package{scrlfile}} defines \Macro{command} to be the current list of packages that should not be loaded. In contrast, \Macro{ResetPreventPackageFromLoading}\ChangedAt{v3.08}{\Package{scrlfile}} resets the list of packages that should not be loaded. After \Macro{ResetPreventPackageFromLoading}, you can load all packages again. \begin{Example} Suppose you need to load a package inside another package and you do not want the user to be able to prevent that package from being loaded with \DescRef{\LabelBase.cmd.PreventPackageFromLoading}% \IndexCmd{PreventPackageFromLoading}. So you reset the do-not-load list before you load this package: \begin{lstcode} \ResetPreventPackageFromLoading \RequirePackage{foo} \end{lstcode} Unfortunately, from this point on the user's entire do-not-load list would be lost. To avoid this, you first store the list and then restore it later: \begin{lstcode} \newcommand*{\Users@PreventList}{}% \StorePreventPackageFromLoading\Users@PreventList \ResetPreventPackageFromLoading \RequirePackage{foo} \PreventPackageFromLoading{\Users@PreventList} \end{lstcode} Note\textnote{Attention!} that \Macro{StorePreventPackageFromLoading} defines the \Macro{Users@PreventList} macro even if it has already been defined. In other words, calling \Macro{StorePreventPackageFromLoading} overwrites existing \Macro{command} definitions without checking. Therefore this example uses \Macro{newcommand*} to get an error message if \Macro{Users@PreventList} has already been defined. \end{Example} Note that when you manipulate the list stored by \Macro{StorePreventPackageFromLoading}, you are responsible for making sure it can be restored. For example, the list elements must be separated by comma, must not contain white space or group braces, and must be fully expandable. Also note\textnote{Attention!}, that \Macro{ResetPreventPackageFromLoading} does not clear the \PName{alternate code} for a package. But this code will not be executed so long as the package is not added again to the do-not-load list.% \EndIndexGroup \begin{Declaration} \Macro{UnPreventPackageFromLoading}\Parameter{package list}% \Macro{UnPreventPackageFromLoading*}\Parameter{package list} \end{Declaration} Instead\ChangedAt{v3.12}{\Package{scrlfile}} of completely resetting the list of packages that should not be loaded, you can also specify individual packages to remove from the list. The starred version of the command also deletes the \PName{alternate code}. For example, restoring packages to the do-not-load list from a stored list will not reactivate their \PName{alternate code} in this case.% % \begin{Example} Suppose you want to prevent a \Package{foo} package from being loaded, but you do not want to execute any outdated \PName{alternate code} that may exist. Instead, only your new \PName{alternate code} should be executed. You can do this as follows: \begin{lstcode} \UnPreventPackageFromLoading*{foo} \PreventPackageFromLoading[\typeout{alternate code}]{foo} \end{lstcode} For the \Macro{UnPreventPackageFromLoading} command, it does not matter whether or not the package has been prevented from being loaded before. Of course you can also use the command to indirectly delete the \PName{alternate code} of all packages: \begin{lstcode} \StorePreventPackageFromLoading\TheWholePreventList \UnPreventPackageFromLoading*{\TheWholePreventList} \PreventPackageFromLoading{\TheWholePreventList} \end{lstcode} In this case the packages that have been prevented from being loaded are still prevented from being loaded, but their \PName{alternate code} has been deleted and will no longer be executed.% \end{Example}% \EndIndexGroup % \EndIndexGroup \endinput %%% Local Variables: %%% mode: latex %%% mode: flyspell %%% ispell-local-dictionary: "english" %%% coding: us-ascii %%% TeX-master: "../guide" %%% End: