summaryrefslogtreecommitdiff
path: root/macros/latex-dev/base/ltclass.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/base/ltclass.dtx')
-rw-r--r--macros/latex-dev/base/ltclass.dtx230
1 files changed, 194 insertions, 36 deletions
diff --git a/macros/latex-dev/base/ltclass.dtx b/macros/latex-dev/base/ltclass.dtx
index b639ae9410..1400ec0a62 100644
--- a/macros/latex-dev/base/ltclass.dtx
+++ b/macros/latex-dev/base/ltclass.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file.
%
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltclass.dtx}
- [2020/10/18 v1.3t LaTeX Kernel (Class & Package Interface)]
+ [2020/12/17 v1.3v LaTeX Kernel (Class & Package Interface)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltclass.dtx}
@@ -427,7 +427,7 @@
% \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}
+% {Directory syntax checking moved to dircheck.dtx}
% \changes{v0.2h}{1993/11/28}
% {Assorted commands now in the kernel removed.}
% \changes{v0.2i}{1993/12/03}
@@ -486,7 +486,7 @@
% \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 class or package file and it defines the order in which
% 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|
@@ -524,6 +524,27 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@currpath}
+% Path to the current file if explicitly given.
+% \changes{v1.3u}{2020/11/20}{Macro added}
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2020/10/01}{\@currpath}%
+%<latexrelease> {Add \@currpath}%
+\let\@currpath\@empty
+%<latexrelease>\EndIncludeInRelease
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}{\@currpath}%
+%<latexrelease> {Add \@currpath}%
+%<latexrelease>\let\@currpath\@undefined
+%<latexrelease>\EndIncludeInRelease
+%</2ekernel|latexrelease>
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\@currname}
% Name of current package or option.
% \begin{macrocode}
@@ -562,6 +583,7 @@
% \changes{v1.3l}{2020/06/05}{Added \cs{@expl@push@filename@@}
% and \cs{@expl@push@filename@aux@@}}
% \changes{v1.3s}{2020/10/08}{Added missing 2020/02/02 \cs{IncludeInRelease}}
+% \changes{v1.3v}{2020/12/14}{Removed \cs{@expl@@@hook@curr@name@push@@n}}
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
@@ -578,13 +600,22 @@
% here, e.g., \cs{@expl@push@filename@@} needs cleanup and (and
% should probably not have this name either).
% \begin{macrocode}
- \@expl@@@hook@curr@name@push@@n{}%
\@expl@push@filename@@
\xdef\@currnamestack{%
{\@currname}%
{\@currext}%
{\the\catcode`\@}%
\@currnamestack}%
+% \end{macrocode}
+% Temporarily add a stack for \cs{@currpath} here. This should be
+% integrated in the main file stack eventually, but other packages
+% rely on \cs{@currnamestack} having three elements per file, so that
+% isn't a trivial change. The prefix \cs{@kernel@...} hopefully
+% discourages people from using it.
+% \begin{macrocode}
+ \xdef\@kernel@currpathstack{%
+ {\@currpath}%
+ \@kernel@currpathstack}%
\@expl@push@filename@aux@@}
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -632,6 +663,10 @@
%<latexrelease> {Add \@expl@pop@filename@@}%
\def\@popfilename{\@expl@@@hook@curr@name@pop@@
\expandafter\@p@pfilename\@currnamestack\@nil
+% \end{macrocode}
+% Same for popping:
+% \begin{macrocode}
+ \expandafter\@p@pfilepath\@kernel@currpathstack\@nil
\@expl@pop@filename@@}
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
@@ -672,6 +707,36 @@
% \end{macro}
% \end{macro}
%
+%
+% \begin{macro}{\@kernel@currpathstack}
+% Path to the current file if explicitly given. The auxiliary is
+% needed here to insert a \cs{@empty} to prevent the loss of braces.
+% \changes{v1.3u}{2020/11/20}{Macro added}
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2020/10/01}{\@kernel@currpathstack}%
+%<latexrelease> {Add \@kernel@currpathstack}%
+\gdef\@kernel@currpathstack{}
+\def\@p@pfilepath#1{%
+ \gdef\@currpath{#1}\@p@pfilepath@aux\@empty}
+\def\@p@pfilepath@aux#1\@nil{%
+ \xdef\@kernel@currpathstack{#1}}
+%<latexrelease>\EndIncludeInRelease
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}{\@kernel@currpathstack}%
+%<latexrelease> {Add \@kernel@currpathstack}%
+%<latexrelease>\let\@kernel@currpathstack\@undefined
+%<latexrelease>\let\@p@pfilepath\@undefined
+%<latexrelease>\let\@p@pfilepath@aux\@undefined
+%<latexrelease>\EndIncludeInRelease
+%</2ekernel|latexrelease>
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
+%
+%
% \begin{macro}{\@ptionlist}
% Returns the option list of the file.
% \begin{macrocode}
@@ -915,15 +980,42 @@
% \changes{v0.3c}{1994/03/12}
% {use \cs{@gtempa}}
% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease> {\ProvidesPackage}{Check name with \strcmp}%
+%<*2ekernel|latexrelease>
\def\ProvidesPackage#1{%
\xdef\@gtempa{#1}%
- \ifx\@gtempa\@currname\else
+% \end{macrocode}
+% \changes{v1.3u}{2020/11/20}
+% {Use string comparison instead of \cs{ifx}}
+% Here \cs{@currpath} is explicitly added to the file name to report
+% when a package or class is loaded using an explicit path. Loading
+% using a path in the argument is supported but not encouraged.
+% \begin{macrocode}
+ \@expandtwoargs\@expl@str@if@eq@@nnTF
+ {\@gtempa}{\@currpath\@currname}{}{%
\@latex@warning@no@line{You have requested
- \@cls@pkg\space`\@currname',\MessageBreak
+ \@cls@pkg\space`\@currpath\@currname',\MessageBreak
but the \@cls@pkg\space provides `#1'}%
- \fi
+ }%
\@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%]
\@onlypreamble\ProvidesPackage
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\ProvidesPackage}{Undo: check name with \strcmp}%
+%<latexrelease>\def\ProvidesPackage#1{%
+%<latexrelease> \xdef\@gtempa{#1}%
+%<latexrelease> \ifx\@gtempa\@currname\else
+%<latexrelease> \@latex@warning@no@line{You have requested
+%<latexrelease> \@cls@pkg\space`\@currname',\MessageBreak
+%<latexrelease> but the \@cls@pkg\space provides `#1'}%
+%<latexrelease> \fi
+%<latexrelease> \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%]
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
% \end{macrocode}
% \end{macro}
%
@@ -934,12 +1026,12 @@
% be cautious when handling the identification string in case it
% contains UTF-8 characters.
% \changes{v1.3e}{2019/11/29}{Protect package info text (gh/52)}
-% \changes{v1.3r}{2020/10/01}{Allow for package subsitution}
+% \changes{v1.3r}{2020/10/01}{Allow for package substitution}
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease> {\@pr@videpackage}{Allow for package subsitution}%
+%<latexrelease> {\@pr@videpackage}{Allow for package substitution}%
\def\@pr@videpackage[#1]{%
\expandafter\protected@xdef % <-- protected...
\csname ver@\@currname.\@currext\endcsname{#1}% Loaded package
@@ -1007,9 +1099,18 @@
%
% \begin{macro}{\ProvidesClass}
% Like |\ProvidesPackage|, but for classes.
+% This needs a dummy \pkg{latexrelease} block to copy the definition
+% of \cs{ProvidesPackage} as it changes across releases.
% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\ProvidesClass}{Track \ProvidesPackage}%
+%<*2ekernel|latexrelease>
\let\ProvidesClass\ProvidesPackage
\@onlypreamble\ProvidesClass
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
% \end{macrocode}
% \end{macro}
%
@@ -1075,10 +1176,18 @@
\@expl@@@filehook@set@curr@file@@nNN
{\@expl@@@filehook@resolve@file@subst@@w #3.#1\@nil}%
\reserved@a\reserved@b
+ \@expl@@@filehook@clear@replacement@flag@@
\expandafter\xdef\csname opt@\reserved@a\endcsname{%
\@ifundefined{opt@\reserved@a}\@empty
{\csname opt@\reserved@a\endcsname,}%
- \zap@space#2 \@empty}}
+ \zap@space#2 \@empty}%
+% \end{macrocode}
+% \changes{v1.3u}{2020/11/20}
+% {Copy option list to the requested package.}
+% \begin{macrocode}
+ \expandafter\let
+ \csname opt@#3.#1\expandafter\endcsname
+ \csname opt@\reserved@a\endcsname}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%
@@ -1170,7 +1279,7 @@
% \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.}
+% {Optimize `empty option' code.}
% \changes{v0.2b}{1993/11/15}
% {Star form added.}
% \changes{v0.2c}{1993/11/17}
@@ -1351,7 +1460,7 @@
% the internal command, |\@fileswithoptions|.
% \begin{macro}{\documentclass}
% \changes{v1.0q}{1995/06/19}
-% {Dont redefine \cs{usepackage} in compat mode for /1634}
+% {Don't redefine \cs{usepackage} in compat mode for /1634}
% The main new-style class declaration.
% \begin{macrocode}
\def\documentclass{%
@@ -1642,7 +1751,7 @@
\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|
+% (Older code used |\relax| which is slightly easier to get into |#1|
% by mistake, which would spoil this test.)
% \begin{macrocode}
\ifx\@nnil##1\@nnil\else
@@ -1719,8 +1828,38 @@
%<latexrelease>\IncludeInRelease{2020/10/01}%
%<latexrelease> {\@onefilewithoptions}{Hooks and unused options issue}%
\def\@onefilewithoptions#1[#2][#3]#4{%
+% \end{macrocode}
+% We have to sanitise file names, so that something like
+% \begin{verbatim}
+% \usepackage{some/local/path/array}
+% \usepackage{array}
+% \end{verbatim}
+% won't load \file{array.sty} twice. It is remotely possible that
+% those are two different files, but as a matter of principles, we
+% will consider that the base file name uniquely identifies a
+% package, regardless of where it lives. This assumption already
+% holds for file hooks, for example, which address the hook to a file
+% by its base name only.
+%
+% We'll use \cs{@expl@@@filehook@set@curr@file@@nNN} to parse the
+% file name and return the \meta{path} and \meta{base+ext} in
+% separate token lists. Further ahead, most operations use
+% \cs{@currname} which doesn't have a path attached to it; only few
+% actions prepend \cs{@currpath} to \cs{@currname} (namely loading,
+% as we have to respect the given path).
+%
+% A file substituiton isn't followed just yet because at this point
+% we are parsing user input, so the file is still what the user
+% asked for, and not the file actually loaded.
+% \begin{macrocode}
+ \@expl@@@filehook@set@curr@file@@nNN{#1.#4}\reserved@a\reserved@b
+ \edef\reserved@c{\def\noexpand\reserved@c####1%
+ \detokenize\expandafter{\expanded{.#4}}%
+ \noexpand\@nil{\def\noexpand\reserved@a{####1}}}\reserved@c
+ \expandafter\reserved@c\reserved@a\@nil
\@pushfilename
- \xdef\@currname{#1}%
+ \xdef\@currname{\string@makeletter\reserved@a}%
+ \xdef\@currpath{\ifx\reserved@b\@empty\else\reserved@b/\fi}%
\global\let\@currext#4%
% \end{macrocode}
% The command \cs{ver@\meta{file}.\meta{ext}} is used to signal that
@@ -1765,9 +1904,11 @@
% \end{macrocode}
% First we take the \meta{name} and \meta{ext} given in the argument
% and check if the file exists, and issue an error otherwise asking
-% for a correction with \cs{@missingfileerror}.
+% for a correction with \cs{@missingfileerror}. For checking if the
+% file exists we use \cs{@currpath} (usually empty) before
+% \cs{@currname}.
% \begin{macrocode}
- \IfFileExists{\@currname.\@currext}{}%
+ \IfFileExists{\@currpath\@currname.\@currext}{}%
{\@missing@onefilewithoptions{#2}}%
% \end{macrocode}
% If \cs{@currname} is empty (the user replied to the ``Enter file
@@ -1784,11 +1925,12 @@
% do the bookkeeping with \cs{@filehook@file@push}
% then call \cs{set@curr@file} to set \cs{@curr@file} (and do any
% required substitution), then actually load the class/package with
-% \cs{load@onefile@withoptions}.
+% \cs{load@onefile@withoptions}. \cs{set@curr@file} also needs the
+% file path.
% \begin{macrocode}
\@disable@packageload@do{\@currname.\@currext}%
{\@expl@@@filehook@file@push@@
- \set@curr@file{\@currname.\@currext}%
+ \set@curr@file{\@currpath\@currname.\@currext}%
\@filehook@set@CurrentFile
% \end{macrocode}
% \changes{v1.3q}{2020/09/06}
@@ -1812,10 +1954,15 @@
\expandafter\@swaptwoargs\expandafter
{\expandafter{\@currpkg@reqd}}%
{% <
+% \end{macrocode}
+% \cs{@currpkg@reqd} doesn't take a path because it is used later to
+% assign \cs[no-index]{opt@...} and \cs[no-index]{ver@...}.
+% \begin{macrocode}
\edef\@currpkg@reqd{\@currname.\@currext}%
\ifx\CurrentFile\CurrentFileUsed
\else
\filename@parse\@curr@file
+ \edef\@currpath{\string@makeletter\filename@area}%
\edef\@currname{\string@makeletter\filename@base}%
\edef\@currext{\string@makeletter\filename@ext}%
\fi
@@ -1864,11 +2011,13 @@
% \end{macro}
%
% \begin{macro}{\@missing@onefilewithoptions}
-% Now the action taken when a file is not found.
+% Now the action taken when a file is not found. Path must be
+% included here as it eventually leads to a file lookup.
% \begin{macrocode}
\def\@missing@onefilewithoptions#1{%
- \@missingfileerror\@currname\@currext
- \xdef\@currname{\@missingfile@area\@missingfile@base}%
+ \@missingfileerror{\@currpath\@currname}\@currext
+ \global\let\@currpath\@missingfile@area
+ \global\let\@currname\@missingfile@base
\global\let\@currext\@missingfile@ext}
% \end{macrocode}
% \end{macro}
@@ -1887,6 +2036,13 @@
% \begin{macrocode}
\def\reserved@a{%
\@pass@ptions\@currext{#1}{\@currname}%
+% \end{macrocode}
+% \changes{v1.3u}{2020/11/20}
+% {Copy option list to the requested package.}
+% \begin{macrocode}
+ \expandafter\let
+ \csname opt@\@currpkg@reqd\expandafter\endcsname
+ \csname opt@\@currname.\@currext\endcsname
\global\expandafter
\let\csname ver@\@currname.\@currext\endcsname\@empty
% \end{macrocode}
@@ -1912,11 +2068,12 @@
\fi
% \end{macrocode}
% Now actually load the file (at this point we are certain it exists,
-% but use \cs{InputIfFileExists} so that file hooks are executed):
+% but use \cs{InputIfFileExists} so that file hooks are executed).
+% \cs{@currpath} is needed here too.
% \begin{macrocode}
- \InputIfFileExists{\@currpkg@reqd}{}%
+ \InputIfFileExists{\@currpath\@currpkg@reqd}{}%
{\@latex@error
- {The \@cls@pkg\space\@currpkg@reqd\space failed to load.}\@ehd}%
+ {The \@cls@pkg\space\@currpkg@reqd\space failed to load}\@ehd}%
%-----------------------------------------
% \end{macrocode}
% In older versions of the code |\@unprocessedoptions| would
@@ -1930,7 +2087,7 @@
% loaded.}
%
% This has changed in 2020. We now use a separate macro per package
-% to avoid interferences in case of nested packages. The whole
+% to avoid interference in case of nested packages. The whole
% code for handling this issue (GitHub 22) was provided by Hironobu
% Yamashita, thanks for that.
% \changes{v1.3k}{2020/04/07}{Use different method to ignore
@@ -2267,7 +2424,7 @@
% \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.}
+% don't 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}
@@ -2819,7 +2976,7 @@
% 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@targetlabel| holds the version name and
% |\pkgcls@targetdate| is set to \texttt{1}.
%
% |\pkgcls@targetdate=0| is used to indicate that there was no
@@ -2906,7 +3063,7 @@
\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:
+% candidates in |\pkgcls@candidate| and initially we don't have any:
% \begin{macrocode}
\let\pkgcls@candidate\@empty
% \end{macrocode}
@@ -2946,7 +3103,7 @@
%
% 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
+% back to the state of the package at that date or to the version
% with the requested name.
%
% If there was no optional argument or the optional argument
@@ -3224,7 +3381,7 @@
%
% \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
+% in two places (and it is rather lengthy) 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
@@ -3271,19 +3428,20 @@
% 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 inlined.
+% \changes{v1.3u}{2020/11/09}{Change help text because the package may have
+% existed then --- there is just no rollback data (gh/423).}
% \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
+ {The \@cls@pkg\space'\@currname' has no rollback data
+ before #1 which\MessageBreak
is after your requested rollback date --- so
- something is wrong here.\MessageBreak
+ something may be 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.
@@ -3326,7 +3484,7 @@
\pkgcls@releasedate
\fi
% \end{macrocode}
-% Otherwise the curent file is the right release, so we record that
+% Otherwise the current file is the right release, so we record that
% in the transcript and then carry on.
% \begin{macrocode}
\else