summaryrefslogtreecommitdiff
path: root/macros/latex/base/ltclass.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/base/ltclass.dtx
Initial commit
Diffstat (limited to 'macros/latex/base/ltclass.dtx')
-rw-r--r--macros/latex/base/ltclass.dtx2500
1 files changed, 2500 insertions, 0 deletions
diff --git a/macros/latex/base/ltclass.dtx b/macros/latex/base/ltclass.dtx
new file mode 100644
index 0000000000..2f19c74352
--- /dev/null
+++ b/macros/latex/base/ltclass.dtx
@@ -0,0 +1,2500 @@
+% \iffalse meta-comment
+%
+% Copyright 1993-2018
+% The LaTeX3 Project and any individual authors listed elsewhere
+% in this file.
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% https://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.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%%% From File: ltclass.dtx
+%
+%<*driver>
+% \fi
+\ProvidesFile{ltclass.dtx}
+ [2018/05/29 v1.2j LaTeX Kernel (Class & Package Interface)]
+% \iffalse
+\documentclass{ltxdoc}
+\GetFileInfo{ltclass.dtx}
+\begin{document}
+\title{The main structure of documents}
+\author{Frank Mittelbach\and Chris Rowley\and Alan Jeffrey\and
+ David Carlisle}
+\date{\filedate}
+ \MaintainedByLaTeXTeam{latex}
+ \maketitle
+ \DocInput{\filename}
+\end{document}
+%</driver>
+% \fi
+%
+% \iffalse
+% (C) Copyright Frank Mittelbach, Chris Rowley,
+% Alan Jeffrey and David Carlisle 1993-1998.
+% All rights reserved.
+% \fi
+%
+%
+% \changes{v0.2f}{1993/11/22}
+% {\cs{@unknownversion} removed}
+% \changes{v1.0j}{1994/10/18}
+% {Move \cs{listfiles} to ltfiles.dtx}
+% \changes{v1.0f}{1994/05/22}{Use new warning and error commands}
+% \changes{v1.0l}{1994/11/17}{\cs{@tempa} to \cs{reserved@a}}
+% \changes{v1.0z}{1998/03/21}{Added to documentation of filecontents}
+% \changes{v1.1c}{1998/08/17}{(RmS) Minor documentation fixes.}
+%
+%
+% \section{Introduction}
+%
+% This file implements the following declarations, which replace
+% |\documentstyle| in \LaTeXe\ documents.
+%
+% Note that old documents containing |\documentstyle| will be run using
+% a compatibility option---thus keeping everyone happy, we hope!
+%
+% The overall idea is that there are two types of `style files':
+% `class files' which define elements and provide a default formatting
+% for them; and `packages' which provide extra functionality. One
+% difference between \LaTeXe\ and \LaTeX2.09 is that \LaTeXe\ packages
+% may have options. Note that options to classes packages may be
+% implemented such that they input files, but these file names are not
+% necessarily directly related to the option name.
+%
+% \section{User interface}
+%
+% |\documentclass[|\meta{main-option-list}|]{|^^A
+% \meta{class}|}[|\meta{version}|]|
+%
+% There must be exactly one such declaration, and it must come first.
+% The \meta{main-option-list} is a list of options which can modify the
+% formatting of elements which are defined in the \meta{class} file
+% as well as in all following |\usepackage| declarations (see below).
+% The \meta{version} is a version number, beginning with a date in the
+% format |YYYY/MM/DD|. If an older version of the class is found, a
+% warning is issued.
+%
+% \bigskip
+%
+% |\documentstyle[|\meta{main-option-list}|]{|^^A
+% \meta{class}|}[|\meta{version}|]|
+%
+% The |\documentstyle| declaration is kept in order to maintain upward
+% compatibility with \LaTeX2.09 documents. It is similar to
+% |\documentclass|, but it causes all options in
+% \meta{main-option-list} that the \meta{class} does not use to be
+% passed to |\RequirePackage| after the options have been processed.
+% This maintains compatibility with the 2.09 behaviour. Also a flag is
+% set to indicate that the document is to be processed in \LaTeX2.09
+% compatibility mode. As far as most packages are concerned, this
+% only affects the warnings and errors \LaTeX\ generates. This flag
+% does affect the definition of font commands, and |\sloppy|.
+%
+% \bigskip
+%
+% |\usepackage[|\meta{package-option-list}|]{|^^A
+% \meta{package-list}|}[|\meta{version}|]|
+%
+% There can be any number of these declarations. All packages in
+% \meta{package-list} are called with the same options.
+%
+% Each \meta{package} file defines new elements (or modifies those
+% defined in the \meta{class}), and thus extends the range of documents
+% which can be processed.
+% The \meta{package-option-list} is a list of options which can modify
+% the formatting of elements defined in the \meta{package} file.
+% The \meta{version} is a version number, beginning with a date in the
+% format |YYYY/MM/DD|. If an older version of the package is found, a
+% warning is issued.
+%
+% Each package is loaded only once. If the same package is requested
+% more than once, nothing happens, unless the package has been requested
+% with options that were not given the first time it was loaded, in
+% which case an error is produced.
+%
+% As well as processing the options given in the
+% \meta{package-option-list}, each package processes the
+% \meta{main-option-list}. This means that options that affect all
+% of the packages can be given globally, rather than repeated for every
+% package.
+%
+% Note that class files have the extension |.cls|, packages have the
+% extension |.sty|.
+%
+% \DescribeEnv{filecontents}
+% The environment |filecontents| is intended for passing the contents
+% of packages, options, or other files along with a document in a
+% single file.
+% It has one argument, which is the name of the file to create. If that
+% file already exists (maybe only in the current directory if the OS
+% supports a notion of a `current directory' or `default directory')
+% then nothing happens
+% (except for an information message) and the body of the environment
+% is bypassed. Otherwise, the body of the environment is written
+% verbatim to the file name given as the first argument, together with
+% some comments about how it was produced.
+%
+% The environment is allowed only before |\documentclass| to ensure
+% that all packages or options necessary for this particular run are
+% present when needed. The begin and end tags should each be on a
+% line by itself. There is also a star-form; this does not write
+% extra comments into the file.
+%
+% \subsection{Option processing}
+%
+% When the options are processed, they are divided into two types: {\em
+% local\/} and {\em global}:
+% \begin{itemize}
+%
+% \item For a class, the options in the |\documentclass| command are
+% local.
+%
+% \item For a package, the options in the |\usepackage| command are
+% local, and the options in the |\documentclass| command are global.
+%
+% \end{itemize}
+% The options for |\documentclass| and |\usepackage|
+% are processed in the following way:
+% \begin{enumerate}
+%
+% \item The local and global options that have been declared
+% (using |\DeclareOption| as described below) are processed
+% first.
+%
+% In the case of |\ProcessOptions|, they are processed in the order
+% that they were declared in the class or package.
+%
+% In the case of |\ProcessOptions*|, they are processed in the order
+% that they appear in the option-lists. First the global options, and
+% then the local ones.
+%
+% \item Any remaining local options are dealt with using the default
+% option (declared using the |\DeclareOption*| declaration described
+% below). For document classes, this usually does nothing, but
+% records the option on a list of unused options.
+% For packages, this usually produces an error.
+%
+% \end{enumerate}
+% Finally, when |\begin{document}| is reached, if there are any global
+% options which have not been used by either the class or any package,
+% the system will produce a warning.
+%
+%
+% \section{Class and Package interface}
+%
+% \subsection{Class name and version}
+%
+% \DescribeMacro\ProvidesClass
+% A class can identify itself with the
+% |\ProvidesClass{|\meta{name}|}[|\meta{version}|]| command. The
+% \meta{version} should begin with a date in the format |YYYY/MM/DD|.
+%
+% \subsection{Package name and version}
+%
+% \DescribeMacro\ProvidesPackage
+% A package can identify itself with the
+% |\ProvidesPackage|\marg{name}\oarg{version} command. The
+% \meta{version} should begin with a date in the format |YYYY/MM/DD|.
+%
+% \subsection{Requiring other packages}
+%
+% \DescribeMacro\RequirePackage
+% Packages or classes can load other packages using\\
+% |\RequirePackage|\oarg{options}\marg{name}\oarg{version}.\\
+% If the package has already been loaded, then nothing happens unless
+% the requested options are not a subset of the options with which it
+% was loaded, in which case an error is called.
+%
+% \DescribeMacro\LoadClass
+% Similar to |\RequirePackage|, but for classes, may not be used in
+% package files.
+%
+% \DescribeMacro\PassOptionsToPackage
+% Packages can pass options to other packages using:\\
+% |\PassOptionsToPackage{|\meta{options}|}{|\meta{package}|}|.\\
+% \DescribeMacro\PassOptionsToClass
+% This adds the \meta{options} to the options list of any future
+% |\RequirePackage| or |\usepackage| command. For example:
+% \begin{verbatim}
+% \PassOptionsToPackage{foo,bar}{fred}
+% \RequirePackage[baz]{fred}\end{verbatim}
+% is the same as:
+% \begin{verbatim}
+% \RequirePackage[foo,bar,baz]{fred}\end{verbatim}
+%
+% \DescribeMacro\LoadClassWithOptions
+% |\LoadClassWithOptions|\marg{name}\oarg{version}:\\
+% This is similar to
+% |\LoadClass|, but it always calls class \meta{name} with
+% exactly the same option list that is being used by the current class,
+% rather than an option explicitly supplied or passed on by
+% |\PassOptionsToClass|.
+% \DescribeMacro\RequirePackageWithOptions
+% |\RequirePackageWithOptions| is the analogous command for packages.
+%
+% This is mainly intended to allow one class to simply build on another,
+% for example:
+%\begin{verbatim}
+% \LoadClassWithOptions{article}
+%\end{verbatim}
+%
+% This should be contrasted with the slightly different construction
+%\begin{verbatim}
+% \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
+% \ProcessOptions
+% \LoadClass{article}
+%\end{verbatim}
+%
+% As used here, the effects are more or less the same, but the
+% version using |\LoadClassWithOptions| is slightly quicker
+% (and less to type).
+% If, however, the class declares options of its own then
+% the two constructions are different; compare, for example:
+%\begin{verbatim}
+% \DeclareOption{landscape}{...}
+% \ProcessOptions
+% \LoadClassWithOptions{article}
+%\end{verbatim}
+% with:
+%\begin{verbatim}
+% \DeclareOption{landscape}{...}
+% \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
+% \ProcessOptions
+% \LoadClass{article}
+%\end{verbatim}
+% In the first case, the \textsf{article} class will be called with
+% option |landscape| precisely when the current class is called with
+% this option; but in the second example it will
+% not as in that case \textsf{article} is only passed options by the
+% default option handler, which is not used for |landscape| as that
+% option is explicitly declared.
+%
+% \DescribeMacro\@ifpackageloaded
+% To find out if a package has already been loaded, use\\
+% \DescribeMacro\@ifclassloaded
+% |\@ifpackageloaded{|\meta{package}|}{|\meta{true}|}{|\meta{false}|}|.
+%
+% \DescribeMacro\@ifpackagelater
+% \changes{v1.1i}{2013/07/07}{Correctly describe how the date in
+% \cs{@ifpackagelater} is used}
+% To find out if a package has already been loaded with a version
+% equal to or more
+% recent than \meta{version}, use\\
+% \DescribeMacro\@ifclasslater
+% |\@ifpackagelater{|\meta{package}|}{|\meta{version}|}{|^^A
+% \meta{true}|}{|\meta{false}|}|.
+%
+% \DescribeMacro\@ifpackagewith
+% To find out if a package has already been loaded with at least the
+% options \meta{options}, use
+% \DescribeMacro\@ifclasswith
+% |\@ifpackagewith{|\meta{package}|}{|\meta{options}|}{|^^A
+% \meta{true}|}{|\meta{false}|}|.
+%
+% There exists one package that can't be tested with the above
+% commands: the \texttt{fontenc} package pretends that it was never
+% loaded to allow for repeated reloading with different options (see
+% \texttt{ltoutenc.dtx} for details).
+%
+%
+% \subsection{Declaring new options}
+%
+% Options for classes and packages are built using the same macros.
+%
+% \DescribeMacro\DeclareOption To define a builtin option, use
+% |\DeclareOption{|\meta{name}|}{|\meta{code}|}|.
+%
+% \DescribeMacro{\DeclareOption*} To define the default action to
+% perform for local options which have not been declared, use
+% |\DeclareOption*{|\meta{code}|}|.
+%
+% {\em Note\/}: there should be no use of\\
+% |\RequirePackage|, |\DeclareOption|, |\DeclareOption*| or
+% |\ProcessOptions|\\
+% inside |\DeclareOption| or |\DeclareOption*|.
+%
+% Possible uses for |\DeclareOption*| include:
+%
+% |\DeclareOption*{}|\\
+% Do nothing. Silently accept unknown options. (This suppresses the
+% usual warnings.)
+%
+% |\DeclareOption*{\@unkownoptionerror}|\\
+% Complain about unknown local options. (The initial setting for
+% package files.)
+%
+% |\DeclareOption*{\PassOptionsToPackage{\CurrentOption}|^^A
+% |{|\meta{pkg-name}|}|\\
+% Handle the the current option by passing it on to the package
+% \meta{pkg-name}, which will presumably be loaded via
+% |\RequirePackage| later in the file. This is useful for building
+% `extension' packages, that perhaps handle a couple of new options,
+% but then pass everything else on to an existing package.
+%
+% |\DeclareOption*{\InputIfFileExists{xx-\CurrentOption.yyy}%|\\
+% | {}%|\\
+% | {\OptionNotUsed}}|\\
+% Handle the option foo by loading the file |xx-foo.yyy| if it
+% exists, otherwise do nothing, but declare that the option was not
+% used.
+% Actually the |\OptionNotUsed| declaration is only needed if this is
+% being used in class files, but does no harm in package files.
+%
+%
+% \subsection{Safe Input Macros}
+% \DescribeMacro{\InputIfFileExists}
+% |\InputIfFileExists{|\meta{file}|}{|\meta{then}|}{|\meta{else}|}|\\
+% Inputs \meta{file} if it exists. Immediately before the input,
+% \meta{then} is executed. Otherwise \meta{else} is executed.
+%
+% \DescribeMacro{\IfFileExists}
+% As above, but does not input the file.
+%
+% One thing you might like to put in the \meta{else} clause is
+%
+% \DescribeMacro{\@missingfileerror}
+% This starts an interactive request for a filename, supplying default
+% extensions. Just hitting return causes the whole input to be skipped
+% and entering |x| quits the current run,
+%
+% \DescribeMacro{\input}
+% This has been redefined from the \LaTeX2.09 definition, in terms of
+% the new commands |\InputIfFileExists| and |\@missingfileerror|.
+%
+%
+% \DescribeMacro{\listfiles} Giving this declaration in the preamble
+% causes a list of all files input via the `safe input' commands to be
+% listed at the end. Any strings specified in the optional argument to
+% |\ProvidesPackage| are listed alongside the file name. So files in
+% standard (and other non-standard) distributions can put informative
+% strings in this argument.
+%
+% \StopEventually{}
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*2ekernel>
+% \end{macrocode}
+%
+%
+% \changes{v0.2g}{1993/11/23}
+% {Various macros now moved to latex.tex.}
+% \changes{v0.2g}{1993/11/23}
+% {Warnings and errors now directly coded.}
+% \changes{v0.2h}{1993/11/28}
+% {Primitive filenames now terminated by space not \cs{relax}.}
+% \changes{v0.2h}{1993/11/28}
+% {Directory syntax checing moved to dircheck.dtx}
+% \changes{v0.2h}{1993/11/28}
+% {Assorted commands now in the kernel removed.}
+% \changes{v0.2i}{1993/12/03}
+% {\cs{@onlypreamble}: Many commands declared.}
+% \changes{v0.2i}{1993/12/03}
+% {Removed obsolete \cs{@documentclass}}
+% \changes{v0.2o}{1993/12/13}
+% {Removed setting \cs{errorcontextlines}\ (now in latex.tex)}
+% \changes{v0.2p}{1993/12/15}
+% {Removed extra `.'s from \cs{@@warning}s}
+% \changes{v0.2s}{1994/01/17}
+% {Added many more \cs{@onlypreamble} commands}
+% \changes{v0.2s}{1994/01/17}
+% {Wrapped long lines to column 72}
+% \changes{v0.3a}{1994/03/02}
+% {Remove need for driver file}
+% \changes{v0.3b}{1994/03/08}
+% {Modify driver code into `new style'}
+% \changes{v0.3c}{1994/03/12}
+% {Change name from docclass to ltclass}
+% \changes{v0.3h}{1994/04/25}
+% {Removed spurious extra `.'s at the end of error messages}
+% \changes{v1.0a}{1994/04/29}
+% {Change version number to 1 (no other change)}
+% \changes{v1.0k}{1994/11/03}
+% {Move \cs{@missingfileerror} to ltfiles}
+%
+% \begin{macro}{\if@compatibility}
+% The flag for compatibility mode.
+% \begin{macrocode}
+\newif\if@compatibility
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@documentclasshook}
+% The hook called after the first |\documentclass| command. By
+% default this checks to see if |\@normalsize| is undefined, and if
+% so, sets it to |\normalsize|.
+% \changes{v0.2q}{1993/12/17}
+% {Macro added}
+% \changes{v0.2z}{1994/02/10}
+% {Changed the name from \cs{@compatibility} to
+% \cs{@documentclasshook}, and added the check for whether
+% \cs{@normalsize} has been defined. ASAJ.}
+% \begin{macrocode}
+\def\@documentclasshook{%
+ \ifx\@normalsize\@undefined
+ \let\@normalsize\normalsize
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@declaredoptions}
+% This list is automatically built by |\DeclareOption|.
+% It is the list of options (separated by commas) declared in
+% the class or package file and it defines the order in which the
+% the corresponding |\ds@|\meta{option} commands are executed.
+% All local \meta{option}s which are not declared will be processed
+% in the order defined by the optional argument of |\documentclass|
+% or |\usepackage|.
+% \begin{macrocode}
+\let\@declaredoptions\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@classoptionslist}
+% List of options of the main class.
+% \changes{v1.0u}{1996/07/26}{made only preamble}
+% \begin{macrocode}
+\let\@classoptionslist\relax
+\@onlypreamble\@classoptionslist
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@unusedoptionlist}
+% \changes{v1.0u}{1996/07/26}{made only preamble}
+% List of options of the main class that haven't been declared or
+% loaded as class option files.
+% \begin{macrocode}
+\let\@unusedoptionlist\@empty
+\@onlypreamble\@unusedoptionlist
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\CurrentOption}
+% Name of current package or option.
+% \changes{v0.2c}{1993/11/17}
+% {Name changed from \cs{@curroption}}
+% \begin{macrocode}
+\let\CurrentOption\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@currname}
+% Name of current package or option.
+% \begin{macrocode}
+\let\@currname\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@currext}
+% The current file extension.
+% \changes{v0.2a}{1993/11/14}{Name changed from \cs{@currextension}}
+% \begin{macrocode}
+\global\let\@currext=\@empty
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@clsextension}
+% \begin{macro}{\@pkgextension}
+% The two possible values of |\@currext|.
+% \begin{macrocode}
+\def\@clsextension{cls}
+\def\@pkgextension{sty}
+\@onlypreamble\@clsextension
+\@onlypreamble\@pkgextension
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@pushfilename}
+% \begin{macro}{\@popfilename}
+% \begin{macro}{\@currnamestack}
+% Commands to push and pop the file name and extension. \\
+% |#1| current name. \\
+% |#2| current extension. \\
+% |#3| current catcode of |@|. \\
+% |#4| Rest of the stack.
+% \begin{macrocode}
+\def\@pushfilename{%
+ \xdef\@currnamestack{%
+ {\@currname}%
+ {\@currext}%
+ {\the\catcode`\@}%
+ \@currnamestack}}
+\@onlypreamble\@pushfilename
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil}
+\@onlypreamble\@popfilename
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@p@pfilename#1#2#3#4\@nil{%
+ \gdef\@currname{#1}%
+ \gdef\@currext{#2}%
+ \catcode`\@#3\relax
+ \gdef\@currnamestack{#4}}
+\@onlypreamble\@p@pfilename
+% \end{macrocode}
+%
+% \begin{macrocode}
+\gdef\@currnamestack{}
+\@onlypreamble\@currnamestack
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@ptionlist}
+% Returns the option list of the file.
+% \begin{macrocode}
+\def\@ptionlist#1{%
+ \@ifundefined{opt@#1}\@empty{\csname opt@#1\endcsname}}
+\@onlypreamble\@ptionlist
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@ifpackageloaded}
+% \begin{macro}{\@ifclassloaded}
+% |\@ifpackageloaded{|\meta{name}|}|
+% Checks to see whether a file has been loaded.
+% \changes{v0.2t}{1994/01/18}
+% {Fix typo \cs{@pkgetension}}
+% \begin{macrocode}
+\def\@ifpackageloaded{\@ifl@aded\@pkgextension}
+\def\@ifclassloaded{\@ifl@aded\@clsextension}
+\@onlypreamble\@ifpackageloaded
+\@onlypreamble\@ifclassloaded
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@ifl@aded#1#2{%
+ \expandafter\ifx\csname ver@#2.#1\endcsname\relax
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+\@onlypreamble\@ifl@aded
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@ifpackagelater}
+% \begin{macro}{\@ifclasslater}
+% |\@ifpackagelater{|\meta{name}|}{YYYY/MM/DD}|
+% Checks that the package loaded is more recent than the given date.
+% \begin{macrocode}
+\def\@ifpackagelater{\@ifl@ter\@pkgextension}
+\def\@ifclasslater{\@ifl@ter\@clsextension}
+\@onlypreamble\@ifpackagelater
+\@onlypreamble\@ifclasslater
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@ifl@ter#1#2{%
+ \expandafter\@ifl@t@r
+ \csname ver@#2.#1\endcsname}
+\@onlypreamble\@ifl@ter
+%</2ekernel>
+% \end{macrocode}
+%
+% This internal macro is also used in |\NeedsTeXFormat|.
+% \changes{v0.2f}{1993/11/22}
+% {Added //00 so parsing never produces a runaway argument.}
+% \changes{v1.2d}{2018/02/18}
+% {Added 0 up front to make bad data come out as 0.}
+% \changes{v1.2g}{2018/04/08}
+% {Strip leading spaces from dates.}
+% \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2018/04/01}%
+%<latexrelease> {\@ifl@t@r}{Guard against bad input}%
+%<*2ekernel|latexrelease>
+\def\@ifl@t@r#1#2{%
+ \ifnum\expandafter\@parse@version@#1//00\@nil<%
+ \expandafter\@parse@version@#2//00\@nil
+ \expandafter\@secondoftwo
+ \else
+ \expandafter\@firstoftwo
+ \fi}
+\def\@parse@version@#1{\@parse@version0#1}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@ifl@t@r}{Guard against bad input}%
+%<latexrelease>\def\@ifl@t@r#1#2{%
+%<latexrelease> \ifnum\expandafter\@parse@version#1//00\@nil<%
+%<latexrelease> \expandafter\@parse@version#2//00\@nil
+%<latexrelease> \expandafter\@secondoftwo
+%<latexrelease> \else
+%<latexrelease> \expandafter\@firstoftwo
+%<latexrelease> \fi}
+%<latexrelease>\let\@parse@version@\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@onlypreamble\@ifl@t@r
+% \end{macrocode}
+%
+% \changes{v1.1j}{2016/06/20}
+% {don't declare as \cs{@onlypreamble}}
+% \changes{v1.2c}{2017/03/08}
+% {add \cs{@parse@version@dash} to support yyyy-mm-dd as well as yyyy/mm/dd }
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexreleasefirst>
+\def\@parse@version#1/#2/#3#4#5\@nil{%
+\@parse@version@dash#1-#2-#3#4\@nil
+}
+% \end{macrocode}
+%
+% The |\if| test here ensures that an argument with no |/| or |-| produces 0 (actually 00).
+% \begin{macrocode}
+\def\@parse@version@dash#1-#2-#3#4#5\@nil{%
+ \if\relax#2\relax\else#1\fi#2#3#4 }
+%</2ekernel|latexreleasefirst>
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@ifpackagewith}
+% \begin{macro}{\@ifclasswith}
+% |\@ifpackagewith{|\meta{name}|}{|\meta{option-list}|}|
+% Checks that \meta{option-list} is a subset of the options
+% \textbf{with} which \meta{name} was loaded.
+% \begin{macrocode}
+\def\@ifpackagewith{\@if@ptions\@pkgextension}
+\def\@ifclasswith{\@if@ptions\@clsextension}
+\@onlypreamble\@ifpackagewith
+\@onlypreamble\@ifclasswith
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@if@ptions#1#2{%
+ \@expandtwoargs\@if@pti@ns{\@ptionlist{#2.#1}}}
+\@onlypreamble\@if@ptions
+% \end{macrocode}
+%
+% Probably shouldn't use |\CurrentOption| here\ldots (changed to
+% |\reserved@b|.)
+% \changes{v0.2y}{1994/02/07}
+% {Add extra ,s so `two' is not matched with `twocolumn'}
+% \changes{v1.1i}{2011/08/19}
+% {Re-jig definition after more stringent \cs{in@} test.}
+% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2017/01/01}%
+%<latexrelease> {\@if@pti@ns}{Spaces in option clash check}%
+%<*2ekernel|latexrelease>
+\def\@if@pti@ns#1#2{%
+ \let\reserved@a\@firstoftwo
+% \end{macrocode}
+% \changes{v1.2a}{2016/10/02}
+% {Ignore spaces while checking for option clash}
+% \begin{macrocode}
+ \edef\reserved@b{\zap@space#2 \@empty}%
+ \@for\reserved@b:=\reserved@b\do{%
+ \ifx\reserved@b\@empty
+ \else
+ \expandafter\in@\expandafter{\expandafter,\reserved@b,}{,#1,}%
+ \ifin@
+ \else
+ \let\reserved@a\@secondoftwo
+ \fi
+ \fi
+ }%
+ \reserved@a}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@if@pti@ns}{Spaces in option clash check}%
+%<latexrelease>\def\@if@pti@ns#1#2{%
+%<latexrelease> \let\reserved@a\@firstoftwo
+%<latexrelease> \@for\reserved@b:=#2\do{%
+%<latexrelease> \ifx\reserved@b\@empty
+%<latexrelease> \else
+%<latexrelease> \expandafter\in@\expandafter
+%<latexrelease> {\expandafter,\reserved@b,}{,#1,}%
+%<latexrelease> \ifin@
+%<latexrelease> \else
+%<latexrelease> \let\reserved@a\@secondoftwo
+%<latexrelease> \fi
+%<latexrelease> \fi
+%<latexrelease> }%
+%<latexrelease> \reserved@a}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@onlypreamble\@if@pti@ns
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\ProvidesPackage}
+% Checks that the current filename is correct, and defines
+% |\ver@filename|.
+% \changes{v0.3c}{1994/03/12}
+% {Add \cs{wlog}}
+% \changes{v0.3c}{1994/03/12}
+% {use \cs{@gtempa}}
+% \begin{macrocode}
+\def\ProvidesPackage#1{%
+ \xdef\@gtempa{#1}%
+ \ifx\@gtempa\@currname\else
+ \@latex@warning@no@line{You have requested
+ \@cls@pkg\space`\@currname',\MessageBreak
+ but the \@cls@pkg\space provides `#1'}%
+ \fi
+ \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%]
+\@onlypreamble\ProvidesPackage
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@pr@videpackage[#1]{%
+ \expandafter\xdef\csname ver@\@currname.\@currext\endcsname{#1}%
+ \ifx\@currext\@clsextension
+ \typeout{Document Class: \@gtempa\space#1}%
+ \else
+ \wlog{Package: \@gtempa\space#1}%
+ \fi}
+\@onlypreamble\@pr@videpackage
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ProvidesClass}
+% Like |\ProvidesPackage|, but for classes.
+% \begin{macrocode}
+\let\ProvidesClass\ProvidesPackage
+\@onlypreamble\ProvidesClass
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ProvidesFile}
+% Like |\ProvidesPackage|, but for arbitrary files. Do not apply
+% |\@onlypreamble| to these, as we may want to label files input
+% during the document.
+% \changes{v0.2l}{1993/12/07}
+% {Macro added}
+% \changes{v0.3c}{1994/03/12}
+% {Add \cs{wlog}}
+% \changes{v0.3g}{1994/04/11}
+% {Protect against weird catcodes.}
+% \begin{macro}{\@providesfile}
+% \changes{v1.0r}{1995/10/17}
+% {Delay definition of \cs{ProvidesFile} till ltfinal}
+% \changes{v1.1a}{1998/03/21}
+% {Allow \&. Internal/2702}
+% \changes{v1.1d}{2001/05/25}{Explicitly set catcode of
+% \cs{endlinechar} to 10 (pr/3334)}
+% \changes{v1.1e}{2001/06/04}{But only if it is a char (pr/3334)}
+% \changes{v1.1f}{2001/08/26}{Readded setting of space char (pr/3353)}
+% \begin{macrocode}
+\def\ProvidesFile#1{%
+ \begingroup
+ \catcode`\ 10 %
+ \ifnum \endlinechar<256 %
+ \ifnum \endlinechar>\m@ne
+ \catcode\endlinechar 10 %
+ \fi
+ \fi
+ \@makeother\/%
+ \@makeother\&%
+% \end{macrocode}
+% \changes{v1.1g}{2004/01/28}{Use kernel version of
+% \cs{@ifnextchar} (pr/3501)}
+% \begin{macrocode}
+ \kernel@ifnextchar[{\@providesfile{#1}}{\@providesfile{#1}[]}}
+% \end{macrocode}
+%
+% During initex a special version of |\@providesfile| is used.
+% The real definition is installed right at the end, in |ltfinal.dtx|.
+%\begin{verbatim}
+%\def\@providesfile#1[#2]{%
+% \wlog{File: #1 #2}%
+% \expandafter\xdef\csname ver@#1\endcsname{#2}%
+% \endgroup}
+%\end{verbatim}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\PassOptionsToPackage}
+% \begin{macro}{\PassOptionsToClass}
+% If the package has been loaded, we check that it was first loaded with
+% the options. Otherwise we add the option list to that of the package.
+% \begin{macrocode}
+\def\@pass@ptions#1#2#3{%
+ \expandafter\xdef\csname opt@#3.#1\endcsname{%
+ \@ifundefined{opt@#3.#1}\@empty
+ {\csname opt@#3.#1\endcsname,}%
+ \zap@space#2 \@empty}}
+\@onlypreamble\@pass@ptions
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\PassOptionsToPackage{\@pass@ptions\@pkgextension}
+\def\PassOptionsToClass{\@pass@ptions\@clsextension}
+\@onlypreamble\PassOptionsToPackage
+\@onlypreamble\PassOptionsToClass
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DeclareOption}
+% \begin{macro}{\DeclareOption*}
+% Adds an option as a |\ds@| command, or the default |\default@ds|
+% command.
+% \changes{v0.2c}{1993/11/17}
+% {Error checking added}
+% \changes{v1.0m}{1995/04/21}
+% {Made long /1498}
+% \changes{v1.0n}{1995/05/12}
+% {Use \cs{toks@} to remove need to double hash /1557}
+% \begin{macrocode}
+\def\DeclareOption{%
+ \let\@fileswith@pti@ns\@badrequireerror
+ \@ifstar\@defdefault@ds\@declareoption}
+\long\def\@declareoption#1#2{%
+ \xdef\@declaredoptions{\@declaredoptions,#1}%
+ \toks@{#2}%
+ \expandafter\edef\csname ds@#1\endcsname{\the\toks@}}
+\long\def\@defdefault@ds#1{%
+ \toks@{#1}%
+ \edef\default@ds{\the\toks@}}
+\@onlypreamble\DeclareOption
+\@onlypreamble\@declareoption
+\@onlypreamble\@defdefault@ds
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\OptionNotUsed}
+% If we are in a class file, add |\CurrentOption| to the list of
+% unused options. Otherwise, in a package file do nothing.
+% \begin{macrocode}
+\def\OptionNotUsed{%
+ \ifx\@currext\@clsextension
+ \xdef\@unusedoptionlist{%
+ \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
+ \CurrentOption}%
+ \fi}
+\@onlypreamble\OptionNotUsed
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\default@ds}
+% The default default option code.
+% Set by |\@onefilewithoptions| to either |\OptionNotUsed| for
+% classes, or |\@unknownoptionerror| for packages. This may be reset
+% in either case with |\DeclareOption*|.
+% \begin{macrocode}
+% \let\default@ds\OptionNotUsed
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ProcessOptions}
+% \begin{macro}{\ProcessOptions*}
+% |\ProcessOptions| calls |\ds@option| for each known package option,
+% then calls |\default@ds| for each option on the local options list.
+% Finally resets all the declared options to |\relax|. The empty option
+% does nothing, this has to be reset on the off chance it's set to
+% |\relax| if an empty element gets into the |\@declaredoptions| list.
+%
+% The star form is similar but executes options given in the order
+% specified in the document, not the order they are declared in the
+% file. In the case of packages, global options are executed before
+% local ones.
+% \changes{v0.2a}{1993/11/14}
+% {Stop adding the global option list inside class files.}
+% \changes{v0.2a}{1993/11/14}
+% {Optimise `empty option' code.}
+% \changes{v0.2b}{1993/11/15}
+% {Star form added.}
+% \changes{v0.2c}{1993/11/17}
+% {restoring \cs{@fileswith@pti@ns} added.}
+% \begin{macrocode}
+\def\ProcessOptions{%
+ \let\ds@\@empty
+ \edef\@curroptions{\@ptionlist{\@currname.\@currext}}%
+ \@ifstar\@xprocess@ptions\@process@ptions}
+\@onlypreamble\ProcessOptions
+% \end{macrocode}
+%
+% \changes{v0.2y}{1994/02/07}
+% {Add extra ,s so `two' is not matched with `twocolumn'}
+% \begin{macrocode}
+\def\@process@ptions{%
+ \@for\CurrentOption:=\@declaredoptions\do{%
+ \ifx\CurrentOption\@empty\else
+ \@expandtwoargs\in@{,\CurrentOption,}{%
+ ,\ifx\@currext\@clsextension\else\@classoptionslist,\fi
+ \@curroptions,}%
+ \ifin@
+ \@use@ption
+ \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+ \fi
+ \fi}%
+ \@process@pti@ns}
+\@onlypreamble\@process@ptions
+% \end{macrocode}
+%
+% \changes{v0.2y}{1994/02/07}
+% {Add extra ,s so `two' is not matched with `twocolumn'}
+% \begin{macrocode}
+\def\@xprocess@ptions{%
+ \ifx\@currext\@clsextension\else
+ \@for\CurrentOption:=\@classoptionslist\do{%
+ \ifx\CurrentOption\@empty\else
+ \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}%
+ \ifin@
+ \@use@ption
+ \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+ \fi
+ \fi}%
+ \fi
+ \@process@pti@ns}
+\@onlypreamble\@xprocess@ptions
+% \end{macrocode}
+%
+% The common part of |\ProcessOptions| and |\ProcessOptions*|.
+% \begin{macrocode}
+\def\@process@pti@ns{%
+ \@for\CurrentOption:=\@curroptions\do{%
+ \@ifundefined{ds@\CurrentOption}%
+ {\@use@ption
+ \default@ds}%
+% \end{macrocode}
+% There should not be any non-empty definition of |\CurrentOption| at
+% this point, as all the declared options were executed earlier. This is
+% for compatibility with 2.09 styles which use |\def\ds@|\ldots\
+% directly, and so have options which do not appear in
+% |\@declaredoptions|.
+% \begin{macrocode}
+ \@use@ption}%
+% \end{macrocode}
+% Clear all the definitions for option code. First set all the declared
+% options to |\relax|, then reset the `default' and `empty' options. and
+% the lst of declared options.
+% \begin{macrocode}
+ \@for\CurrentOption:=\@declaredoptions\do{%
+ \expandafter\let\csname ds@\CurrentOption\endcsname\relax}%
+% \end{macrocode}
+% \changes{v1.0r}{1995/10/17}
+% {Reset \cs{CurrentOption} for graphics/1873}
+% \begin{macrocode}
+ \let\CurrentOption\@empty
+ \let\@fileswith@pti@ns\@@fileswith@pti@ns
+ \AtEndOfPackage{\let\@unprocessedoptions\relax}}
+\@onlypreamble\@process@pti@ns
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@options}
+% |\@options| is a synonym for |\ProcessOptions*| for upward
+% compatibility with \LaTeX2.09 style files.
+% \begin{macrocode}
+\def\@options{\ProcessOptions*}
+\@onlypreamble\@options
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@use@ption}
+% Execute the code for the current option.
+% \changes{v0.2g}{1993/11/23}
+% {Name changed from \cs{@executeoption}}
+% \changes{v1.0e}{1994/05/17}
+% {Execute option after removing from list, not before}
+% \begin{macrocode}
+\def\@use@ption{%
+ \@expandtwoargs\@removeelement\CurrentOption
+ \@unusedoptionlist\@unusedoptionlist
+ \csname ds@\CurrentOption\endcsname}
+\@onlypreamble\@use@ption
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ExecuteOptions}
+% |\ExecuteOptions{|\meta{option-list}|}| executes the code declared
+% for each option.
+% \changes{v0.2d}{1993/11/18}
+% {Use \cs{CurrentOption} not \cs{reserved@a}}
+% \changes{v0.2k}{1993/12/06}
+% {Preserve \cs{CurrentOption}.}
+% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2017/01/01}%
+%<latexrelease> {\ExecuteOptions}{Spaces in \ExecuteOptions}%
+%<*2ekernel|latexrelease>
+\def\ExecuteOptions#1{%
+% \end{macrocode}
+% \changes{v1.2a}{2016/10/02}
+% {Ignore spaces in argument}
+% Use |\@fortmp| here as it is anyway cleared during |\@for| loop
+% so does not change any existing names.
+% \begin{macrocode}
+ \edef\@fortmp{\zap@space#1 \@empty}%
+ \def\reserved@a##1\@nil{%
+ \@for\CurrentOption:=\@fortmp\do
+ {\csname ds@\CurrentOption\endcsname}%
+ \edef\CurrentOption{##1}}%
+ \expandafter\reserved@a\CurrentOption\@nil}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\ExecuteOptions}{Spaces in \ExecuteOptions}%
+%<latexrelease>\def\ExecuteOptions#1{%
+%<latexrelease> \def\reserved@a##1\@nil{%
+%<latexrelease> \@for\CurrentOption:=#1\do
+%<latexrelease> {\csname ds@\CurrentOption\endcsname}%
+%<latexrelease> \edef\CurrentOption{##1}}%
+%<latexrelease> \expandafter\reserved@a\CurrentOption\@nil}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@onlypreamble\ExecuteOptions
+% \end{macrocode}
+% \end{macro}
+%
+% The top-level commands, which just set some parameters then call
+% the internal command, |\@fileswithoptions|.
+% \begin{macro}{\documentclass}
+% \changes{v1.0q}{1995/06/19}
+% {Dont redefine \cs{usepackage} in compat mode for /1634}
+% The main new-style class declaration.
+% \begin{macrocode}
+\def\documentclass{%
+ \let\documentclass\@twoclasseserror
+ \if@compatibility\else\let\usepackage\RequirePackage\fi
+ \@fileswithoptions\@clsextension}
+\@onlypreamble\documentclass
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\documentstyle}
+% 2.09 style class `style' declaration.
+% \changes{v0.2a}{1993/11/14}
+% {Added \cs{RequirePackage} \cs{@unusedoptionlist} stuff.}
+% \changes{v0.2b}{1993/11/15}
+% {Modified to match \cs{ProcessOption*}}
+% \changes{v0.2d}{1993/11/18}
+% {Modified \cs{RequirePackage} stuff.}
+% \changes{v0.2n}{1993/12/09}
+% {input 209 compatibility file.}
+% \changes{v0.2o}{1993/12/13}
+% {compatibility file now latex209.sty.}
+% \changes{v0.2q}{1993/12/17}
+% {Match Alan's new code.}
+% \changes{v0.2u}{1994/01/21}
+% {compatibility file now latex209.def.}
+% \begin{macrocode}
+\def\documentstyle{%
+ \makeatletter\input{latex209.def}\makeatother
+ \documentclass}
+\@onlypreamble\documentstyle
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\RequirePackage}
+% Load package if not already loaded.
+% \begin{macrocode}
+\def\RequirePackage{%
+ \@fileswithoptions\@pkgextension}
+\@onlypreamble\RequirePackage
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\LoadClass}
+% Load class.
+% \begin{macrocode}
+\def\LoadClass{%
+ \ifx\@currext\@pkgextension
+ \@latex@error
+ {\noexpand\LoadClass in package file}%
+ {You may only use \noexpand\LoadClass in a class file.}%
+ \fi
+ \@fileswithoptions\@clsextension}
+\@onlypreamble\LoadClass
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@loadwithoptions}
+% \changes{v1.0t}{1995/11/14}{macro added}
+% Pass the current option list on to a class or package.
+% |#1| is |\@|\emph{cls-or-pkg}|extension|,
+% |#2| is |\RequirePackage| or |\LoadClass|,
+% |#3| is the class or package to be loaded.
+% \begin{macrocode}
+\def\@loadwithoptions#1#2#3{%
+ \expandafter\let\csname opt@#3.#1\expandafter\endcsname
+ \csname opt@\@currname.\@currext\endcsname
+ #2{#3}}
+\@onlypreamble\@loadwithoptions
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\LoadClassWithOptions}
+% \changes{v1.0t}{1995/11/14}{macro added}
+% Load class `|#1|' with the current option list.
+% \begin{macrocode}
+\def\LoadClassWithOptions{%
+ \@loadwithoptions\@clsextension\LoadClass}
+\@onlypreamble\LoadClassWithOptions
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\RequirePackageWithOptions}
+% \changes{v1.0t}{1995/11/14}{macro added}
+% \changes{v1.0v}{1996/10/04}{Reset \cs{@unprocessedoptions} for /2269}
+% Load package `|#1|' with the current option list.
+% \begin{macrocode}
+\def\RequirePackageWithOptions{%
+ \AtEndOfPackage{\let\@unprocessedoptions\relax}%
+ \@loadwithoptions\@pkgextension\RequirePackage}
+\@onlypreamble\RequirePackageWithOptions
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\usepackage}
+% To begin with, |\usepackage| produces an error. This is reset by
+% |\documentclass|.
+% \changes{v0.2o}{1993/12/13}
+% {Fixed error handling}
+% \changes{v1.0h}{1994/05/23}{Remove argument if possible}
+% \begin{macrocode}
+\def\usepackage#1#{%
+ \@latex@error
+ {\noexpand \usepackage before \string\documentclass}%
+ {\noexpand \usepackage may only appear in the document
+ preamble, i.e.,\MessageBreak
+ between \noexpand\documentclass and
+ \string\begin{document}.}%
+ \@gobble}
+\@onlypreamble\usepackage
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NeedsTeXFormat}
+% Check that the document is running on the correct system.
+% \changes{v0.2a}{1993/11/14}
+% {made more robust for alternative syntax for other formats.}
+% \changes{v0.2c}{1993/11/17}
+% {Name changed from \cs{NeedsFormat}}
+% \changes{v0.2d}{1993/11/18}
+% {\cs{fmtname} \cs{fmtversion} not \cs{@}\ldots}
+% \begin{macrocode}
+\def\NeedsTeXFormat#1{%
+ \def\reserved@a{#1}%
+ \ifx\reserved@a\fmtname
+ \expandafter\@needsformat
+ \else
+ \@latex@error{This file needs format `\reserved@a'%
+ \MessageBreak but this is `\fmtname'}{%
+ The current input file will not be processed
+ further,\MessageBreak
+ because it was written for some other flavor of
+ TeX.\MessageBreak\@ehd}%
+% \end{macrocode}
+% If the file is not meant to be processed by \LaTeXe{} we stop
+% inputting it, but we do not end the run. We just end inputting
+% the current file.
+% \changes{v1.0h}{1994/05/23}
+% {Don't stop completely when format is wrong}
+% \begin{macrocode}
+ \endinput \fi}
+\@onlypreamble\NeedsTeXFormat
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@needsformat{%
+ \@ifnextchar[%]
+ \@needsf@rmat
+ {}}
+\@onlypreamble\@needsformat
+% \end{macrocode}
+%
+% \changes{v1.0b}{1994/05/04}
+% {Changed wording of the warning}
+% \begin{macrocode}
+\def\@needsf@rmat[#1]{%
+ \@ifl@t@r\fmtversion{#1}{}%
+ {\@latex@warning@no@line
+ {You have requested release `#1' of LaTeX,\MessageBreak
+ but only release `\fmtversion' is available}}}
+\@onlypreamble\@needsf@rmat
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\zap@space}
+% |\zap@space foo|\meta{space}|\@empty| removes all spaces from |foo|
+% that are not protected by |{ }| groups.
+% \begin{macrocode}
+\def\zap@space#1 #2{%
+ #1%
+ \ifx#2\@empty\else\expandafter\zap@space\fi
+ #2}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@fileswithoptions}
+% The common part of |\documentclass| and |\usepackage|.
+% \begin{macrocode}
+\def\@fileswithoptions#1{%
+ \@ifnextchar[%]
+ {\@fileswith@ptions#1}%
+ {\@fileswith@ptions#1[]}}
+\@onlypreamble\@fileswithoptions
+% \end{macrocode}
+%
+% \changes{v0.2f}{1993/11/22}
+% {Made the default [] not [\cs{@unknownversion}]}
+% \changes{v1.1h}{2007/08/05}
+% {Prevent loss of brackets PR/3965}
+% \begin{macrocode}
+\def\@fileswith@ptions#1[#2]#3{%
+ \@ifnextchar[%]
+ {\@fileswith@pti@ns#1[{#2}]#3}%
+ {\@fileswith@pti@ns#1[{#2}]#3[]}}
+\@onlypreamble\@fileswith@ptions
+% \end{macrocode}
+% Then we do some work.
+%
+% First of all, we define the global variables.
+% Then we look to see if the file has already been loaded.
+% If it has, we check that it was first loaded with at least the current
+% options.
+% If it has not, we add the current options to the package options,
+% set the default version to be |0000/00/00|, and load the file if we
+% can find it.
+% Then we check the version number.
+%
+% Finally, we restore the old file name, reset the default option,
+% and we set the catcode of |@|.
+%
+% For classes, we can immediately process the file. For other types,
+% |#2| could be a comma separated list, so loop through, processing
+% each one separately.
+% \changes{v0.2q}{1993/12/17}
+% {Add \cs{@compatibility} hook}
+% \changes{v0.2s}{1994/01/17}
+% {Modify to reduce parameter stack usage}
+% \changes{v0.2y}{1994/02/07}
+% {Run \cs{@compatibility} on the first class to start
+% (not the first to finish) }
+% \changes{v0.2z}{1994/02/10}
+% {Renamed \cs{@compatibility} to \cs{@documentclasshook}.
+% ASAJ.}
+% \changes{v1.1h}{2007/08/05}
+% {Prevent loss of brackets PR/3965}
+% \changes{v2.1b}{2016/11/09}
+% {Improve \cs{ifx} tests PR/4497}
+% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2017/01/01}%
+%<latexrelease> {\@fileswith@pti@ns}{ifx tests in \@fileswith@pti@ns}%
+%<*2ekernel|latexrelease>
+\def\@fileswith@pti@ns#1[#2]#3[#4]{%
+ \ifx#1\@clsextension
+ \ifx\@classoptionslist\relax
+ \xdef\@classoptionslist{\zap@space#2 \@empty}%
+ \def\reserved@a{%
+ \@onefilewithoptions#3[{#2}][{#4}]#1%
+ \@documentclasshook}%
+ \else
+ \def\reserved@a{%
+ \@onefilewithoptions#3[{#2}][{#4}]#1}%
+ \fi
+ \else
+% \end{macrocode}
+% build up a list of calls to |\@onefilewithoptions|
+% (one for each package) without thrashing the parameter stack.
+% \begin{macrocode}
+ \def\reserved@b##1,{%
+% \end{macrocode}
+% If |#1| is |\@nnil| we have reached the end of the list
+% (older version used |\@nil| here but |\@nil| is undefined so |\ifx|
+% equal to all undefined commands)
+% \begin{macrocode}
+ \ifx\@nnil##1\relax\else
+% \end{macrocode}
+% If |\ifx\@nnil##1\n@nil| is true then |#1| is (presumably) empty
+% (Older code used |\relax| which is slighly easier to get into |#1|
+% by mistake, which would spoil this test.)
+% \begin{macrocode}
+ \ifx\@nnil##1\@nnil\else
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \noexpand\@onefilewithoptions##1[{#2}][{#4}]%
+ \noexpand\@pkgextension
+ \fi
+ \expandafter\reserved@b
+ \fi}%
+ \edef\reserved@a{\zap@space#3 \@empty}%
+ \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nnil,}%
+ \fi
+ \reserved@a}
+%</2ekernel|latexrelease>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@fileswith@pti@ns}{ifx tests in \@fileswith@pti@ns}%
+%<latexrelease>\def\@fileswith@pti@ns#1[#2]#3[#4]{%
+%<latexrelease> \ifx#1\@clsextension
+%<latexrelease> \ifx\@classoptionslist\relax
+%<latexrelease> \xdef\@classoptionslist{\zap@space#2 \@empty}%
+%<latexrelease> \def\reserved@a{%
+%<latexrelease> \@onefilewithoptions#3[{#2}][{#4}]#1%
+%<latexrelease> \@documentclasshook}%
+%<latexrelease> \else
+%<latexrelease> \def\reserved@a{%
+%<latexrelease> \@onefilewithoptions#3[{#2}][{#4}]#1}%
+%<latexrelease> \fi
+%<latexrelease> \else
+%<latexrelease> \def\reserved@b##1,{%
+%<latexrelease> \ifx\@nil##1\relax\else
+%<latexrelease> \ifx\relax##1\relax\else
+%<latexrelease> \noexpand\@onefilewithoptions##1[{#2}][{#4}]%
+%<latexrelease> \noexpand\@pkgextension
+%<latexrelease> \fi
+%<latexrelease> \expandafter\reserved@b
+%<latexrelease> \fi}%
+%<latexrelease> \edef\reserved@a{\zap@space#3 \@empty}%
+%<latexrelease> \edef\reserved@a{%
+%<latexrelease> \expandafter\reserved@b\reserved@a,\@nil,}%
+%<latexrelease> \fi
+%<latexrelease> \reserved@a}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@onlypreamble\@fileswith@pti@ns
+% \end{macrocode}
+%
+% Have the main argument as |#1|, so we only need one |\expandafter|
+% above.
+% \changes{v0.2a}{1993/11/14}
+% {Moved resetting of \cs{default@ds}, \cs{ds@} and
+% \cs{@declaredoptions} here, from the end of
+% \cs{ProcessOptions}.}
+% \changes{v0.2f}{1993/11/22}
+% {Made the initial version [] not [\cs{@unknownversion}]}
+% \changes{v0.2m}{1993/12/07}
+% {Reset \cs{CurrentOption}}
+% \begin{macrocode}
+\def\@onefilewithoptions#1[#2][#3]#4{%
+ \@pushfilename
+ \xdef\@currname{#1}%
+ \global\let\@currext#4%
+ \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty
+ \let\CurrentOption\@empty
+ \@reset@ptions
+ \makeatletter
+% \end{macrocode}
+% Grab everything in a macro, so the parameter stack is popped before
+% any processing begins.
+% \changes{v0.2s}{1994/01/17}
+% {Modify to reduce parameter stack usage}
+% \changes{v1.1b}{1998/05/07}
+% {Modify help message for latex/2805}
+% \begin{macrocode}
+ \def\reserved@a{%
+ \@ifl@aded\@currext{#1}%
+ {\@if@ptions\@currext{#1}{#2}{}%
+ {\@latex@error
+ {Option clash for \@cls@pkg\space #1}%
+ {The package #1 has already been loaded
+ with options:\MessageBreak
+ \space\space[\@ptionlist{#1.\@currext}]\MessageBreak
+ There has now been an attempt to load it
+ with options\MessageBreak
+ \space\space[#2]\MessageBreak
+ Adding the global options:\MessageBreak
+ \space\space
+ \@ptionlist{#1.\@currext},#2\MessageBreak
+ to your \noexpand\documentclass declaration may fix this.%
+ \MessageBreak
+ Try typing \space <return> \space to proceed.}}}%
+ {\@pass@ptions\@currext{#2}{#1}%
+% \end{macrocode}
+% \changes{v0.3c}{1994/03/12}
+% {Do not use \cs{@pr@videpackage} to avoid typeout}
+% \begin{macrocode}
+ \global\expandafter
+ \let\csname ver@\@currname.\@currext\endcsname\@empty
+ \InputIfFileExists
+ {\@currname.\@currext}%
+ {}%
+ {\@missingfileerror\@currname\@currext}%
+% \end{macrocode}
+% |\@unprocessedoptions| will generate an error for each specified
+% option in a package unless a |\ProcessOptions| has appeared in the
+% package file.
+% \changes{v0.2v}{1994/01/29}
+% {All options raise error if no \cs{ProcessOptions} appears}
+% \changes{v0.2x}{1994/02/02}
+% {Only run the hook and options check if the file was loaded.}
+% \begin{macrocode}
+ \let\@unprocessedoptions\@@unprocessedoptions
+ \csname\@currname.\@currext-h@@k\endcsname
+ \expandafter\let\csname\@currname.\@currext-h@@k\endcsname
+ \@undefined
+ \@unprocessedoptions}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@ifl@ter\@currext{#1}{#3}{}%
+ {\@latex@warning@no@line
+ {You have requested,\on@line,
+ version\MessageBreak
+ `#3' of \@cls@pkg\space #1,\MessageBreak
+ but only version\MessageBreak
+ `\csname ver@#1.\@currext\endcsname'\MessageBreak
+ is available}}%
+% \end{macrocode}
+% \changes{v0.2c}{1993/11/17}
+% {Added trap for two \cs{LoadClass} commands.}
+% \begin{macrocode}
+ \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi
+ \@popfilename
+ \@reset@ptions}%
+ \reserved@a}
+\@onlypreamble\@onefilewithoptions
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@fileswith@pti@ns}
+% Save the definition (for error checking).
+% \changes{v0.2c}{1993/11/17}
+% {Macro added}
+% \begin{macrocode}
+\let\@@fileswith@pti@ns\@fileswith@pti@ns
+\@onlypreamble\@@fileswith@pti@ns
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@reset@ptions}
+% Reset the default option, and clear lists of declared options.
+% \changes{v0.2a}{1993/11/14}{macro added}
+% \begin{macrocode}
+\def\@reset@ptions{%
+ \global\ifx\@currext\@clsextension
+ \let\default@ds\OptionNotUsed
+ \else
+ \let\default@ds\@unknownoptionerror
+ \fi
+ \global\let\ds@\@empty
+ \global\let\@declaredoptions\@empty}
+\@onlypreamble\@reset@ptions
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Hooks}
+%
+% Allow code do be saved to be executed at specific later times.
+%
+% Save things in macros, I considered using toks registers, (and
+% |\addto@hook| from the NFSS code, that would require stacking the
+% contents in the case of required packages, so just generate a new
+% macro for each package.
+% \begin{macro}{\@begindocumenthook}
+% \changes{v1.0s}{1995/10/20}
+% {Make setting conditional, for autoload version}
+% \begin{macro}{\@enddocumenthook}
+% Stuff to appear at the beginning or end of the document.
+% \begin{macrocode}
+\ifx\@begindocumenthook\@undefined
+ \let\@begindocumenthook\@empty
+\fi
+\let\@enddocumenthook\@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\g@addto@macro}
+% Globally add to the end of a macro.
+% \changes{v0.2a}{1993/11/14}{Made global}
+% \changes{v0.2w}{1994/01/31}
+% {Use toks register to avoid `hash' problems}
+% \changes{v1.0o}{1995/05/17}
+% {Make long for latex/1522}
+% \changes{v1.0w}{1996/12/17}
+% {Use \cs{begingroup} to save making a mathord}
+% \changes{v1.0x}{1997/02/05}
+% {missing percent /2402}
+% \begin{macrocode}
+\long\def\g@addto@macro#1#2{%
+ \begingroup
+ \toks@\expandafter{#1#2}%
+ \xdef#1{\the\toks@}%
+ \endgroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AtEndOfPackage}
+% \begin{macro}{\AtEndOfClass}
+% \begin{macro}{\AtBeginDocument}
+% \begin{macro}{\AtEndDocument}
+% The access functions.
+% \changes{v0.2a}{1993/11/14}
+% {Included extension in the generated macro name for package
+% and class hooks.}
+% \begin{macrocode}
+\def\AtEndOfPackage{%
+ \expandafter\g@addto@macro\csname\@currname.\@currext-h@@k\endcsname}
+\let\AtEndOfClass\AtEndOfPackage
+\@onlypreamble\AtEndOfPackage
+\@onlypreamble\AtEndOfClass
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\AtBeginDocument{\g@addto@macro\@begindocumenthook}
+\def\AtEndDocument{\g@addto@macro\@enddocumenthook}
+\@onlypreamble\AtBeginDocument
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@cls@pkg}
+% The current file type.
+% \changes{v0.2i}{1993/12/03}
+% {Name changed to avoid clash with output routine.}
+% \begin{macrocode}
+\def\@cls@pkg{%
+ \ifx\@currext\@clsextension
+ document class%
+ \else
+ package%
+ \fi}
+\@onlypreamble\@cls@pkg
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@unknownoptionerror}
+% Bad option.
+% \begin{macrocode}
+\def\@unknownoptionerror{%
+ \@latex@error
+ {Unknown option `\CurrentOption' for \@cls@pkg\space`\@currname'}%
+ {The option `\CurrentOption' was not declared in
+ \@cls@pkg\space`\@currname', perhaps you\MessageBreak
+ misspelled its name.
+ Try typing \space <return>
+ \space to proceed.}}
+\@onlypreamble\@unknownoptionerror
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@unprocessedoptions}
+% Declare an error for each option, unless a |\ProcessOptions| occurred.
+% \changes{v0.2v}{1994/01/29}
+% {Macro added.}
+% \changes{v1.0t}{1995/11/14}{Allow empty option}
+% \begin{macrocode}
+\def\@@unprocessedoptions{%
+ \ifx\@currext\@pkgextension
+ \edef\@curroptions{\@ptionlist{\@currname.\@currext}}%
+ \@for\CurrentOption:=\@curroptions\do{%
+ \ifx\CurrentOption\@empty\else\@unknownoptionerror\fi}%
+ \fi}
+\@onlypreamble\@unprocessedoptions
+\@onlypreamble\@@unprocessedoptions
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@badrequireerror}
+% |\RequirePackage| or |\LoadClass| occurs in the options section.
+% \changes{v0.2c}{1993/11/17}
+% {Macro added}
+% \begin{macrocode}
+\def\@badrequireerror#1[#2]#3[#4]{%
+ \@latex@error
+ {\noexpand\RequirePackage or \noexpand\LoadClass
+ in Options Section}%
+ {The \@cls@pkg\space `\@currname' is defective.\MessageBreak
+ It attempts to load `#3' in the options section, i.e.,\MessageBreak
+ between \noexpand\DeclareOption and \string\ProcessOptions.}}
+\@onlypreamble\@badrequireerror
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@twoloadclasserror}
+% Two |\LoadClass| in a class.
+% \changes{v0.2c}{1993/11/17}
+% {Macro added}
+% \begin{macrocode}
+\def\@twoloadclasserror{%
+ \@latex@error
+ {Two \noexpand\LoadClass commands}%
+ {You may only use one \noexpand\LoadClass in a class file}}
+\@onlypreamble\@twoloadclasserror
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@twoclasseserror}
+% Two |\documentclass| or |\documentstyle|.
+% \changes{v0.2h}{1993/11/28}
+% {Macro added}
+% \begin{macrocode}
+\def\@twoclasseserror#1#{%
+ \@latex@error
+ {Two \noexpand\documentclass or \noexpand\documentstyle commands}%
+ {The document may only declare one class.}\@gobble}
+\@onlypreamble\@twoclasseserror
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Providing shipment}
+%
+% \begin{macro}{\two@digits}
+% Prefix a number less than 10 with `0'.
+% \begin{macrocode}
+\def\two@digits#1{\ifnum#1<10 0\fi\number#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\filecontents}
+% \begin{macro}{\endfilecontents}
+% This environment implements inline files.
+% The star-form does not write extra comments into the file.
+%
+% \changes{v0.2h}{1993/11/28}
+% {Don't globally allocate a write stream (always use 15)}
+% \changes{v0.2r}{1993/12/19}{Different message when ignoring a file}
+% \changes{v0.3g}{1994/04/11}
+% {Add star form,
+% dont write \cs{endinput} at the end of the file.}
+% \changes{v1.0c}{1994/05/11}
+% {Add checks for form feed and tab}
+% \changes{v1.0m}{1995/04/21}
+% {Close input check stream: latex/1487}
+% \changes{v1.0p}{1995/05/25}{Delete \cs{filec@ntents} after preamble}
+% \begin{macrocode}
+\begingroup%
+\@tempcnta=1
+\loop
+ \catcode\@tempcnta=12 %
+ \advance\@tempcnta\@ne %
+\ifnum\@tempcnta<32 %
+\repeat %
+\catcode`\*=11 %
+\catcode`\^^M\active%
+\catcode`\^^L\active\let^^L\relax%
+\catcode`\^^I\active%
+% \end{macrocode}
+%
+% \begin{macrocode}
+\gdef\filecontents{\@tempswatrue\filec@ntents}%
+\gdef\filecontents*{\@tempswafalse\filec@ntents}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+\gdef\filec@ntents#1{%
+ \openin\@inputcheck#1 %
+ \ifeof\@inputcheck%
+ \@latex@warning@no@line%
+ {Writing file `\@currdir#1'}%
+% \end{macrocode}
+%
+% \changes{v1.0y}{1997/10/10}
+% {\cs{reserved@c} not \cs{verbatim@out} to save a csname}
+% \begin{macrocode}
+ \chardef\reserved@c15 %
+ \ch@ck7\reserved@c\write%
+ \immediate\openout\reserved@c#1\relax%
+ \else%
+% \end{macrocode}
+%
+% \changes{v1.0y}{1997/10/10}
+% {Use \cs{@gobbletwo}}
+% \begin{macrocode}
+ \closein\@inputcheck%
+ \@latex@warning@no@line%
+ {File `#1' already exists on the system.\MessageBreak%
+ Not generating it from this source}%
+ \let\write\@gobbletwo%
+ \let\closeout\@gobble%
+ \fi%
+ \if@tempswa%
+% \end{macrocode}
+%
+% \changes{v1.0y}{1997/10/10}
+% {\cs{@currenvir} in banner}
+% \begin{macrocode}
+ \immediate\write\reserved@c{%
+ \@percentchar\@percentchar\space%
+ \expandafter\@gobble\string\LaTeX2e file `#1'^^J%
+ \@percentchar\@percentchar\space generated by the %
+ `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J%
+ \@percentchar\@percentchar\space from source `\jobname' on %
+ \number\year/\two@digits\month/\two@digits\day.^^J%
+ \@percentchar\@percentchar}%
+ \fi%
+ \let\do\@makeother\dospecials%
+% \end{macrocode}
+% If there are active characters in the upper half (e.g., from
+% \texttt{inputenc} there would be confusion so we render everything
+% harmless.
+% \changes{v1.2f}{2018/03/27}
+% {Use full file name for old release}
+% \begin{macrocode}
+ \count@ 128\relax%
+ \loop%
+ \catcode\count@ 11\relax%
+ \advance\count@ \@ne%
+ \ifnum\count@<\@cclvi%
+ \repeat%
+% \end{macrocode}
+%
+% \changes{v1.0y}{1997/10/10}
+% {Check for text before or after \cs{end} environment. latex/2636}
+% \begin{macrocode}
+ \edef\E{\@backslashchar end\string{\@currenvir\string}}%
+ \edef\reserved@b{%
+ \def\noexpand\reserved@b%
+ ####1\E####2\E####3\relax}%
+ \reserved@b{%
+ \ifx\relax##3\relax%
+% \end{macrocode}
+% There was no |\end{filecontents}|
+% \begin{macrocode}
+ \immediate\write\reserved@c{##1}%
+ \else%
+% \end{macrocode}
+% There was a |\end{filecontents}|, so stop this time.
+% \begin{macrocode}
+ \edef^^M{\noexpand\end{\@currenvir}}%
+ \ifx\relax##1\relax%
+ \else%
+% \end{macrocode}
+% Text before the |\end|, write it with a warning.
+% \begin{macrocode}
+ \@latex@warning{Writing text `##1' before %
+ \string\end{\@currenvir}\MessageBreak as last line of #1}%
+ \immediate\write\reserved@c{##1}%
+ \fi%
+ \ifx\relax##2\relax%
+ \else%
+% \end{macrocode}
+% Text after the |\end|, ignore it with a warning.
+% \begin{macrocode}
+ \@latex@warning{%
+ Ignoring text `##2' after \string\end{\@currenvir}}%
+ \fi%
+ \fi%
+ ^^M}%
+% \end{macrocode}
+%
+% \changes{v1.2j}{2018/05/29}{use \cs{csname} not \cs{@undefined}}
+% \begin{macrocode}
+ \catcode`\^^L\active%
+ \let\L\@undefined%
+ \def^^L{\expandafter\ifx\csname L\endcsname\relax\fi ^^J^^J}%
+ \catcode`\^^I\active%
+ \let\I\@undefined%
+ \def^^I{\expandafter\ifx\csname I\endcsname\relax\fi\space}%
+ \catcode`\^^M\active%
+ \edef^^M##1^^M{%
+ \noexpand\reserved@b##1\E\E\relax}}%
+\endgroup%
+% \end{macrocode}
+%
+% \begin{macrocode}
+\begingroup
+\catcode`|=\catcode`\%
+\catcode`\%=12
+\catcode`\*=11
+\gdef\@percentchar{%}
+\gdef\endfilecontents{|
+ \immediate\closeout\reserved@c
+ \def\T##1##2##3{|
+ \ifx##1\@undefined\else
+ \@latex@warning@no@line{##2 has been converted to Blank ##3e}|
+ \fi}|
+ \T\L{Form Feed}{Lin}|
+ \T\I{Tab}{Spac}|
+ \immediate\write\@unused{}}
+\global\let\endfilecontents*\endfilecontents
+\@onlypreamble\filecontents
+\@onlypreamble\endfilecontents
+\@onlypreamble\filecontents*
+\@onlypreamble\endfilecontents*
+\endgroup
+\@onlypreamble\filec@ntents
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%
+% \section{Package/class rollback mechanism}
+%
+%
+%
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexreleasefirst>
+% \end{macrocode}
+%
+% \changes{v1.2d}{2018/02/18}{Introduce rollback concept}
+%
+% \begin{macro}{\pkgcls@debug}
+% For testing we have a few extra lines of code that by default do
+% nothing but one can set |\pkgcls@debug| to |\typeout| to get
+% extra info. Sometime in the future this will be dropped.
+% \begin{macrocode}
+%<*tracerollback>
+%\let\pkgcls@debug\typeout
+\let\pkgcls@debug\@gobble
+%</tracerollback>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\requestedLaTeXdate}
+% The macro (!) |\requestedLaTeXdate| holds the globally requested
+% rollback date (via \texttt{latexrelease}) or zero if no such
+% request was made.
+% \begin{macrocode}
+\def\requestedLaTeXdate{0}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\pkgcls@targetdate}
+% \begin{macro}{\pkgcls@targetlabel}
+% \begin{macro}{\pkgcls@innerdate}
+%
+% If a rollback for a package or class is requested then
+% |\pkgcls@targetdate| holds the requested date as a number
+% YYYYMMDD (if there was one, otherwise the value of
+% |\requestedLaTeXdate|) and |\pkgcls@targetlabel| will be
+% empty. If there was a request for a named version then
+% |\pkgcls@targetlabel| holds the verion name and
+% |\pkgcls@targetdate| is set to \texttt{1}.
+%
+% |\pkgcls@targetdate=0| is used to indicate that there was no
+% rollback request.
+% While loading an old release |\pkgcls@targetdate| is also reset to
+% zero so that |\DeclareRelease| declarations are bypassed.
+%
+% In contrast |\pkgcls@innerdate| will always hold the requested
+% date (in a macro not a counter) if there was one, otherwise,
+% e.g., if there was no request or a request to a version name it
+% will contain \TeX{} largest legal number. While loading a file
+% this can be used to provide conditionals that select code based
+% on the request.
+%
+%
+% \begin{macrocode}
+\ifx\pkgcls@targetdate\@undefined
+ \newcount\pkgcls@targetdate
+\fi
+\let\pkgcls@targetlabel\@empty
+\def\pkgcls@innerdate{\maxdimen}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+
+% \begin{macro}{\pkgcls@candidate}
+% \begin{macro}{\pkgcls@releasedate}
+% When looping through the |\DeclareRelease| declarations we
+% record if the release is the best candidate we have seen so far.
+% This is recorded in |\pkgcls@candidate| and we update it whenever
+% we see a better one.
+%
+% In |\pkgcls@releasedate| we keep track of the release date of
+% that candidate.
+% \begin{macrocode}
+\let\pkgcls@candidate\@empty
+\let\pkgcls@releasedate\@empty
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\load@onefilewithoptions}
+% \begin{macro}{\@onefilewithoptions}
+% the best place to add the rollback code is at the point where
+% |\@onefilewithoptions| is called to load a single class or
+% package.
+%
+% To make things easy we save the old definition as
+% |\load@onefilewithoptions| and then provide a new interface.
+%
+% Important: as this code is also unconditionally placed into
+% latexrelease we can only do this name change once otherwise both
+% macros will contain the same code.
+% \begin{macrocode}
+\ifx\load@onefilewithoptions\@undefined
+ \let\load@onefilewithoptions\@onefilewithoptions
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \def\@onefilewithoptions#1[#2][#3]#4{%
+% \end{macrocode}
+% First a bit of tracing normally disabled.
+% \begin{macrocode}
+%<*tracerollback>
+ \pkgcls@debug{--- File loaded request (\noexpand\usepackage or ...)}%
+ \pkgcls@debug{\@spaces 1: #1}%
+ \pkgcls@debug{\@spaces 2: #2}%
+ \pkgcls@debug{\@spaces 3: #3}%
+ \pkgcls@debug{\@spaces 4: #4}%
+%</tracerollback>
+% \end{macrocode}
+% Two of the arguments are needed later on in error/warning
+% messages so we save them.
+% \begin{macrocode}
+ \def\pkgcls@name{#1}% % for info message
+ \def\pkgcls@arg {#3}% % for info message
+% \end{macrocode}
+% then we parse the final optional argument to determine if there
+% is a specific rollback request for the current file. This will
+% set |\pkgcls@targetdate|, |\pkgcls@targetlabel| and
+% |\pkgcls@mindate|.
+% \begin{macrocode}
+ \pkgcls@parse@date@arg{#3}%
+% \end{macrocode}
+% When determining the correct release to load we keep track of
+% candiates in |\pkgcls@candidate| and initially we don't have any:
+% \begin{macrocode}
+ \let\pkgcls@candidate\@empty
+% \end{macrocode}
+% If we had a rollback request then |#3| may contain data but not
+% necessarily a ``minimal date'' so instead of passing it on we
+% pass on the content of |\pkgcls@mindate|. We need to pass the
+% value not the command, otherwise nested packages may pick up the
+% wrong information.
+% \changes{v1.2h}{2018-04-08}{Pass expanded date}
+% \begin{macrocode}
+ \begingroup
+ \edef\reserved@a{%
+ \endgroup
+ \unexpanded{\load@onefilewithoptions#1[#2]}%
+ [\pkgcls@mindate]%
+ \unexpanded{#4}}%
+ \reserved@a
+ }
+\fi
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\pkgcls@parse@date@arg}
+% The |\pkgcls@parse@date@arg| command parses the second optional
+% argument of |\usepackage|, |\RequirePackage| or |\documentclass|
+% for a rollback request setting the values of |\pkgcls@targetdate|
+% and |\pkgcls@targetlabel|.
+%
+% This optional argument has a dual purpose: If it just contains a
+% date string then this means that the package should have at least
+% that date (to ensure that a certain feature is actually available,
+% or a certain bug has been fixed). When the package gets loaded the
+% information in |\Provides...| will then be checked against this
+% request.
+%
+% But if it starts with an equal sign followed by a date string or
+% followed by a version name then this means that we should roll
+% back to the state of the package at tht date or to the version
+% with the requested name.
+%
+% If there was no optional argument or the optional argument
+% does not start with ``\texttt{=}'' then the |\pkgcls@targetdate|
+% is set to the date of the overall rollback request (via
+% \texttt{latexrelease}) or if that was not given it is set to
+% \texttt{0}.
+% In either case |\pkgcls@targetlabel| will be made empty.
+%
+% If the argument doesn't start with ``\texttt{=}'' then it is
+% supposed to be a ``minimal date'' and we therefore save the value
+% in |\pkgcls@mindate|, otherwise this macro is made empty.
+%
+% So in summary we have:
+% \begin{flushleft}
+% \hspace*{-1in}\begin{tabular}{ccccc@{}}
+% Input & & \cs{pkgcls@targetdate}
+% & \cs{pkgcls@targetlabel}
+% & \cs{pkgcls@mindate}\\[3pt]
+% \meta{empty} & $\to$ & \meta{global-rollbackdate-as-number}
+% & \meta{empty} & \meta{empty}
+% \\
+% \meta{date} & $\to$ & \meta{global-rollbackdate-as-number}
+% & \meta{empty} & \meta{date}
+% \\
+% \texttt{=}\meta{date} & $\to$ & \meta{date-as-number}
+% & \meta{empty} & \meta{empty}
+% \\
+% \texttt{=}\meta{version}& $\to$ & \texttt{1}
+% & \meta{version} & \meta{empty}
+% \\
+% \meta{other} & $\to$ & \meta{global-rollbackdate-as-number}
+% & \meta{empty} & \meta{other}
+% \\
+% \end{tabular}
+% \end{flushleft}
+% where \meta{global-rollbackdate-as-number} is a date request given
+% via \texttt{latexrelease} or if there wasn't one \texttt{0}.
+%
+% \begin{macrocode}
+\def\pkgcls@parse@date@arg #1{%
+% \end{macrocode}
+% If the argument is empty we use the rollback date from
+% \texttt{latexrelease} which has the value of zero if there was no
+% rollback request. The label and the minimal date is made empty in that case.
+% \begin{macrocode}
+ \ifx\@nil#1\@nil
+ \pkgcls@targetdate\requestedLaTeXdate\relax
+ \let\pkgcls@targetlabel\@empty
+ \let\pkgcls@mindate\@empty
+% \end{macrocode}
+% Otherwise we parse the argument further, checking for a \texttt{=}
+% as the first character. We append a \texttt{=} at the end so that
+% there is at least one such character in the argument.
+% \begin{macrocode}
+ \else
+ \pkgcls@parse@date@arg@#1=\@nil\relax
+ \fi
+ }
+% \end{macrocode}
+% The actual parsing work then happens in |\pkgcls@parse@date@arg@|:
+% \begin{macrocode}
+\def\pkgcls@parse@date@arg@#1=#2\@nil{%
+% \end{macrocode}
+% We set |\pkgcls@targetdate| depending on the parsing result; the
+% code is expandable so we can do the parsing as part of the assignment.
+% \begin{macrocode}
+ \pkgcls@targetdate
+% \end{macrocode}
+% If a \texttt{=} was in first position then |#1| will be empty. In
+% that case |#2| will be the original argument with a \texttt{=}
+% appended.
+%
+% This can be parsed with |\@parse@version|, the trailing character
+% is simply ignored. This macro returns the parsed date as a number
+% (or zero if it wasn't a date) and accepts both YYYY/MM/DD and YYYY-MM-DD
+% formats.
+% \begin{macrocode}
+ \ifx\@nil#1\@nil
+ \@parse@version0#2//00\@nil\relax
+% \end{macrocode}
+% Whatever is returned is thus assigned to |\pkgcls@targetdate|
+% and therefore we can now test its value. If the value is zero we
+% assume that the remaining argument string represents a version
+% and change |\pkgcls@targetdate| and set |\pkgcls@targetlabel| to
+% the version name (after stripping off the trailing \texttt{=}.
+% \begin{macrocode}
+ \ifnum \pkgcls@targetdate=\z@
+ \pkgcls@targetdate\@ne
+ \def\pkgcls@innerdate{\maxdimen}%
+ \pkgcls@parse@date@arg@version#2%
+ \else
+ \edef\pkgcls@innerdate{\the\pkgcls@targetdate}%
+ \fi
+ \let\pkgcls@mindate\@empty
+ \else
+% \end{macrocode}
+% If |#1| was not empty then there wasn't a \texttt{=} character in
+% first position so we we are dealing either with a ``minimum
+% date'' or with some incorrect data. We assume the former and make
+% the following assignments (the first one finishing the assignment
+% of |\pkgcls@targetdate|):
+% \begin{macrocode}
+ \requestedLaTeXdate\relax
+ \let\pkgcls@targetlabel\@empty
+ \def\pkgcls@innerdate{\maxdimen}%
+ \def\pkgcls@mindate{#1}%
+% \end{macrocode}
+% If the min-date is after the requested rollback date (if there is
+% any, i.e., if it is not zero) then we have a conflict and
+% therefore issue a warning.
+% \changes{v1.2i}{2018/05/08}
+% {Make suspicious rollback a warning not error: github issue 43}
+% \begin{macrocode}
+ \ifnum \pkgcls@targetdate > \z@
+ \ifnum \@parse@version0#1//00\@nil > \pkgcls@targetdate
+ \@latex@warning@no@line{Suspicious rollback/min-date date given\MessageBreak
+ A minimal date of #1 has been specified for
+ \@cls@pkg\MessageBreak '\pkgcls@name'.\MessageBreak
+ But this is in conflict
+ with a rollback request to \requestedpatchdate}
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% Strip off te trailing \texttt{=} and assign the version name to
+% |\pkgcls@targetlabel|.
+% \begin{macrocode}
+\def\pkgcls@parse@date@arg@version#1={%
+ \def\pkgcls@targetlabel{#1}}
+% \end{macrocode}
+% \end{macro}
+
+
+
+
+% \begin{macro}{\DeclareRelease}
+% First argument is the ``name'' of the release and it can be left empty
+% if one doesn't like to give a name to the release.
+% The second argument is that from which on this release was
+% available (or should be used in case of minor updates).
+% The final argument is the external file name of this release, by
+% convention this should be
+% \meta{pkg/cls-name}\texttt{-}\meta{date}\texttt{.}\meta{extension}
+% but this is not enforced and through this argument one can
+% overwrite it.
+% \begin{macrocode}
+\def\DeclareRelease#1#2#3{%
+ \ifnum\pkgcls@targetdate>\z@ % some sort of rollback request
+%<*tracerollback>
+ \pkgcls@debug{---\string\DeclareRelease:}%
+ \pkgcls@debug{\@spaces 1: #1}%
+ \pkgcls@debug{\@spaces 2: #2}%
+ \pkgcls@debug{\@spaces 3: #3}%
+%</tracerollback>
+% \end{macrocode}
+% If the date argument |#2| is empty we are dealing with a special
+% release that should be only accessible via its name; a typical
+% use case would be a ``beta'' release. So if we are
+% currently processing a date request we ignore it and otherwise we
+% check if we can match the name and if so load the corresponding
+% release file.
+% \begin{macrocode}
+ \ifx\@nil#2\@nil
+ \ifnum\pkgcls@targetdate=\@ne % named request
+ \def\reserved@a{#1}%
+ \ifx\pkgcls@targetlabel\reserved@a
+ \pkgcls@use@this@release{#3}{}%
+%<*tracerollback>
+ \else
+ \pkgcls@debug{Label doesn't match}%
+%</tracerollback>
+ \fi
+%<*tracerollback>
+ \else
+ \pkgcls@debug{Date request: ignored}%
+%</tracerollback>
+ \fi
+ \else
+% \end{macrocode}
+% If the value of |\pkgcls@targetdate| is greater than 1 (or in
+% reality greater than something like 19930101) we are dealing with a
+% rollback request to a specific date.
+% \begin{macrocode}
+ \ifnum\pkgcls@targetdate>\@ne % a real request
+% \end{macrocode}
+% So we parse the date of this release to check if it is before or
+% after the request date.
+% \begin{macrocode}
+ \ifnum\@parse@version#2//00\@nil
+ >\pkgcls@targetdate
+% \end{macrocode}
+% If it is after we have to distinguish between two cases: If there
+% was an earlier candidate we use that one because the other is too
+% late, but if there wasn't one (i.e., if current release is the
+% oldest that exists) we use it as the best choice. However in
+% that case something is wrong (as there shouldn't be a rollback to
+% a date where a package used doesn't yet exists. So we make a
+% complained to the user.
+% \begin{macrocode}
+ \ifx\pkgcls@candidate\@empty
+ \pkgcls@rollbackdate@error{#2}%
+ \pkgcls@use@this@release{#3}{#2}%
+ \else
+ \pkgcls@use@this@release\pkgcls@candidate
+ \pkgcls@releasedate
+ \fi
+ \else
+% \end{macrocode}
+% Otherwise, if the release date of this version is before the
+% target rollback and we record it as a candidate. But we don't use
+% it yet as there may be another release which is still before the
+% target rollback.
+% \begin{macrocode}
+ \def\pkgcls@candidate{#3}%
+ \def\pkgcls@releasedate{#2}%
+%<*tracerollback>
+ \pkgcls@debug{New candidate: #3}%
+%</tracerollback>
+ \fi
+ \else
+% \end{macrocode}
+% If we end up in this branch we have a named version request. So
+% we check if |\pkgcls@targetlabel| matches the current name and if
+% yes we use this release immediately, otherwise we do nothing as a
+% later declaration may match it.
+% \begin{macrocode}
+ \def\reserved@a{#1}%
+ \ifx\pkgcls@targetlabel\reserved@a
+ \pkgcls@use@this@release{#3}{#2}%
+%<*tracerollback>
+ \else
+ \pkgcls@debug{Label doesn't match}%
+%</tracerollback>
+ \fi
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+
+
+
+
+% \begin{macro}{\pkgcls@use@this@release}
+% If a certain release has been selected (stored in the external
+% file given in \verb=#1=) we need to input it and afterwards stop
+% reading the current file.
+% \begin{macrocode}
+\def\pkgcls@use@this@release#1#2{%
+% \end{macrocode}
+% Before that we record the selection made inside the transcript.
+% \begin{macrocode}
+ \pkgcls@show@selection{#1}{#2}%
+% \end{macrocode}
+% We then set the |\pkgcls@targetdate| to zero so that any
+% |\DeclareRelease| or |\DeclareCurrentRelease| in the file we
+% now load are bypassed\footnote{The older release may also have
+% such declarations inside if it was a simply copy of the
+% \texttt{.sty} or \texttt{.cls} file current at that
+% date. Removing these declarations would make the file load a tiny
+% bit faster, but this way it works in any case.} and then we
+% finally load the correct release.
+%
+% After loading that file we need to stop reading the current file
+% so we issue |\endinput|. Note that the |\relax| before that is
+% essential to ensure that the |\endinput| is only happening after
+% the file has been fully processed, otherwise it would act after the
+% first line of the |\@@input|!
+% \changes{v1.2e}{2018/03/24}
+% {Use full file name for old release}
+% \begin{macrocode}
+ \pkgcls@targetdate\z@
+ \@@input #1\relax
+ \endinput
+}
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\pkgcls@show@selection}
+% This command records what selection was made. As that is needed
+% in two places (and it is rather lengthly) it was placed in a
+% separate command. The first argument is the name of the external
+% file that is being loaded and is only needed for debugging. The
+% second argument is the date that corresponds to this file and it
+% is used as part of the message.
+% \begin{macrocode}
+\def\pkgcls@show@selection#1#2{%
+%<*tracerollback>
+ \pkgcls@debug{Result: use #1}%
+%</tracerollback>
+ \GenericInfo
+ {\@spaces\@spaces\space}{Rollback for
+ \@cls@pkg\space'\@currname' requested ->
+ \ifnum\pkgcls@targetdate>\@ne
+ date
+ \ifnum\requestedLaTeXdate=\pkgcls@targetdate
+ \requestedpatchdate
+ \else
+ \expandafter\@gobble\pkgcls@arg
+ \fi.\MessageBreak
+% \end{macrocode}
+% Instead of ``best approximation'' we could say that we have been
+% able to exactly match the date (if it is exact), but that would
+% mean extra tests without much gain, so not done.
+% \begin{macrocode}
+ Best approximation is
+ \else
+ version '\pkgcls@targetlabel'.\MessageBreak
+ This corresponds to
+ \fi
+ \ifx\@nil#2\@nil
+ a special release%
+ \else
+ the release introduced on #2%
+ \fi
+ \@gobble}%
+}
+% \end{macrocode}
+% \end{macro}
+
+
+% \begin{macro}{\pkgcls@rollbackdate@error}
+% This is called if the requested rollback date is earlier than the
+% earliest known release of a package or class.
+%
+% A similar error is given if global rollback date and min-date on
+% a specific package conflict with each other, but that case is
+% happens only once so it is is inlined.
+% \begin{macrocode}
+\def\pkgcls@rollbackdate@error#1{%
+ \@latex@error{Suspicious rollback date given}%
+ {The \@cls@pkg\space'\@currname' claims that it
+ came into existence on #1 which\MessageBreak
+ is after your requested rollback date --- so
+ something is wrong here.\MessageBreak
+ Continue and we use the earliest known release.}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\DeclareCurrentRelease}
+% This declares the date (and possible name) of the current version
+% of a package or class.
+% \begin{macrocode}
+\def\DeclareCurrentRelease#1#2{%
+% \end{macrocode}
+% First we test if |\pkgcls@targetdate| is greater than zero,
+% otherwise this code is bypassed (as there is no rollback
+% request).
+% \begin{macrocode}
+ \ifnum\pkgcls@targetdate>\z@ % some sort of rollback request
+%<*tracerollback>
+ \pkgcls@debug{---DeclareCurrentRelease}%
+ \pkgcls@debug{ 1: #1}%
+ \pkgcls@debug{ 2: #2}%
+%</tracerollback>
+% \end{macrocode}
+% If the value is greater than 1 we have to deal with a date
+% request, so we parse |#2| as a date and compare it with
+% |\pkgcls@targetdate|.
+% \begin{macrocode}
+ \ifnum\pkgcls@targetdate>\@ne % a date request
+ \ifnum\@parse@version#2//00\@nil
+ >\pkgcls@targetdate
+% \end{macrocode}
+% If it is greater that means the release date if this file is
+% later than the requested rollback date. Again we have two cases:
+% If there was a previous candidate release we use that one as the
+% current release is too young, but if there wasn't we have to use
+% this release nevertheless as there isn't any alternative.
+%
+% However this case can only happen if there is a
+% |\DeclareCurrentRelease| but no declared older releases (so
+% basically the use of the declaration is a bit dubious).
+% \begin{macrocode}
+
+ \ifx\pkgcls@candidate\@empty
+ \pkgcls@rollbackdate@error{#2}%
+ \else
+ \pkgcls@use@this@release\pkgcls@candidate
+ \pkgcls@releasedate
+ \fi
+% \end{macrocode}
+% Otherwise the curent file is the right release, so we record that
+% in the transcript and then carry on.
+% \begin{macrocode}
+ \else
+ \pkgcls@show@selection{current version}{#2}%
+ \fi
+ \else % a label request
+% \end{macrocode}
+% Otherwise we have a rollback request to a named version so we
+% check if that fits the current name and if not give an error as
+% this was the last possible opportunity.
+% \begin{macrocode}
+ \def\reserved@a{#1}%
+ \ifx\pkgcls@targetlabel\reserved@a
+ \pkgcls@show@selection{current version}{#2}%
+ \else
+ \@latex@error{Requested version '\pkgcls@targetlabel' for
+ \@cls@pkg\space'\@currname' is unknown}\@ehc
+ \fi
+ \fi
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+
+% \begin{macro}{\IfTargetDateBefore}
+% This enables a simple form of conditional code inside a class or
+% package file. If there is a date request and the request date is
+% earlier than the first argument the code in the second argument
+% is processed otherwise the code in the third argument is
+% processed. If there was no date request then we also execute the
+% third argument, i.e., we will get the ``latest'' version of the
+% file.
+%
+% Most often the second argument (before-date-code) will be empty.
+% \begin{macrocode}
+\long\def\IfTargetDateBefore#1{%
+ \ifnum\pkgcls@innerdate <%
+ \expandafter\@parse@version\expandafter0#1//00\@nil
+ \typeout{Exclude code introduced on #1}%
+ \expandafter\@firstoftwo
+ \else
+ \typeout{Include code introduced on #1}%
+ \expandafter\@secondoftwo
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</2ekernel|latexreleasefirst>
+% \end{macrocode}
+%
+%
+% \section{After Preamble}
+% Finally we declare a package that allows all the commands declared
+% above to be |\@onlypreamble| to be used after |\begin{document}|.
+% \changes{v0.3f}{1994/03/16}
+% {Add pkgindoc package}
+% \changes{v1.1a}{1998/03/21}
+% {Correct to new onlypreamble command list}
+% \begin{macrocode}
+%<*afterpreamble>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{pkgindoc}
+ [1994/10/20 v1.1 Package Interface in Document (DPC)]
+\def\reserved@a#1\do\@classoptionslist#2\do\filec@ntents#3\relax{%
+ \gdef\@preamblecmds{#1#3}}
+\expandafter\reserved@a\@preamblecmds\relax
+%</afterpreamble>
+% \end{macrocode}
+%
+% \Finale