The main structure of documents

Frank Mittelbach  Chris Rowley  Alan Jeffrey

David Carlisle

1995/11/14

1 Introduction

This file implements the following declarations, which replace \documentstyle in L^{A}TEX 2ε 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 L^{A}TEX 2ε and L^{A}TEX2.09 is that L^{A}TEX 2ε 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.

2 User interface

\documentclass[⟨main-option-list⟩]{⟨class⟩}[⟨version⟩]

There must be exactly one such declaration, and it must come first. The ⟨main-option-list⟩ is a list of options which can modify the formatting of elements which are defined in the ⟨class⟩ file as well as in all following \usepackage declarations (see below). The ⟨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.

\documentstyle[⟨main-option-list⟩]{⟨class⟩}[⟨version⟩]

The \documentstyle declaration is kept in order to maintain upward compatibility with L^{A}TEX2.09 documents. It is similar to \documentclass, but it causes all options in ⟨main-option-list⟩ that the ⟨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 L^{A}TEX2.09 compatibility mode. As far as most packages are concerned, this only affects the warnings and errors L^{A}TEX generates. This flag does affect the definition of font commands, and \sloppy.

\usepackage[⟨package-option-list⟩]{⟨package-list⟩}[⟨version⟩]

There can be any number of these declarations. All packages in ⟨package-list⟩ are called with the same options.

Each ⟨package⟩ file defines new elements (or modifies those defined in the ⟨class⟩), and thus extends the range of documents which can be processed. The ⟨package-option-list⟩ is a list of options which can modify the formatting of elements defined in the ⟨package⟩ file. The ⟨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 ⟨package-option-list⟩, each package processes the ⟨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.

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.

The environment is allowed only before \documentclass to ensure that all packages or options necessary for this particular run are present when needed.

2.1 Option processing

When the options are processed, they are divided into two types: local and global:

• For a class, the options in the \documentclass command are local.

• For a package, the options in the \usepackage command are local, and the options in the \documentclass command are global.

The options for \documentclass and \usepackage are processed in the following way:

1. 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.

2. 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.

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.

3 Class and Package interface

3.1 Class name and version

\ProvidesClass A class can identify itself with the \ProvidesClass{⟨name⟩}[⟨version⟩] command. The ⟨version⟩ should begin with a date in the format YYYY/MM/DD.

3.2 Package name and version

\ProvidesPackage A package can identify itself with the \ProvidesPackage{⟨name⟩}[⟨version⟩] command. The ⟨version⟩ should begin with a date in the format YYYY/MM/DD.

3.3 Requiring other packages

\RequirePackage Packages or classes can load other packages using \RequirePackage[⟨options⟩]{⟨name⟩}[⟨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.

\LoadClass Similar to \RequirePackage, but for classes, may not be used in package files.

\PassOptionsToPackage Packages can pass options to other packages using:

\PassOptionsToPackage{⟨options⟩}{⟨package⟩}.

\PassOptionsToClass This adds the ⟨options⟩ to the options list of any future \RequirePackage or \usepackage command. For example:

    \PassOptionsToPackage{foo,bar}{fred}
    \RequirePackage[baz]{fred}

is the same as:

    \RequirePackage[foo,bar,baz]{fred}
\LoadClassWithOptions      \LoadClassWithOptions{⟨name⟩}[⟨version⟩]:

This is similar to \LoadClass, but it always calls class ⟨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.

\RequirePackageWithOptions  \RequirePackageWithOptions is the analogous command for packages.

This is mainly intended to allow one class to simply build on another, for example:

   \LoadClassWithOptions{article}

This should be contrasted with the slightly different construction

   \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
   \ProcessOptions
   \LoadClass{article}

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:

   \DeclareOption{landscape}{...}
   \ProcessOptions
   \LoadClassWithOptions{article}

with:

   \DeclareOption{landscape}{...}
   \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
   \ProcessOptions
   \LoadClass{article}

In the first case, the 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 article is only passed options by the default option handler, which is not used for landscape as that option is explicitly declared.

\@ifpackageloaded To find out if a package has already been loaded, use

\@ifclassloaded  \@ifpackageloaded{⟨package⟩}{⟨true⟩}{⟨false⟩}.

\@ifpackagelater To find out if a package has already been loaded with a version more recent \@ifclasslater than ⟨version⟩, use \@ifpackagelater{⟨package⟩}{⟨version⟩}{⟨true⟩}{⟨false⟩}. \@ifpackagewith To find out if a package has already been loaded with at least the options

\@ifclasswith ⟨options⟩, use \@ifpackagewith{⟨package⟩}{⟨options⟩}{⟨true⟩}{⟨false⟩}.

3.4 Declaring new options

Options for classes and packages are built using the same macros.

\DeclareOption To define a builtin option, use \DeclareOption{⟨name⟩}{⟨code⟩}. \DeclareOption* To define the default action to perform for local options which have not been

declared, use \DeclareOption*{⟨code⟩}.

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}{⟨pkg-name⟩}

Handle the the current option by passing it on to the package ⟨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.

3.5 Safe Input Macros

\InputIfFileExists  \InputIfFileExists{⟨file⟩}{⟨then⟩}{⟨else⟩}

Inputs ⟨file⟩ if it exists. Immediately before the input, ⟨then⟩ is executed. Otherwise ⟨else⟩ is executed.

\IfFileExists As above, but does not input the file.

One thing you might like to put in the ⟨else⟩ clause is

\@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,

\input This has been redefined from the L^{A}TEX2.09 definition, in terms of the new

commands \InputIfFileExists and \@missingfileerror.

\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.

4 Implementation

1 ⟨∗2ekernel⟩

\if@compatibility The flag for compatibilty mode.

 2 \newif\if@compatibility

\@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.

 3 \def\@documentclasshook{%
 4 \ifx\@normalsize\@undefined
 5  \let\@normalsize\normalsize
 6 \fi
 7 }

\@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@⟨option⟩ commands are executed. All local ⟨option⟩s which are not declared will be processed in the order defined by the

optional argument of \documentclass or \usepackage.
 8 \let\@declaredoptions\@empty

\@classoptionslist List of options of the main class.

 9 \let\@classoptionslist\relax

\@unusedoptionlist List of options of the main class that haven’t been declared or loaded as class option files.

10 \let\@unusedoptionlist\@empty

\CurrentOption Name of current package or option.

11 \let\CurrentOption\@empty

\@currname Name of current package or option.

12 \let\@currname\@empty

\@currext The current file extension.

13 \global\let\@currext=\@empty
\@clsextension \@pkgextension The two possible values of \@currext.
14 \def\@clsextension{cls}
15 \def\@pkgextension{sty}
16 \@onlypreamble\@clsextension
17 \@onlypreamble\@pkgextension

\@pushfilename \@popfilename \@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.

18 \def\@pushfilename{%
19 \xdef\@currnamestack{%
20  {\@currname}%
21  {\@currext}%
22  {\the\catcode`\@}%
23  \@currnamestack}}
24 \@onlypreamble\@pushfilename
25 \def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil}
26 \@onlypreamble\@popfilename
27 \def\@p@pfilename#1#2#3#4\@nil{%
28 \gdef\@currname{#1}%
29 \gdef\@currext{#2}%
30 \catcode`\@#3\relax
31 \gdef\@currnamestack{#4}}
32 \@onlypreamble\@p@pfilename

33 \gdef\@currnamestack{}
34 \@onlypreamble\@currnamestack

\@ptionlist Returns the option list of the file.

35 \def\@ptionlist#1{%
36 \@ifundefined{opt@#1}\@empty{\csname opt@#1\endcsname}}
37 \@onlypreamble\@ptionlist
\@ifpackageloaded \@ifclassloaded  \@ifpackageloaded{⟨name⟩} Checks to see whether a file has been loaded.
38 \def\@ifpackageloaded{\@ifl@aded\@pkgextension}
39 \def\@ifclassloaded{\@ifl@aded\@clsextension}
40 \@onlypreamble\@ifpackageloaded
41 \@onlypreamble\@ifclassloaded
42 \def\@ifl@aded#1#2{%
43 \expandafter\ifx\csname ver@#2.#1\endcsname\relax
44  \expandafter\@secondoftwo
45 \else
46  \expandafter\@firstoftwo
47 \fi}
48 \@onlypreamble\@ifl@aded
\@ifpackagelater \@ifclasslater  \@ifpackagelater{⟨name⟩}{YYYY/MM/DD} Checks that the package loaded is

more recent than the given date.

49 \def\@ifpackagelater{\@ifl@ter\@pkgextension}
50 \def\@ifclasslater{\@ifl@ter\@clsextension}
51 \@onlypreamble\@ifpackagelater
52 \@onlypreamble\@ifclasslater
53 \def\@ifl@ter#1#2{%
54 \expandafter\@ifl@t@r
55  \csname ver@#2.#1\endcsname}
56 \@onlypreamble\@ifl@ter

This internal macro is also used in \NeedsTeXFormat.

57 \def\@ifl@t@r#1#2{%
58 \ifnum\expandafter\@parse@version#1//00\@nil<%
59  \expandafter\@parse@version#2//00\@nil
60  \expandafter\@secondoftwo
61 \else
62  \expandafter\@firstoftwo
63 \fi}
64 \@onlypreamble\@ifl@t@r
65 \def\@parse@version#1/#2/#3#4#5\@nil{#1#2#3#4 }
66 \@onlypreamble\@parse@version

\@ifpackagewith \@ifclasswith \@ifpackagewith{⟨name⟩}{⟨option-list⟩} Checks that ⟨option-list⟩ is a subset of the options with which ⟨name⟩ was loaded.

67 \def\@ifpackagewith{\@if@ptions\@pkgextension}
68 \def\@ifclasswith{\@if@ptions\@clsextension}

69 \@onlypreamble\@ifpackagewith
70 \@onlypreamble\@ifclasswith
71 \def\@if@ptions#1#2{%
72 \@expandtwoargs\@if@pti@ns{\@ptionlist{#2.#1}}}
73 \@onlypreamble\@if@ptions

Probably shouldnt use \CurrentOption here… (changed to \reserved@b.)

74 \def\@if@pti@ns#1#2{%
75 \let\reserved@a\@firstoftwo
76 \@for\reserved@b:=#2\do{%
77  \expandafter\in@\expandafter{\expandafter,\reserved@b,}{,#1,}%
78  \ifin@\else\let\reserved@a\@secondoftwo\fi}%
79 \reserved@a}
80 \@onlypreamble\@if@pti@ns

\ProvidesPackage Checks that the current filename is correct, and defines \ver@filename.

81 \def\ProvidesPackage#1{%
82 \xdef\@gtempa{#1}%
83 \ifx\@gtempa\@currname\else
84  \@latex@warning@no@line{You have requested
85  \@cls@pkg\space`\@currname',\MessageBreak
86  but the \@cls@pkg\space provides `#1'}%
87 \fi
88 \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%]
89 \@onlypreamble\ProvidesPackage
90 \def\@pr@videpackage[#1]{%
91 \expandafter\xdef\csname ver@\@currname.\@currext\endcsname{#1}%
92 \ifx\@currext\@clsextension
93  \typeout{Document Class: \@gtempa\space#1}%
94 \else
95  \wlog{Package: \@gtempa\space#1}%
96 \fi}
97 \@onlypreamble\@pr@videpackage
\ProvidesClass Like \ProvidesPackage, but for classes.
98 \let\ProvidesClass\ProvidesPackage
99 \@onlypreamble\ProvidesClass
\ProvidesFile Like \ProvidesPackage, but for arbitrary files. Do not apply \@onlypreamble to

these, as we may want to label files input during the document.

\@providesfile
100 \def\ProvidesFile#1{%
101 \begingroup
102  \catcode`\ 10 %
103  \@makeother\/%
104  \@ifnextchar[{\@providesfile{#1}}{\@providesfile{#1}[]}}

During initex a special version of \@providesfile is used. The real definition is installed right at the end, in ltfinal.dtx.

 \def\@providesfile#1[#2]{%
     \wlog{File: #1 #2}%
     \expandafter\xdef\csname ver@#1\endcsname{#2}%
   \endgroup}
     \end{macrocode}

\PassOptionsToPackage \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.

105 \def\@pass@ptions#1#2#3{%
106 \expandafter\xdef\csname opt@#3.#1\endcsname{%
107  \@ifundefined{opt@#3.#1}\@empty
108  {\csname opt@#3.#1\endcsname,}%
109  \zap@space#2 \@empty}}
110 \@onlypreamble\@pass@ptions
111 \def\PassOptionsToPackage{\@pass@ptions\@pkgextension}
112 \def\PassOptionsToClass{\@pass@ptions\@clsextension}
113 \@onlypreamble\PassOptionsToPackage
114 \@onlypreamble\PassOptionsToClass
\DeclareOption \DeclareOption* Adds an option as a \ds@ command, or the default \default@ds command.
115 \def\DeclareOption{%
116 \let\@fileswith@pti@ns\@badrequireerror
117 \@ifstar\@defdefault@ds\@declareoption}
118 \long\def\@declareoption#1#2{%
119 \xdef\@declaredoptions{\@declaredoptions,#1}%
120 \toks@{#2}%
121 \expandafter\edef\csname ds@#1\endcsname{\the\toks@}}
122 \long\def\@defdefault@ds#1{%
123 \toks@{#1}%
124 \edef\default@ds{\the\toks@}}
125 \@onlypreamble\DeclareOption
126 \@onlypreamble\@declareoption
127 \@onlypreamble\@defdefault@ds

\OptionNotUsed If we are in a class file, add \CurrentOption to the list of unused options. Otherwise, in a package file do nothing.

128 \def\OptionNotUsed{%
129 \ifx\@currext\@clsextension
130  \xdef\@unusedoptionlist{%
131  \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
132  \CurrentOption}%
133 \fi}
134 \@onlypreamble\OptionNotUsed

\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*.

135 % \let\default@ds\OptionNotUsed
\ProcessOptions \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.

136 \def\ProcessOptions{%
137 \let\ds@\@empty
138 \edef\@curroptions{\@ptionlist{\@currname.\@currext}}%
139 \@ifstar\@xprocess@ptions\@process@ptions}
140 \@onlypreamble\ProcessOptions
141 \def\@process@ptions{%
142 \@for\CurrentOption:=\@declaredoptions\do{%
143  \ifx\CurrentOption\@empty\else
144  \@expandtwoargs\in@{,\CurrentOption,}{%
145  ,\ifx\@currext\@clsextension\else\@classoptionslist,\fi
146  \@curroptions,}%
147  \ifin@
148  \@use@ption
149  \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
150  \fi
151  \fi}%
152 \@process@pti@ns}
153 \@onlypreamble\@process@ptions
154 \def\@xprocess@ptions{%
155 \ifx\@currext\@clsextension\else
156  \@for\CurrentOption:=\@classoptionslist\do{%
157  \ifx\CurrentOption\@empty\else
158  \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}%
159  \ifin@
160  \@use@ption
161  \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
162  \fi
163  \fi}%
164 \fi
165 \@process@pti@ns}
166 \@onlypreamble\@xprocess@ptions
    The common part of \ProcessOptions and \ProcessOptions*.
167 \def\@process@pti@ns{%
168 \@for\CurrentOption:=\@curroptions\do{%
169  \@ifundefined{ds@\CurrentOption}%
170  {\@use@ption
171  \default@ds}%

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@… directly, and so have options which do not appear

 in \@declaredoptions.
172  \@use@ption}%

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.

173 \@for\CurrentOption:=\@declaredoptions\do{%
174  \expandafter\let\csname ds@\CurrentOption\endcsname\relax}%
175 \let\CurrentOption\@empty
176 \let\@fileswith@pti@ns\@@fileswith@pti@ns
177 \AtEndOfPackage{\let\@unprocessedoptions\relax}}
178 \@onlypreamble\@process@pti@ns

\@options \@options is a synonym for \ProcessOptions* for upward compatibility with L^{A}TEX2.09 style files.

179 \def\@options{\ProcessOptions*}
180 \@onlypreamble\@options

\@use@ption Execute the code for the current option.

181 \def\@use@ption{%
182 \@expandtwoargs\@removeelement\CurrentOption
183 \@unusedoptionlist\@unusedoptionlist
184 \csname ds@\CurrentOption\endcsname}
185 \@onlypreamble\@use@ption

\ExecuteOptions \ExecuteOptions{⟨option-list⟩} executes the code declared for each option.

186 \def\ExecuteOptions#1{%
187 \def\reserved@a##1\@nil{%
188  \@for\CurrentOption:=#1\do{\csname ds@\CurrentOption\endcsname}%
189  \edef\CurrentOption{##1}}%
190 \expandafter\reserved@a\CurrentOption\@nil}
191 \@onlypreamble\ExecuteOptions

The top-level commands, which just set some parameters then call the internal

 command, \@fileswithoptions.

\documentclass The main new-style class declaration.

192 \def\documentclass{%
193 \let\documentclass\@twoclasseserror
194 \if@compatibility\else\let\usepackage\RequirePackage\fi
195 \@fileswithoptions\@clsextension}
196 \@onlypreamble\documentclass

\documentstyle 2.09 style class ‘style’ declaration.

197 \def\documentstyle{%

198 \makeatletter\input{latex209.def}\makeatother
199 \documentclass}
200 \@onlypreamble\documentstyle

\RequirePackage Load package if not already loaded.

201 \def\RequirePackage{%
202 \@fileswithoptions\@pkgextension}
203 \@onlypreamble\RequirePackage
\LoadClass Load class.
204 \def\LoadClass{%
205 \ifx\@currext\@pkgextension
206  \@latex@error
207  {\noexpand\LoadClass in package file}%
208  {You may only use \noexpand\LoadClass in a class file.}%
209 \fi
210 \@fileswithoptions\@clsextension}
211 \@onlypreamble\LoadClass

\@loadwithoptions Pass the current option list on to a class or package. #1 is \@cls-or-pkgextension, #2 is \RequirePackage or \LoadClass, #3 is the class or package to be loaded.

212 \def\@loadwithoptions#1#2#3{%
213 \expandafter\let\csname opt@#3.#1\expandafter\endcsname
214  \csname opt@\@currname.\@currext\endcsname
215 #2{#3}}
216 \@onlypreamble\@loadwithoptions

\LoadClassWithOptions Load class ‘#1’ with the current option list.

217 \def\LoadClassWithOptions{%
218 \@loadwithoptions\@clsextension\LoadClass}
219 \@onlypreamble\LoadClassWithOptions

\RequirePackageWithOptions Load package ‘#1’ with the current option list.

220 \def\RequirePackageWithOptions{%
221 \@loadwithoptions\@pkgextension\RequirePackage}
222 \@onlypreamble\RequirePackageWithOptions

\usepackage To begin with, \usepackage produces an error. This is reset by \documentclass.

223 \def\usepackage#1#{%
224 \@latex@error
225  {\noexpand \usepackage before \string\documentclass}%
226  {\noexpand \usepackage may only appear in the document
227  preamble, i.e.,\MessageBreak
228  between \noexpand\documentclass and
229  \string\begin{document}.}%
230 \@gobble}
231 \@onlypreamble\usepackage

\NeedsTeXFormat Check that the document is running on the correct system.

232 \def\NeedsTeXFormat#1{%
233 \def\reserved@a{#1}%
234 \ifx\reserved@a\fmtname
235  \expandafter\@needsformat
236 \else
237  \@latex@error{This file needs format `\reserved@a'%
238  \MessageBreak but this is `\fmtname'}{%
239  The current input file will not be processed
240  further,\MessageBreak
241  because it was written for some other flavor of
242  TeX.\MessageBreak\@ehd}%

If the file is not meant to be processed by L^{A}TEX 2ε we stop inputting it, but we do not end the run. We just end inputting the current file.

243  \endinput \fi}
244 \@onlypreamble\NeedsTeXFormat
245 \def\@needsformat{%
246 \@ifnextchar[%]
247  \@needsf@rmat
248  {}}
249 \@onlypreamble\@needsformat
250 \def\@needsf@rmat[#1]{%
251  \@ifl@t@r\fmtversion{#1}{}%
252  {\@latex@warning@no@line
253  {You have requested release `#1' of LaTeX,\MessageBreak
254  but only release `\fmtversion' is available}}}
255 \@onlypreamble\@needsf@rmat

\zap@space \zap@space foo⟨space⟩\@empty removes all spaces from foo that are not protected by { } groups.

256 \def\zap@space#1 #2{%
257 #1%
258 \ifx#2\@empty\else\expandafter\zap@space\fi
259 #2}
\@fileswithoptions The common part of \documentclass and \usepackage.
260 \def\@fileswithoptions#1{%
261 \@ifnextchar[%]
262  {\@fileswith@ptions#1}%
263  {\@fileswith@ptions#1[]}}
264 \@onlypreamble\@fileswithoptions
265 \def\@fileswith@ptions#1[#2]#3{%
266 \@ifnextchar[%]
267 {\@fileswith@pti@ns#1[#2]#3}%
268 {\@fileswith@pti@ns#1[#2]#3[]}}
269 \@onlypreamble\@fileswith@ptions

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.

270 \def\@fileswith@pti@ns#1[#2]#3[#4]{%
271 \ifx#1\@clsextension
272  \ifx\@classoptionslist\relax
273  \xdef\@classoptionslist{\zap@space#2 \@empty}%
274  \def\reserved@a{%
275  \@onefilewithoptions#3[#2][#4]#1%
276  \@documentclasshook}%
277  \else
278  \def\reserved@a{%
279  \@onefilewithoptions#3[#2][#4]#1}%
280  \fi
281 \else

build up a list of calls to \@onefilewithoptions (one for each package) without thrashing the parameter stack.

282  \def\reserved@b##1,{%
283  \ifx\@nil##1\relax\else
284  \ifx\relax##1\relax\else
285  \noexpand\@onefilewithoptions##1[#2][#4]\noexpand\@pkgextension
286  \fi
287  \expandafter\reserved@b
288  \fi}%
289  \edef\reserved@a{\zap@space#3 \@empty}%
290  \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nil,}%
291 \fi
292 \reserved@a}
293 \@onlypreamble\@fileswith@pti@ns

Have the main argument as #1, so we only need one \expandafter above.

294 \def\@onefilewithoptions#1[#2][#3]#4{%
295 \@pushfilename
296 \xdef\@currname{#1}%
297 \global\let\@currext#4%
298 \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty
299 \let\CurrentOption\@empty
300 \@reset@ptions
301 \makeatletter

Grab everything in a macro, so the parameter stack is popped before any processing begins.

302 \def\reserved@a{%
303  \@ifl@aded\@currext{#1}%
304  {\@if@ptions\@currext{#1}{#2}{}%
305  {\@latex@error
306  {Option clash for \@cls@pkg\space #1}%
307  {The package #1 has already been loaded
308  with options:\MessageBreak
309  \space\space[\@ptionlist{#1.\@currext}]\MessageBreak
310  There has now been an attempt to load it
311  with options\MessageBreak
312  \space\space[#2]\MessageBreak
313  Adding the line:\MessageBreak
314  \space\space\string\usepackage
315  [\@ptionlist{#1.\@currext},#2]{#1}\MessageBreak
316  to your document may fix this.\MessageBreak
317  Try typing \space <return> \space to proceed.}}}%
318  {\@pass@ptions\@currext{#2}{#1}%
319  \global\expandafter
320  \let\csname ver@\@currname.\@currext\endcsname\@empty
321  \InputIfFileExists
322  {\@currname.\@currext}%
323  {}%
324  {\@missingfileerror\@currname\@currext}%

\@unprocessedoptions will generate an error for each specified option in a package unless a \ProcessOptions has appeared in the package file.

325  \let\@unprocessedoptions\@@unprocessedoptions
326  \csname\@currname.\@currext-h@@k\endcsname
327  \expandafter\let\csname\@currname.\@currext-h@@k\endcsname
328  \@undefined
329  \@unprocessedoptions}
330  \@ifl@ter\@currext{#1}{#3}{}%
331  {\@latex@warning@no@line
332  {You have requested,\on@line,
333  version\MessageBreak
334  `#3' of \@cls@pkg\space #1,\MessageBreak
335  but only version\MessageBreak
336  `\csname ver@#1.\@currext\endcsname'\MessageBreak
337  is available}}%
338  \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi
339  \@popfilename
340  \@reset@ptions}%
341 \reserved@a}
342 \@onlypreamble\@onefilewithoptions

\@@fileswith@pti@ns Save the definition (for error checking).

343 \let\@@fileswith@pti@ns\@fileswith@pti@ns
344 \@onlypreamble\@@fileswith@pti@ns

\@reset@ptions Reset the default option, and clear lists of declared options.

345 \def\@reset@ptions{%
346 \global\ifx\@currext\@clsextension
347  \let\default@ds\OptionNotUsed
348 \else
349  \let\default@ds\@unknownoptionerror
350 \fi
351 \global\let\ds@\@empty
352 \global\let\@declaredoptions\@empty}
353 \@onlypreamble\@reset@ptions

4.1 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.

\@begindocumenthook \@enddocumenthook Stuff to appear at the begining or end of the document.

354 \ifx\@begindocumenthook\@undefined
355 \let\@begindocumenthook\@empty
356 \fi
357 \let\@enddocumenthook\@empty

\g@addto@macro Globally add to the end of a macro.

358 \long\def\g@addto@macro#1#2{{%
359 \toks@\expandafter{#1#2}%
360 \xdef#1{\the\toks@}}}
\AtEndOfPackage \AtEndOfClass \AtBeginDocument \AtEndDocument The access functions.
361 \def\AtEndOfPackage{%
362 \expandafter\g@addto@macro\csname\@currname.\@currext-h@@k\endcsname}
363 \let\AtEndOfClass\AtEndOfPackage
364 \@onlypreamble\AtEndOfPackage
365 \@onlypreamble\AtEndOfClass
366 \def\AtBeginDocument{\g@addto@macro\@begindocumenthook}
367 \def\AtEndDocument{\g@addto@macro\@enddocumenthook}
368 \@onlypreamble\AtBeginDocument

\@cls@pkg The current file type.

369 \def\@cls@pkg{%
370 \ifx\@currext\@clsextension
371  document class%
372 \else
373  package%
374 \fi}
375 \@onlypreamble\@cls@pkg

\@unknownoptionerror Bad option.
376 \def\@unknownoptionerror{%
377 \@latex@error
378  {Unknown option `\CurrentOption' for \@cls@pkg\space`\@currname'}%
379  {The option `\CurrentOption' was not declared in
380  \@cls@pkg\space`\@currname', perhaps you\MessageBreak
381  misspelled its name.
382  Try typing \space <return>
383  \space to proceed.}}
384 \@onlypreamble\@unknownoptionerror

\@@unprocessedoptions Declare an error for each option, unless a \ProcessOptions occured.

385 \def\@@unprocessedoptions{%
386 \ifx\@currext\@pkgextension
387  \edef\@curroptions{\@ptionlist{\@currname.\@currext}}%
388  \@for\CurrentOption:=\@curroptions\do{%
389  \ifx\CurrentOption\@empty\else\@unknownoptionerror\fi}%
390 \fi}
391 \@onlypreamble\@unprocessedoptions
392 \@onlypreamble\@@unprocessedoptions
\@badrequireerror  \RequirePackage or \LoadClass occurs in the options section.
393 \def\@badrequireerror#1[#2]#3[#4]{%
394 \@latex@error
395  {\noexpand\RequirePackage or \noexpand\LoadClass
396  in Options Section}%
397  {The \@cls@pkg\space `\@currname' is defective.\MessageBreak
398  It attempts to load `#3' in the options section, i.e.,\MessageBreak
399  between \noexpand\DeclareOption and \string\ProcessOptions.}}
400 \@onlypreamble\@badrequireerror
\@twoloadclasserror Two \LoadClass in a class.
401 \def\@twoloadclasserror{%
402 \@latex@error
403  {Two \noexpand\LoadClass commands}%
404  {You may only use one \noexpand\LoadClass in a class file}}
405 \@onlypreamble\@twoloadclasserror
\@twoclasseserror Two \documentclass or \documentstyle.
406 \def\@twoclasseserror#1#{%
407 \@latex@error
408  {Two \noexpand\documentclass or \noexpand\documentstyle commands}%
409  {The document may only declare one class.}\@gobble}
410 \@onlypreamble\@twoclasseserror

4.2 Providing shipment

\two@digits Prefix a number less than 10 with ‘0’.

411 \def\two@digits#1{\ifnum#1<10 0\fi\number#1}

\filecontents \endfilecontents This environment implements inline files. The star-form does not write extra comments into the file.

412 \begingroup%
413 \gdef\filecontents{\@tempswatrue\filec@ntents}%
414 \catcode`\*=11 %
415 \gdef\filecontents*{\@tempswafalse\filec@ntents}%
416 \catcode`\^^M\active%
417 \catcode`\^^L\active\let^^L\relax%
418 \catcode`\^^I\active%
419 \gdef\filec@ntents#1{%
420 \openin\@inputcheck#1 %
421 \ifeof\@inputcheck%
422  \@latex@warning@no@line%
423  {Writing file `\@currdir#1'}%
424  \chardef\verbatim@out15 %
425  \ch@ck7\verbatim@out\write%
426 \else%
427  \closein\@inputcheck%
428  \@latex@warning@no@line%
429  {File `#1' already exists on the system.\MessageBreak%
430  Not generating it from this source}%
431  \def\immediate##1\relax{}%
432 \fi%
433 \immediate\openout\verbatim@out=#1\relax%
434 \if@tempswa%
435  \immediate\write\verbatim@out{%
436  \@percentchar\@percentchar\space LaTeX2e file `#1'^^J%
437  \@percentchar\@percentchar\space  generated by the %
438  `filecontents' environment^^J%
439  \@percentchar\@percentchar\space from source `\jobname' on %
440  \number\year/\two@digits\month/\two@digits\day.^^J%
441  \@percentchar\@percentchar}\relax%
442 \fi%
443 \let\do\@makeother\dospecials%
444 \@vwrend%
445 \catcode`\^^L\active%
446 \let\L\@undefined%
447 \def^^L{\@ifundefined L^^J^^J^^J}%
448 \catcode`\^^I\active%
449 \let\I\@undefined%
450 \def^^I{\@ifundefined I\space\space}%
451 \catcode`\^^M\active%
452 \def^^M##1^^M%
453  {\def\reserved@b{##1}%
454  \ifx\reserved@b\reserved@a%
455  \expandafter\end\expandafter{\@currenvir}%
456  \else%
457  \immediate\write\verbatim@out{##1}\relax\expandafter^^M%
458  \fi}}%

459 \endgroup%
460 \begingroup
461 \catcode`/=0
462 \catcode`<=\catcode`{
463 \catcode`>=\catcode`}
464 \catcode`|=\catcode`\%
465 /catcode`/\=12
466 /catcode`/{=12
467 /catcode`/}=12
468 /catcode`/%=12
469 /catcode`/*=11
470 /gdef/@percentchar<%>
471 /gdef/@vwrend</edef/reserved@a<\end{/@currenvir}>>
472 /gdef/endfilecontents<|
473 /immediate/closeout/verbatim@out/relax
474 /ifx/L/@undefined/else
475  /@latex@warning@no@line<Form Feed has been converted to Blank Line>|
476 /fi
477 /ifx/I/@undefined/else
478  /@latex@warning@no@line<Tab has been converted to Space>|
479 /fi
480 /immediate/write/@unused<>/relax>
481 /global/let/endfilecontents*/endfilecontents|
482 /@onlypreamble/filecontents
483 /@onlypreamble/endfilecontents
484 /@onlypreamble/filecontents*
485 /@onlypreamble/endfilecontents*
486 /endgroup
487 \@onlypreamble\filec@ntents
488 \@onlypreamble\@vwrend

489 ⟨/2ekernel⟩

5 After Preamble

Finally we declare a package that allows all the commands declared above to be

 \@onlypreamble to be used after \begin{document}.

490 ⟨∗afterpreamble⟩

491 \NeedsTeXFormat{LaTeX2e}
492 \ProvidesPackage{pkgindoc}
493  [1994/10/20 v1.1 Package Interface in Document (DPC)]
494 \def\reserved@a#1\do\@clsextension#2\do\@vwrend#3\relax{%
495 \gdef\@preamblecmds{#1#3}}
496 \expandafter\reserved@a\@preamblecmds\relax

497 ⟨/afterpreamble⟩