summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-12-22 00:05:02 +0000
committerKarl Berry <karl@freefriends.org>2010-12-22 00:05:02 +0000
commit4d94830abaa19630ce446cf73cd5d2dca75dfc2f (patch)
tree17c98d7a44735f6845a3014e3a373a64b2fe2e67 /Master/texmf-dist/source/latex
parentacc3b35eec6064cf6c468aeed3a19f83813dde8d (diff)
filehook (21dec10)
git-svn-id: svn://tug.org/texlive/trunk@20822 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex')
-rw-r--r--Master/texmf-dist/source/latex/filehook/filehook.dtx275
1 files changed, 209 insertions, 66 deletions
diff --git a/Master/texmf-dist/source/latex/filehook/filehook.dtx b/Master/texmf-dist/source/latex/filehook/filehook.dtx
index 3b7544dcbed..2c385a7bac8 100644
--- a/Master/texmf-dist/source/latex/filehook/filehook.dtx
+++ b/Master/texmf-dist/source/latex/filehook/filehook.dtx
@@ -19,7 +19,7 @@
%% This work consists of the files filehook.dtx, filehook.ins
%% and the derived file filehook.sty.
%%
-%% $Id: filehook.dtx 1905 2010-12-08 18:57:34Z martin $
+%% $Id: filehook.dtx 1926 2010-12-20 23:11:20Z martin $
% \fi
%
% \iffalse
@@ -29,18 +29,19 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{filehook}
%<*package>
- [2010/12/08 v0.2 Hooks for input files]
+ [2010/12/20 v0.3 Hooks for input files]
%</package>
%
%<*driver>
-\documentclass{ltxdoc}
-\usepackage{filehook}[2010/12/06]
+\documentclass{ydoc}[2010/12/20]
+\usepackage{filehook}[2010/12/08]
\usepackage{ifpdf}
\usepackage{hyperref}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\providecommand*\pkg{\texttt}
+\listfiles
\begin{document}
\DocInput{filehook.dtx}
\PrintChanges
@@ -49,7 +50,7 @@
%</driver>
% \fi
%
-% \CheckSum{365}
+% \CheckSum{422}
%
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
@@ -70,11 +71,12 @@
%
% \changes{v0.1}{2010/04/08}{Initial version}
% \changes{v0.2}{2010/12/08}{Added support for 'memoir' class and 'scrlfile' package. Remove support for deprecated 'fink' package.}
+% \changes{v0.3}{2010/12/20}{Added hooks for package and class files. Changed a warning to an error and added the 'force' option to overwrite this.}
%
% \GetFileInfo{filehook.dtx}
%
% \DoNotIndex{\newcommand,\newenvironment}
-%
+%
% \ifpdf
% \hypersetup{%
% pdfauthor = {Martin Scharrer <martin@scharrer-online.de>},
@@ -90,7 +92,7 @@
% {\LARGE\sffamily The \emph{filehook} Package\\[\medskipamount]}
% {\large Martin Scharrer \\[\medskipamount]\normalsize
% \url{martin@scharrer-online.de}\\[.8ex]
-% \url{http://www.ctan.org/pkg/standalone/}\\[\bigskipamount]}
+% \url{http://www.ctan.org/pkg/filehook/}\\[\bigskipamount]}
% {\large Version \fileversion\ -- \filedate}\\
% \end{center}
% \vspace{1.2em}%
@@ -104,17 +106,17 @@
% These package changes some internal \LaTeX{} macros used to load input files so that they include `hooks'.
% A hook is an (internal) macro executed at specific points. Normally it is initially empty, but can be extended using
% an user level macro. The most common hook in \LaTeX{} is the `At-Begin-Document' hook. Code can be added to this hook
-% using \cs{AtBeginDocument}\marg{code}.
+% using \Macro{AtBeginDocument}{<\TeX code>}.
%
% \section{Usage}
-% This package provides three groups of hooks: for file read using |\input|, for files read using |\include| and for all read files (i.e.\ all files read using
-% |\InputIfFileExists|, which includes package and class files and files falling into the first two groups).
-% All groups include a `AtBegin' and a `AtEnd' macro. The |\include| group has also a `After' hook which
-% it is executed \emph{after} the page break (|\clearpage|) is inserted by the |\include| code. In contrast, the `AtEnd' hook is executed before the trailing page break
+% This package provides several groups of hooks: for file read using \Macro{input}, for files read using \Macro{include} and for all read files (i.e.\ all files read using
+% \Macro{InputIfFileExists}, which includes package and class files and files falling into the first two groups). Since v0.3 from 2010/12/20 there are also hooks for package and class files.
+% All groups include a `AtBegin' and a `AtEnd' macro. The \Macro{include} group has also a `After' hook which
+% it is executed \emph{after} the page break (\Macro{clearpage}) is inserted by the \Macro{include} code. In contrast, the `AtEnd' hook is executed before the trailing page break
% and the `AtBegin' hook is executed after the \emph{leading} page break.
%
-% Each group includes general and file specific hooks. The general hooks are executed for every file of this group and provide the file name as argument |#1|.
-% The file specific ones are only executed for a certain file.
+% The first three groups includes general and file specific hooks. The general hooks are executed for every file of this group and provide the file name as argument |#1|.
+% The file specific ones are only executed for a certain file. The package and class hocks are always specific to one file.
%
% The below macros can be used to add material (\TeX{} code) to the related hooks. All `AtBegin' macros will \emph{append} the code to the hooks, but the
% `AtEnd' and `After' macros will \emph{prefix} the code instead. This ensures that two different packages adding material in `AtBegin'/`AtEnd' pairs do not
@@ -123,86 +125,114 @@
% If required inside another package a different order can be enforced by using the internal hook macros shown in the implementation section.
%
% \subsection*{Include Files}
-% \DescribeMacro{\AtBeginOfIncludes}
-% \DescribeMacro{\AtEndOfIncludes}
-% \DescribeMacro{\AfterIncludes}
-% All these macro take one argument (some \TeX{} code) which is added to the specific hook for files read using |\include|. The code can use the macro argument |#1|
-% which will be expanded to the include file name, i.e.\ the hooks are macros with one argument which will be the file name.
-% As described above the `AtEnd' hook is executed before and the `After' hook is executed after the trailing |\clearpage|.
+% \DescribeMacro{\AtBeginOfIncludes}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfIncludes}{<\TeX\ code>}
+% \DescribeMacro{\AfterIncludes}{<\TeX\ code>}
+% All these macro take one argument (some \TeX{} code) which is added to the specific hook for files read using \Macro{include}.
+% The code can use the macro argument |#1|
+% which will be expanded to the include \meta{file name}, i.e.\ the hooks are macros with one argument which will be the file name.
+% As described above the `AtEnd' hook is executed before and the `After' hook is executed after the trailing \Macro{clearpage}.
% Material which should be (still) valid in the page header or footer of the last page of such an
% file should therefore use the `After' hook.
%
-% \DescribeMacro{\AtBeginOfIncludeFile}
-% \DescribeMacro{\AtEndOfIncludeFile}
-% \DescribeMacro{\AfterIncludeFile}
-% These file-specific macros take the two arguments \marg{file name}\marg{code}. The \meta{code} is only executed for the file with the given \meta{file name}
-% and only if it is read using |\include|. It is not allowed to use macro arguments inside the code.
-% The \meta{file name} should be identical to the name used for |\include| and not include the `|.tex|' extension.
+% \DescribeMacro{\AtBeginOfIncludeFile}{<file name>}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfIncludeFile}{<file name>}{<\TeX\ code>}
+% \DescribeMacro{\AfterIncludeFile}{<file name>}{<\TeX\ code>}
+% These file-specific macros take the two arguments. The \meta{code} is only executed for the file with the given \meta{file name}
+% and only if it is read using \Macro{include}. It is not allowed to use macro arguments inside the code.
+% The \meta{file name} should be identical to the name used for \Macro{include} and not include the `|.tex|' extension.
%
% \subsection*{Input Files}
%
-% \DescribeMacro{\AtBeginOfInputs}
-% \DescribeMacro{\AtEndOfInputs}
-% Like the |\...OfIncludes|\marg{code} macros above, just for file read using |\input|. Again, the macro argument |#1| can be used inside the \meta{code} and
-% will be expanded to the file name.
+% \DescribeMacro{\AtBeginOfInputs}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfInputs}{<\TeX\ code>}
+% Like the \Macro{...OfIncludes}\marg{code} macros above, just for file read using \Macro{input}. Again, the macro argument |#1| can be used inside the \meta{code} and
+% will be expanded to the <file name>.
%
-% \DescribeMacro{\AtBeginOfInputFile}
-% \DescribeMacro{\AtEndOfInputFile}
-% Like the |\...OfIncludeFile|\marg{file name}\marg{code} macros above, just for file read using |\input|. Here the \meta{file name} should include the file
+% \DescribeMacro{\AtBeginOfInputFile}{<file name>}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfInputFile}{<file name>}{<\TeX\ code>}
+% Like the \Macro{...OfIncludeFile}\marg{<file name>}\marg{code} macros above, just for file read using \Macro{input}. Here the \meta{file name} should include the file
% extension! The \meta{code} must not include any macro arguments (|#1|).
%
% \subsection*{All Files}
%
-% \DescribeMacro{\AtBeginOfFiles}
-% \DescribeMacro{\AtEndOfFiles}
-% These macros add the given \marg{code} to two hooks executed for all files read using the |\InputIfFileExists| macro. This macro is used internally by the
-% |\input|, |\include| and |\usepackage|/|\RequirePackage| macros. Packages and classes might use it to include additional or auxiliary files.
-% Authors can exclude those files from the hooks by using |\IfFileExists|\marg{file name}|{\@input\@filef@und}{}| instead.
+% \DescribeMacro{\AtBeginOfFiles}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfFiles}{<\TeX\ code>}
+% These macros add the given \marg{code} to two hooks executed for all files read using the \Macro{InputIfFileExists} macro. This macro is used internally by the
+% \Macro{input}, \Macro{include} and \Macro{usepackage}/\Macro{RequirePackage} macros. Packages and classes might use it to include additional or auxiliary files.
+% Authors can exclude those files from the hooks by using \Macro{IfFileExists}{<file name>}|{\@input\@filef@und}{}| instead.
%
-% \DescribeMacro{\AtBeginOfFile}
-% \DescribeMacro{\AtEndOfFile}
-% Like the |\...OfIncludeFile|\marg{file name}\marg{code} macros above, just for `all' read files. Here the \meta{file name} should include the file
+% \DescribeMacro{\AtBeginOfFile}{<file name with extension>}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfFile}{<file name with extension>}{<\TeX\ code>}
+% Like the {\expandafter\Macro\csname...OfIncludeFile\endcsname{<file name>}{<\TeX\ code>}} macros above, just for `all' read files. Here the \meta{file name} should include the file
% extension! The \meta{code} must not include any macro arguments (|#1|).
%
+% The `all files' hooks are closer to the file content than the \Macro{input} and \Macro{include} hook, i.e.\ the \Macro{AtBeginOfFiles} comes \emph{after} the \Macro{AtBeginOfIncludes} and
+% the \Macro{AtEndOfFiles} comes \emph{before} the \Macro{AtEndOfIncludes} hook.
+%
+%
+% \subsection*{Package Files}
+%
+% \DescribeMacro{\AtBeginOfPackageFile}{<package name>}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfPackageFile}*{<package name>}{<\TeX\ code>}
+% This macros install the given \MacroArgs<\TeX\ code> in the `AtBegin' and `AtEnd' hooks of the given package file.
+% The \Macro\AtBeginOfPackageFile simply executes \Macro\AtBeginOfFile{<package name>.sty}{<\TeX code>}.
+% Special care is taken to ensure that the `AtEnd' code is executed \emph{after} any code installed by the package itself
+% using the \LaTeX\ macro \Macro\AtEndOfPackage.
+% If the starred version is used and the package is already loaded the code
+% is executed right away.
+%
+%
+% \subsection*{Class Files}
+%
+% \DescribeMacro{\AtBeginOfClassFile}{<class name>}{<\TeX\ code>}
+% \DescribeMacro{\AtEndOfClassFile}*{<class name>}{<\TeX\ code>}
+% This macros install the given \MacroArgs<\TeX\ code> in the `AtBegin' and `AtEnd' hooks of the given class file.
+% They work with classes loaded using \Macro\LoadClass, \Macro\LoadClassWithOptions and also \Macro\documentclass.
+% However, in the latter case |filehook| must be loaded using \Macro\RequirePackage beforehand.
+% The \Macro\AtBeginOfClassFile simply executes \Macro\AtBeginOfFile{<class name>.cls}{<\TeX code>}.
+% Special care is taken to ensure that the `AtEnd' code is executed \emph{after} any code installed by the class itself
+% using the \LaTeX\ macro \Macro\AtEndOfPackage.
+% If the starred version is used and the class is already loaded the code
+% is executed right away.
%
-% The `all files' hooks are closer to the file content than the |\input| and |\include| hook, i.e.\ the \cs{AtBeginOfFiles} comes after the \cs{AtBeginOfIncludes} and
-% the \cs{AtEndOfFiles} comes before the \cs{AtEndOfIncludes} hook.
%
% \StopEventually{}
%
% \section{Compatibility Issues with other Packages}
-% The |filehook| package might clash with other packages or classes which also redefine |\InputIfFileExists|.
+% The |filehook| package might clash with other packages or classes which also redefine \Macro{InputIfFileExists}.
% Special compatibility code is in place for the known packages listed below (in their current implementation).
-% If any other unknown definition is found a warning will be printed and the macro will be overwritten.
-% Any previous modifications will be lost, which will most likely break the other package.
+% If any other unknown definition is found an error will be raised. The package option `|force|' can be used
+% to prevent this and to force the redefinition of this macro.
+% Then any previous modifications will be lost, which will most likely break the other package.
% Please do not hesitate to inform the author of |filehook| of any encountered problems with other packages.
%
% \subsection*{jmlrbook}
-% The |jmlrbook| class from the |jmlr| bundle temporary redefines |\InputIfFileExists| to import papers.
+% The |jmlrbook| class from the |jmlr| bundle temporary redefines \Macro{InputIfFileExists} to import papers.
% The `original' definition is saved away at load time of the package and is used internally by the new definition.
% This means that the hooks will not be active for this imported files because |filehook| is loaded after the class.
% This should not affect its normal usage.
-% Note that, in theory, the package could be loaded before |\documentclass| using |\RequirePackage| to enable the file hooks also for these files.
+% Note that, in theory, the package could be loaded before \Macro{documentclass} using \Macro{RequirePackage} to enable the file hooks also for these files.
%
% \subsection*{memoir}
-% The |memoir| class redefines |\InputIfFileExists| to add own hooks identical to the |At...OfFiles| hooks (there called |\AtBeginFile| and |\AtEndFile|).
+% The |memoir| class redefines \Macro{InputIfFileExists} to add own hooks identical to the |At...OfFiles| hooks (there called \Macro{AtBeginFile} and \Macro{AtEndFile}).
% This hooks will be moved to the corresponding ones of |filehook| and will keep working as normal.
%
% \subsection*{scrlfile}
-% The |scrlfile| package from the \emph{koma-script} bundle redefines |\InputIfFileExists| to allow file name aliases and to also add hooks.
+% The |scrlfile| package from the \emph{koma-script} bundle redefines \Macro{InputIfFileExists} to allow file name aliases and to also add hooks.
% If required it should be loaded before |filehook|, which will add its hooks correctly to the modified definition.
%
% \subsection*{fink}
% The |filehook| and |currfile| packages where written as replacements for the |fink| package, where |filehook| provides the necessary hooks for |currfile|.
% The |fink| package has now been deprecated in favour of |currfile| and should not be used anymore. The |fink| compatibility code has been removed from |filehook|
-% and both cannot be used successfully together as both redefine the |\InputIfFileExists| macro.
+% and both cannot be used successfully together as both redefine the \Macro{InputIfFileExists} macro.
%
% \subsection*{listings}
-% The \pkg{listings} package uses |\input| inside \cs{lstinputlisting}. Therefore the |InputFile|(|s|) and |File|(|s|) hooks are also triggered for these files.
+% The \pkg{listings} package uses \Macro{input} inside \Macro{lstinputlisting}. Therefore the |InputFile|(|s|) and |File|(|s|) hooks are also triggered for these files.
% Please note that this hooks are executing inside a verbatim environment. While the code in the hook is not affected (because it was added outside the verbatim
-% environment), any further code read using any input macro (|\input|, |\@input|, |\@@input| (\TeX's |\input|), \ldots) will be processed verbatim and typeset
+% environment), any further code read using any input macro (\Macro{input}, \Macro{@input}, \Macro{@@input} (\TeX's \Macro{input}), \ldots) will be processed verbatim and typeset
% as part of the listing. A known package suffering from this is \pkg{svn-multi} which loads |.svx| files for every |.tex| file.
-% A workaround for this issue is to temporally redefine |\input| to |\@input| for \cs{lstinputlisting}: |{\let\input\@input\lstinputlisting{...}}|.
+% A workaround for this issue is to temporally redefine \Macro{input} to \Macro{@input} for \Macro{lstinputlisting}: |{\let\input\@input\lstinputlisting{...}}|.
%
%
% \section{Implementation}\label{sec:impl}
@@ -211,8 +241,15 @@
%<*package>
% \fi
%
+% \subsection{Options}
+% \begin{macrocode}
+\newif\iffilehook@force
+\DeclareOption{force}{\filehook@forcetrue}
+\ProcessOptions\relax
+% \end{macrocode}
+%
% \subsection{Installation of Hooks}
-% The \cs{@input@} and \cs{@iinput} macros from |latex.ltx| are redefined to install the hooks.
+% The \Macro{@input@} and \Macro{@iinput} macros from |latex.ltx| are redefined to install the hooks.
%
% First the original definitions are saved away.
% \begin{macrocode}
@@ -221,10 +258,10 @@
% \end{macrocode}
%
% \begin{macro}{\@input@}
-% This macro is redefined for the |\include| file hooks.
-% Checks if the next command is |\clearpage| which indicates that we are inside \cs{@include}.
+% This macro is redefined for the \Macro{include} file hooks.
+% Checks if the next command is \Macro{clearpage} which indicates that we are inside \Macro{@include}.
% If so the hooks are installed, otherwise the original macro is used unchanged.
-% For the `after' hook an own |\clearpage| is inserted and the original one is gobbled.
+% For the `after' hook an own \Macro{clearpage} is inserted and the original one is gobbled.
%
% \begin{macrocode}
\def\@input@#1{%
@@ -242,7 +279,7 @@
% \end{macro}
%
% \begin{macro}{\@iinput}
-% This macro is redefined for the |\input| file hooks.
+% This macro is redefined for the \Macro{input} file hooks.
% it simply surrounds the original macro with the hooks.
% \begin{macrocode}
\def\@iinput#1{%
@@ -256,7 +293,7 @@
% \begin{macro}{\InputIfFileExists}
% This macro is redefined for the general file hooks.
% The original definition is checked but is not saved away and called by the new definition, because
-% of the existing complexity. The hooks must be places around the actual input macro (|\@@input|).
+% of the existing complexity. The hooks must be places around the actual input macro (\Macro{@@input}).
%
% Alternatives definitions of \cs{InputIfFileExists} are defined here for comparison.
% This is done inside a group to keep them only temporary.
@@ -298,9 +335,9 @@
% \end{macrocode}
%
% If the |scrlfile| package definition is detected the |filehook|s are added
-% to that definition. Unfortunately the |\scr@load@hook{before}| hook is placed \emph{before}
+% to that definition. Unfortunately the \Macro{scr@load@hook}{before} hook is placed \emph{before}
% not after the |#2\@addtofilelist{#1}| code. Otherwise the |filehook|s could simply be added to these hooks.
-% Note that should |scrlfile| ever change its |\InputIfFileExists| macro this code will not be executed and
+% Note that should |scrlfile| ever change its \Macro{InputIfFileExists} macro this code will not be executed and
% the general clause below will kick in.
% \begin{macrocode}
\ifx\InputIfFileExists\scrlfile@InputIfFileExists
@@ -350,9 +387,25 @@
% \begin{macrocode}
\ifx\InputIfFileExists\latex@InputIfFileExists
\else
- \PackageWarning{filehook}
- {Changed definition of \string\InputIfFileExists\space detected!^^J%
- This macro will be redefined and this might break other packages or code.}%
+ \@ifpackageloaded{scrlfile}{%
+ \PackageWarning{filehook}{Detected 'scrlfile' package with unknown definition of \string\InputIfFileExists}%
+ }{}%
+
+ \@ifclassloaded{memoir}{%
+ \PackageWarning{filehook}{Detected 'memoir' class with unknown definition of \string\InputIfFileExists}%
+ }{}%
+
+ \iffilehook@force
+ \PackageWarning{filehook}
+ {Changed definition of \string\InputIfFileExists\space detected!^^J%
+ The 'force' option is in effect and therefore this macros is redefined.
+ This might break other packages or code}%
+ \else
+ \PackageError{filehook}
+ {Changed definition of \string\InputIfFileExists\space detected!^^J%
+ Use the 'force' option to force the redefinition of this macro.^^J%
+ This might break other packages or code}%
+ \fi
\fi
\fi
@@ -448,7 +501,7 @@
% \end{macro}
%
% \begin{macro}{\filehook@appendwarg}
-% Appends code with one macro argument. The |\@tempa| intermediate step is required because of the
+% Appends code with one macro argument. The \Macro{@tempa} intermediate step is required because of the
% included |##1| which wouldn't correctly expand otherwise.
% \begin{macrocode}
\long\def\filehook@appendwarg#1#2{%
@@ -620,6 +673,96 @@
% \end{macro}
%
%
+% \begin{macro}{\AtBeginOfPackageFile}[1]{package name}
+% Simply add the package extension and calls the general macro.
+% \begin{macrocode}
+\newcommand*\AtBeginOfPackageFile[1]{%
+ \AtBeginOfFile{#1.\@pkgextension}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\AtEndOfPackageFile}
+% \begin{macrocode}
+\newcommand*\AtEndOfPackageFile{%
+ \@ifnextchar*\AtEndOfPackageFile@star\AtEndOfPackageFile@normal
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AtEndOfPackageFile@star}[2]{package name}{code}
+% If the package is already loaded the code is executed right away.
+% Otherwise it is installed normally.
+% \begin{macrocode}
+\def\AtEndOfPackageFile@star*#1#2{%
+ \@ifpackageloaded{#1}%
+ {#2}%
+ {\AtEndOfPackageFile@normal{#1}{#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AtEndOfPackageFile@normal}[2]{package name}{code}
+% Installs the code at the end of the package file inside a \Macro\AtEndOfPackage
+% command to ensure it is executed after any \Macro\AtEndOfPackage code installed
+% by the package itself.
+%
+% Note if the package was already loaded or is not loaded at all the installed
+% code is never executed.
+% \begin{macrocode}
+\def\AtEndOfPackageFile@normal#1#2{%
+ \AtEndOfFile{#1.\@pkgextension}{\AtEndOfPackage{#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\AtBeginOfClassFile}[1]{class name}
+% Simply add the class extension and calls the general macro.
+% \begin{macrocode}
+\newcommand*\AtBeginOfClassFile[1]{%
+ \AtBeginOfFile{#1.\@clsextension}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\AtEndOfClassFile}[2]{class name}{code}
+% \begin{macrocode}
+\newcommand*\AtEndOfClassFile{%
+ \@ifnextchar*\AtEndOfClassFile@star\AtEndOfClassFile@normal
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AtEndOfClassFile@star}[2]{class name}{code}
+% If the class is already loaded the code is executed right away.
+% Otherwise it is installed normally.
+% \begin{macrocode}
+\def\AtEndOfClassFile@star*#1#2{%
+ \@ifclassloaded{#1}%
+ {#2}%
+ {\AtEndOfClassFile@normal{#1}{#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AtEndOfClassFile@normal}[2]{class name}{code}
+% Installs the code at the end of the class file inside a \Macro\AtEndOfClass
+% command to ensure it is executed after any \Macro\AtEndOfClass code installed
+% by the class itself.
+%
+% Note if the class was already loaded or is not loaded at all the installed
+% code is never executed.
+% \begin{macrocode}
+\def\AtEndOfClassFile@normal#1#2{%
+ \AtEndOfFile{#1.\@clsextension}{\AtEndOfClass{#2}}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
% \iffalse
%</package>
% \fi