diff options
author | Karl Berry <karl@freefriends.org> | 2020-10-02 21:49:18 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-10-02 21:49:18 +0000 |
commit | 5255c37137345163348d22ab46af2304cf9f55a6 (patch) | |
tree | 88246497477ddcc26834e5708566ad4c1c862a19 /Master/texmf-dist/source/latex/base/ltclass.dtx | |
parent | 1922ba4684a59cde742dcef9ed152381d2d7b110 (diff) |
latex2e (2oct20)
git-svn-id: svn://tug.org/texlive/trunk@56514 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/base/ltclass.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/base/ltclass.dtx | 791 |
1 files changed, 688 insertions, 103 deletions
diff --git a/Master/texmf-dist/source/latex/base/ltclass.dtx b/Master/texmf-dist/source/latex/base/ltclass.dtx index 578443921b8..bc6500541e5 100644 --- a/Master/texmf-dist/source/latex/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/02/20 v1.3j LaTeX Kernel (Class & Package Interface)] + [2020/10/01 v1.3r LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -44,6 +44,9 @@ \date{\filedate} \MaintainedByLaTeXTeam{latex} \maketitle + + \providecommand\pkg[1]{\texttt{#1}} + \DocInput{\filename} \end{document} %</driver> @@ -64,6 +67,7 @@ % \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.} +% \changes{v1.3o}{2020/08/21}{Integration of new hook management interface} % % % \section{Introduction} @@ -161,7 +165,7 @@ % option \texttt{nosearch} will only check the current directory % when looking if the file exists. This can be useful if you want to % generate a local (modified) copy of some file that is already in the -% search tree of \TeX{}. Finally, you can use \texttt{nopremable} to +% search tree of \TeX{}. Finally, you can use \texttt{noheader} to % prevent it from writing the standard blurb at the top of the file % (this is actually the same as using the star form of the environment). % @@ -256,8 +260,9 @@ % \PassOptionsToPackage{foo,bar}{fred} % \RequirePackage[baz]{fred}\end{verbatim} % is the same as: -% \begin{verbatim} -% \RequirePackage[foo,bar,baz]{fred}\end{verbatim} +%\begin{verbatim} +% \RequirePackage[foo,bar,baz]{fred} +%\end{verbatim} % % \DescribeMacro\LoadClassWithOptions % |\LoadClassWithOptions|\marg{name}\oarg{version}:\\ @@ -458,7 +463,9 @@ % \end{macro} % % \begin{macro}{\@documentclasshook} -% The hook called after the first |\documentclass| command. By +% This legacy hook is called after the first |\documentclass| command. +% It is \emph{not} integrated with the new 2020 hook management system! +% By % default this checks to see if |\@normalsize| is undefined, and if % so, sets it to |\normalsize|. % \changes{v0.2q}{1993/12/17} @@ -552,22 +559,75 @@ % |#2| current extension. \\ % |#3| current catcode of |@|. \\ % |#4| Rest of the stack. +% \changes{v1.3l}{2020/06/05}{Added \cs{@expl@push@filename@@} +% and \cs{@expl@push@filename@aux@@}} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}{\@pushfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% \def\@pushfilename{% +% \end{macrocode} +% The push and pop macros are injected in \cs{@pushfilename} and +% \cs{@popfilename} so that they correctly keep track of the hook +% labels. +% +% This needs cleanup with the \pkg{expl3} interfaces also playing +% 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}} + \@currnamestack}% + \@expl@push@filename@aux@@} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{0000/00/00}{\@pushfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%<latexrelease>\def\@pushfilename{% +%<latexrelease> \xdef\@currnamestack{% +%<latexrelease> {\@currname}% +%<latexrelease> {\@currext}% +%<latexrelease> {\the\catcode`\@}% +%<latexrelease> \@currnamestack}} +%<latexrelease>\EndIncludeInRelease \@onlypreamble\@pushfilename % \end{macrocode} % +% +% +% +% +% \changes{v1.3l}{2020/06/05}{Added \cs{@expl@pop@filename@@}} % \begin{macrocode} -\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%<latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}{\@popfilename}% +%<latexrelease> {Add \@expl@pop@filename@@}% +\def\@popfilename{\@expl@@@hook@curr@name@pop@@ + \expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} +%<latexrelease>\EndIncludeInRelease +%<latexrelease> +%<latexrelease>\IncludeInRelease{0000/00/00}{\@popfilename}% +%<latexrelease> {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%<latexrelease>\EndIncludeInRelease \@onlypreamble\@popfilename % \end{macrocode} % % \begin{macrocode} +%</2ekernel|latexrelease> +%<*2ekernel> +% \end{macrocode} +% +% +% +% \begin{macrocode} \def\@p@pfilename#1#2#3#4\@nil{% \gdef\@currname{#1}% \gdef\@currext{#2}% @@ -620,15 +680,60 @@ % % \begin{macro}{\@ifpackagelater} % \begin{macro}{\@ifclasslater} -% |\@ifpackagelater{|\meta{name}|}{YYYY/MM/DD}| -% Checks that the package loaded is more recent than the given date. +% |\@ifpackagelater{|\meta{name}|}{YYYY/MM/DD}{|\meta{true +% code}|}{|\meta{false code}|}| +% Checks that the package loaded is more recent or equal to the +% given date. +% A better name for it would therefore been +% |\@ifpackagelaterorequal| but it is in use for more than 30 +% years, so \ldots % \begin{macrocode} \def\@ifpackagelater{\@ifl@ter\@pkgextension} \def\@ifclasslater{\@ifl@ter\@clsextension} \@onlypreamble\@ifpackagelater \@onlypreamble\@ifclasslater % \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\IfPackageAtLeastTF} +% \begin{macro}{\IfClassAtLeastTF} +% \begin{macro}{\IfFormatAtLeastTF} +% |\IfFormatAtLeastTF{YYYY/MM/DD}{|\meta{true +% code}|}{|\meta{false code}|}| +% Test if the format is later or equal to the given date. +% \changes{v1.3k}{2020/04/07}{Macro added; also in rollback (gh/168)} +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\IfFormatAtLeastTF}{Test format date}% +\def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} +\let\IfPackageAtLeastTF\@ifpackagelater +\let\IfClassAtLeastTF\@ifclasslater +\@onlypreamble\IfFormatAtLeastTF +\@onlypreamble\IfPackageAtLeastTF +\@onlypreamble\IfClassAtLeastTF +% \end{macrocode} +% For rollback pretend it was available since the beginning of dawn. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\IfFormatAtLeastTF}{Test format date}% +%<latexrelease>\def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} +%<latexrelease>\let\IfPackageAtLeastTF\@ifpackagelater +%<latexrelease>\let\IfClassAtLeastTF\@ifclasslater +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} % +% \begin{macro}{\@ifl@ter} % \begin{macrocode} \def\@ifl@ter#1#2{% \expandafter\@ifl@t@r @@ -675,6 +780,7 @@ % \begin{macrocode} \@onlypreamble\@ifl@t@r % \end{macrocode} +% \end{macro} % % \changes{v1.1j}{2016/06/20} % {don't declare as \cs{@onlypreamble}} @@ -695,8 +801,8 @@ %</2ekernel|latexreleasefirst> %<*2ekernel> % \end{macrocode} -% \end{macro} -% \end{macro} +% +% % % \begin{macro}{\@ifpackagewith} % \begin{macro}{\@ifclasswith} @@ -800,14 +906,17 @@ % 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} % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2020/02/02}% -%<latexrelease> {\@pr@videpackage}{Protection for package info}% +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@pr@videpackage}{Allow for package subsitution}% \def\@pr@videpackage[#1]{% \expandafter\protected@xdef % <-- protected... - \csname ver@\@currname.\@currext\endcsname{#1}% + \csname ver@\@currname.\@currext\endcsname{#1}% Loaded package + \expandafter\protected@xdef % <-- protected... + \csname ver@\@currpkg@reqd\endcsname{#1}% Requested package \ifx\@currext\@clsextension \typeout{Document Class: \@gtempa\space#1}% \else @@ -832,6 +941,19 @@ % \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/02/02}% +%<latexrelease> {\@pr@videpackage}{Protection for package info}% +%<latexrelease> +%<latexrelease>\def\@pr@videpackage[#1]{% +%<latexrelease> \expandafter\protected@xdef % <-- protected... +%<latexrelease> \csname ver@\@currname.\@currext\endcsname{#1}% +%<latexrelease>\ifx\@currext\@clsextension +%<latexrelease> \typeout{Document Class: \@gtempa\space#1}% +%<latexrelease> \else +%<latexrelease> \protected@wlog{Package: \@gtempa\space#1}% <--- protected +%<latexrelease> \fi} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\@pr@videpackage}{Protection for package info}% %<latexrelease> @@ -915,11 +1037,28 @@ % 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} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020/10/01}{\@pass@ptions} +%<latexrelease> {Add file replacement in \@pass@ptions}% +%<*2ekernel|latexrelease> \def\@pass@ptions#1#2#3{% - \expandafter\xdef\csname opt@#3.#1\endcsname{% - \@ifundefined{opt@#3.#1}\@empty - {\csname opt@#3.#1\endcsname,}% + \edef\reserved@a{\@expl@@@filehook@resolve@file@subst@@w #3.#1\@nil}% + \expandafter\xdef\csname opt@\reserved@a\endcsname{% + \@ifundefined{opt@\reserved@a}\@empty + {\csname opt@\reserved@a\endcsname,}% \zap@space#2 \@empty}} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% +%<latexrelease>\IncludeInRelease{0000/00/00}{\@pass@ptions} +%<latexrelease> {\@pass@ptions}% +%<latexrelease>\def\@pass@ptions#1#2#3{% +%<latexrelease> \expandafter\xdef\csname opt@#3.#1\endcsname{% +%<latexrelease> \@ifundefined{opt@#3.#1}\@empty +%<latexrelease> {\csname opt@#3.#1\endcsname,}% +%<latexrelease> \zap@space#2 \@empty}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> \@onlypreamble\@pass@ptions % \end{macrocode} % @@ -1050,6 +1189,10 @@ % % The common part of |\ProcessOptions| and |\ProcessOptions*|. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@process@pti@ns}{Unused options issue}% \def\@process@pti@ns{% \@for\CurrentOption:=\@curroptions\do{% \@ifundefined{ds@\CurrentOption}% @@ -1073,11 +1216,33 @@ % \end{macrocode} % \changes{v1.0r}{1995/10/17} % {Reset \cs{CurrentOption} for graphics/1873} +% \changes{v1.3k}{2020/04/07}{Use different method to ignore +% unprocessed options (gh/22)} % \begin{macrocode} \let\CurrentOption\@empty \let\@fileswith@pti@ns\@@fileswith@pti@ns - \AtEndOfPackage{\let\@unprocessedoptions\relax}} + \AtEndOfPackage{\expandafter\let + \csname unprocessedoptions-\@currname.\@currext\endcsname + \relax}} \@onlypreamble\@process@pti@ns +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@process@pti@ns}{Unused options issue}% +%<latexrelease> +%<latexrelease>\def\@process@pti@ns{% +%<latexrelease> \@for\CurrentOption:=\@curroptions\do{% +%<latexrelease> \@ifundefined{ds@\CurrentOption}% +%<latexrelease> {\@use@ption +%<latexrelease> \default@ds}% +%<latexrelease> \@use@ption}% +%<latexrelease> \@for\CurrentOption:=\@declaredoptions\do{% +%<latexrelease> \expandafter\let\csname ds@\CurrentOption\endcsname\relax}% +%<latexrelease> \let\CurrentOption\@empty +%<latexrelease> \let\@fileswith@pti@ns\@@fileswith@pti@ns +%<latexrelease> \AtEndOfPackage{\let\@unprocessedoptions\relax}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} @@ -1243,13 +1408,45 @@ % \changes{v1.0v}{1996/10/04}{Reset \cs{@unprocessedoptions} for /2269} % Load package `|#1|' with the current option list. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\RequirePackageWithOptions}{Unused options issue}% \def\RequirePackageWithOptions{% - \AtEndOfPackage{\let\@unprocessedoptions\relax}% +% \end{macrocode} +% The resetting of the unprocessed options is now done on a par package basis. +% \changes{v1.3k}{2020/04/07}{Use different method to ignore +% unprocessed options (gh/22)} +% \begin{macrocode} + \AtEndOfPackage{\expandafter\let + \csname unprocessedoptions-\@currname.\@currext\endcsname + \relax}% \@loadwithoptions\@pkgextension\RequirePackage} \@onlypreamble\RequirePackageWithOptions +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\RequirePackageWithOptions}{Unused options issue}% +%<latexrelease> +%<latexrelease>\def\RequirePackageWithOptions{% +%<latexrelease> \AtEndOfPackage{\let\@unprocessedoptions\relax}% +%<latexrelease> \@loadwithoptions\@pkgextension\RequirePackage} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % +% + + + + + + +% % \begin{macro}{\usepackage} % To begin with, |\usepackage| produces an error. This is reset by % |\documentclass|. @@ -1469,6 +1666,9 @@ \@onlypreamble\@fileswith@pti@ns % \end{macrocode} % +% \begin{macro}{\load@onefilewithoptions} +% This macro is used when loading packages or classes. +% % Have the main argument as |#1|, so we only need one |\expandafter| % above. % \changes{v0.2a}{1993/11/14} @@ -1482,91 +1682,338 @@ % \changes{v1.3d}{2019/10/18}{Initialize \cs{...-h@@k} only when loading % the package or class (gh/198)} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@onefilewithoptions}{Hooks and unused options issue}% \def\@onefilewithoptions#1[#2][#3]#4{% \@pushfilename \xdef\@currname{#1}% \global\let\@currext#4% +% \end{macrocode} +% The command \cs{ver@\meta{file}.\meta{ext}} is used to signal that +% a package is already loaded, either because it is in fact loaded, or +% because it's loading was suppressed. In minimal installations, said +% package may not exist but still have its loading suppressed with +% \cs{ver@\meta{file}.\meta{ext}}, so before checking if the file +% exists we have to check that we do need to load it with +% \cs{@ifl@aded}. If we don't, then there's no point in checking for +% a typo or load-disabling. +% \begin{macrocode} + \@ifl@aded\@currext\@currname +% \end{macrocode} +% If the package is already loaded, check that there were no option +% clashes: +% \changes{v1.1b}{1998/05/07} +% {Modify help message for latex/2805} +% \begin{macrocode} + {\@if@ptions\@currext{\@currname}{#2}{}% + {\@latex@error + {Option clash for \@cls@pkg\space \@currname}% + {The package \@currname\space has already been loaded + with options:\MessageBreak + \space\space[\@ptionlist{\@currname.\@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{\@currname.\@currext},#2\MessageBreak + to your \noexpand\documentclass declaration may fix this.% + \MessageBreak + Try typing \space <return> \space to proceed.}}% + \@firstofone}% + {\makeatletter +% \end{macrocode} +% The next line seems to be necessary for 2.09 compatibility (the +% way the code is written there) This seems questionable and should be +% look at as in 2e it is definitely unnecessary at this point! +% \begin{macrocode} + \@reset@ptions +% \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}. +% \begin{macrocode} + \IfFileExists{\@currname.\@currext}{}% + {\@missing@onefilewithoptions{#2}}% +% \end{macrocode} +% If \cs{@currname} is empty (the user replied to the ``Enter file +% name'' prompt with \meta{RETURN}), so stop here +% (do \cs{@popfilename} to pop the item just added above). +% +% This \cs{@gobble} omits the date check at the end. +% \begin{macrocode} + \ifx\@currname\@empty + \expandafter\@gobble + \else +% \end{macrocode} +% If the file exists, check if it was load-prevented, and otherwise +% 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}. +% \begin{macrocode} + \@disable@packageload@do{\@currname.\@currext}% + {\@expl@@@filehook@file@push@@ + \set@curr@file{\@currname.\@currext}% + \@filehook@set@CurrentFile +% \end{macrocode} +% \changes{v1.3q}{2020/09/06} +% {Save \cs{@currpkg@reqd} so that we don't lose track of +% package substitutions.} +% The \cs{set@curr@file} line above might have replaced the file, so +% \cs{@currname} and \cs{@currext} may no longer hold the actual +% package being loaded, so in that case we need to update these two +% token lists (\cs{@curr@file} holds the file name after replacement, +% so we parse that). +% +% The requested file is saved in \cs{@currpkg@reqd} to be used in +% \cs{InputIfFileExists} later: if the updated \cs{@currname} and +% \cs{@currext} are used we lose track of the substitution, so +% \cs{CurrentFile} and \cs{CurrentFileUsed} will be (incorrectly) +% the same. +% \begin{macrocode} + \edef\@currpkg@reqd{\@currname.\@currext}% + \ifx\CurrentFile\CurrentFileUsed + \else + \filename@parse\@curr@file + \edef\@currname{\string@makeletter\filename@base}% + \edef\@currext{\string@makeletter\filename@ext}% + \fi + \load@onefile@withoptions{#2}% +% \end{macrocode} +% Now just clean up and exit. +% \begin{macrocode} + \@expl@@@filehook@file@pop@@}% + \expandafter\@firstofone + \fi}% +% \end{macrocode} +% Except in the case where \cs{@currname} is empty, the date is +% checked against the date marked in the package file: +% \begin{macrocode} + {\@ifl@ter\@currext{\@currname}{#3}{}% + {\@latex@warning@no@line + {You have requested,\on@line, + version\MessageBreak + `#3' of \@cls@pkg\space \@currname,\MessageBreak + but only version\MessageBreak + `\csname ver@\@currname.\@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} +% \end{macrocode} +% +% \begin{macrocode} +\@onlypreamble\@onefilewithoptions +% \end{macrocode} +% +% The kernel no longer uses \cs{@unprocessedoptions} +% \begin{macrocode} +\let\@unprocessedoptions\@undefined +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@missing@onefilewithoptions} +% Now the action taken when a file is not found. +% \begin{macrocode} +\def\@missing@onefilewithoptions#1{% + \@missingfileerror\@currname\@currext + \xdef\@currname{\@missingfile@area\@missingfile@base}% + \global\let\@currext\@missingfile@ext} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\load@onefile@withoptions} +% Now the code that actually does the file loading: +% \begin{macrocode} +\def\load@onefile@withoptions#1{% \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 + \@pass@ptions\@currext{#1}{\@currname}% + \global\expandafter + \let\csname ver@\@currname.\@currext\endcsname\@empty % \end{macrocode} % We initialize \cs{...-h@@k} here and only if we load the file so that it % remains undefined otherwise. % \begin{macrocode} - \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty - \InputIfFileExists - {\@currname.\@currext}% - {}% - {\@missingfileerror\@currname\@currext}% + \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty +% \end{macrocode} +% When the current extension is \cs{@pkgextension} we are loading a +% package otherwise, if it is \cs{@clsextension}, a class, so +% depending on that we execute different hooks. If the extension is +% neither, then it is another type of file without special hooks. +% \begin{macrocode} +%----------------------------------------- + \ifx\@currext\@pkgextension + \UseHook{package/before}% + \UseHook{package/before/\@currname}% + \else + \ifx\@currext\@clsextension + \UseHook{class/before}% + \UseHook{class/before/\@currname}% + \fi + \fi % \end{macrocode} -% |\@unprocessedoptions| will generate an error for each specified -% option in a package unless a |\ProcessOptions| has appeared in the -% package file. +% Now actually load the file (at this point we are certain it exists, +% but use \cs{InputIfFileExists} so that file hooks are executed): +% \begin{macrocode} + \InputIfFileExists{\@currpkg@reqd}{}% + {\@latex@error + {The \@cls@pkg\space\@currpkg@reqd\space failed to load.}\@ehd}% +%----------------------------------------- +% \end{macrocode} +% In older versions of the code |\@unprocessedoptions| would +% 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 +% {Only run the hook and options check if the file was +% loaded.} +% +% This has changed in 2020. We now use a separate macro per package +% to avoid interferences 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 +% unprocessed options (gh/22)} +% \begin{macrocode} + \expandafter\let\csname unprocessedoptions-\@currname.\@currext\endcsname + \@@unprocessedoptions \csname\@currname.\@currext-h@@k\endcsname \expandafter\let\csname\@currname.\@currext-h@@k\endcsname \@undefined - \@unprocessedoptions}% % \end{macrocode} -% +% Catch the case where the packages has handled the options and +% redefined \cs{@unprocessedoptions} to \cs{relax} (old interface). +% In that case no error should be produced. +% \changes{v1.3k}{2020/04/07}{Use different method to ignore +% unprocessed options (gh/22)} % \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}}% + \ifx\@unprocessedoptions\relax + \let\@unprocessedoptions\@undefined % \end{macrocode} -% \changes{v0.2c}{1993/11/17} -% {Added trap for two \cs{LoadClass} commands.} +% Otherwise run the per package set of unused options. % \begin{macrocode} - \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi - \@popfilename - \@reset@ptions}% - \reserved@a} -\@onlypreamble\@onefilewithoptions + \else + \csname unprocessedoptions-\@currname.\@currext\endcsname + \fi +% \end{macrocode} +% In either case we drop the macro afterwards as it is no longer needed. +% \begin{macrocode} + \expandafter\let + \csname unprocessedoptions-\@currname.\@currext\endcsname + \@undefined +% \end{macrocode} +% And same procedure, James, when we are finished loading, except +% that the hook order is now reversed. +% \begin{macrocode} +%----------------------------------------- + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi}% +%----------------------------------------- + \@ifl@aded\@currext\@currname{}{\reserved@a}} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@onefilewithoptions}{Hooks and unused options issue}% +%<latexrelease> +% \end{macrocode} +% Because of the way \cs{@onfilewithoptions} is changed for +% rollback handling below we have to define +% \cs{load@onefilewithoptions} when rolling back! +% \begin{macrocode} +%<latexrelease>\def\load@onefilewithoptions#1[#2][#3]#4{% +%<latexrelease> \@pushfilename +%<latexrelease> \xdef\@currname{#1}% +%<latexrelease> \global\let\@currext#4% +%<latexrelease> \let\CurrentOption\@empty +%<latexrelease> \@reset@ptions +%<latexrelease> \makeatletter +%<latexrelease> \def\reserved@a{% +%<latexrelease> \@ifl@aded\@currext{#1}% +%<latexrelease> {\@if@ptions\@currext{#1}{#2}{}% +%<latexrelease> {\@latex@error +%<latexrelease> {Option clash for \@cls@pkg\space #1}% +%<latexrelease> {The package #1 has already been loaded +%<latexrelease> with options:\MessageBreak +%<latexrelease> \space\space[\@ptionlist{#1.\@currext}]\MessageBreak +%<latexrelease> There has now been an attempt to load it +%<latexrelease> with options\MessageBreak +%<latexrelease> \space\space[#2]\MessageBreak +%<latexrelease> Adding the global options:\MessageBreak +%<latexrelease> \space\space +%<latexrelease> \@ptionlist{#1.\@currext},#2\MessageBreak +%<latexrelease> to your \noexpand\documentclass declaration may fix this.% +%<latexrelease> \MessageBreak +%<latexrelease> Try typing \space <return> \space to proceed.}}}% +%<latexrelease> {\@pass@ptions\@currext{#2}{#1}% +%<latexrelease> \global\expandafter +%<latexrelease> \let\csname ver@\@currname.\@currext\endcsname\@empty +%<latexrelease> \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty +%<latexrelease> \InputIfFileExists +%<latexrelease> {\@currname.\@currext}% +%<latexrelease> {}% +%<latexrelease> {\@missingfileerror\@currname\@currext}% +%<latexrelease> \let\@unprocessedoptions\@@unprocessedoptions +%<latexrelease> \csname\@currname.\@currext-h@@k\endcsname +%<latexrelease> \expandafter\let\csname\@currname.\@currext-h@@k\endcsname +%<latexrelease> \@undefined +%<latexrelease> \@unprocessedoptions}% +%<latexrelease> \@ifl@ter\@currext{#1}{#3}{}% +%<latexrelease> {\@latex@warning@no@line +%<latexrelease> {You have requested,\on@line, +%<latexrelease> version\MessageBreak +%<latexrelease> `#3' of \@cls@pkg\space #1,\MessageBreak +%<latexrelease> but only version\MessageBreak +%<latexrelease> `\csname ver@#1.\@currext\endcsname'\MessageBreak +%<latexrelease> is available}}% +%<latexrelease> \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi +%<latexrelease> \@popfilename +%<latexrelease> \@reset@ptions}% +%<latexrelease> \reserved@a} +%<latexrelease> +%<latexrelease>\let \load@onefile@withoptions \@undefined +%<latexrelease>\let \@missing@onefilewithoptions \@undefined +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % +% +% +% +% +% % \begin{macro}{\@@fileswith@pti@ns} % Save the definition (for error checking). % \changes{v0.2c}{1993/11/17} @@ -1593,9 +2040,12 @@ % \end{macrocode} % \end{macro} % +% +% +% % \subsection{Hooks} % -% Allow code do be saved to be executed at specific later times. +% Allow code to 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 @@ -1615,25 +2065,6 @@ % \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} @@ -1652,8 +2083,29 @@ % \end{macrocode} % % \begin{macrocode} -\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} -\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\AtBeginDocument}{Use hook system}% +\DeclareRobustCommand\AtBeginDocument{\AddToHook{begindocument}} +\DeclareRobustCommand\AtEndDocument {\AddToHook{enddocument}} +%\DeclareRobustCommand\AtEndDocument {\AddToHook{env/document/end}} % alternative impl +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\AtBeginDocument}{Use hook system}% +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} +%<latexrelease>\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \@onlypreamble\AtBeginDocument % \end{macrocode} % \end{macro} @@ -1760,6 +2212,7 @@ % \end{macrocode} % \end{macro} % +% \begin{environment}{filecontents} % \begin{macro}{\filecontents} % \begin{macro}{\endfilecontents} % This environment implements inline files. @@ -1776,17 +2229,16 @@ % \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} % \changes{v1.3a}{2019/07/01}{Support UTF8 and spaces in % filecontents environment file name} % \changes{v1.3b}{2019/08/27}{Make various commands robust} % \changes{v1.3c}{2019/09/11}{Support optional argument for filecontents} % \changes{v1.3f}{2020/01/05}{Support more write streams in LuaTeX gh/238} -% +% \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\filec@ntents}{Spaces in file names + optional arg}% +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\filec@ntents}{Define \q@curr@file directly (gh/220)}% % % \end{macrocode} % We use |@tempswa| to mean no preamble writing and reuse |@filesw| @@ -1817,7 +2269,7 @@ \filec@ntents } % \end{macrocode} -% Option \texttt{force}) (or \texttt{overwrite}) changes the +% Option \texttt{force} (or \texttt{overwrite}) changes the % overwriting switch % \begin{macrocode} \let\filec@ntents@force\@fileswfalse @@ -1829,7 +2281,7 @@ \let\filec@ntents@noheader\@tempswafalse % \end{macrocode} % Option \texttt{nosearch} only checks the current directory not -% the how \TeX{} tree for the existence of the file to write. +% the whole \TeX{} tree for the existence of the file to write. % \begin{macrocode} \def\filec@ntents@nosearch{% \let\filec@ntents@checkdir\@currdir @@ -1855,10 +2307,12 @@ \catcode`\^^I\active% % \end{macrocode} % +% \changes{v1.3m}{2020-08-08}{define \cs{q@curr@file} directly as the +% quotes have already been removed (gh/220)} % \begin{macrocode} \gdef\filec@ntents#1{% \set@curr@file{\filec@ntents@checkdir#1}% - \edef\q@curr@file{\expandafter\quote@name\expandafter{\@curr@file}}% + \edef\q@curr@file{"\@curr@file"}% % \end{macrocode} % % Lua\TeX\ has more writes (and 18 is safe here). @@ -2019,6 +2473,136 @@ % \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\filec@ntents}{Spaces in file names + optional arg}% +%<latexrelease>\def\filecontents{\@tempswatrue\@fileswtrue +%<latexrelease> \@ifnextchar[\filec@ntents@opt\filec@ntents +%<latexrelease>} +%<latexrelease>\@namedef{filecontents*}{\@tempswafalse\@fileswtrue +%<latexrelease> \@ifnextchar[\filec@ntents@opt\filec@ntents +%<latexrelease>} +%<latexrelease>\def\filec@ntents@opt[#1]{% +%<latexrelease> \edef\@fortmp{\zap@space#1 \@empty}% +%<latexrelease> \@for\reserved@a:=\@fortmp\do{% +%<latexrelease> \ifcsname filec@ntents@\reserved@a\endcsname +%<latexrelease> \csname filec@ntents@\reserved@a\endcsname +%<latexrelease> \else +%<latexrelease> \@latex@error{Unknown filecontents option \reserved@a}% +%<latexrelease> {Valid options are force (or overwrite), nosearch, noheader}% +%<latexrelease> \fi}% +%<latexrelease> \filec@ntents +%<latexrelease>} +%<latexrelease>\let\filec@ntents@force\@fileswfalse +%<latexrelease>\let\filec@ntents@overwrite\@fileswfalse % alternative name +%<latexrelease>\let\filec@ntents@noheader\@tempswafalse +%<latexrelease>\def\filec@ntents@nosearch{% +%<latexrelease> \let\filec@ntents@checkdir\@currdir +%<latexrelease> \def\filec@ntents@where{in current directory}} +%<latexrelease>\let\filec@ntents@checkdir\@empty +%<latexrelease>\def\filec@ntents@where{exists on the system} +%<latexrelease>\begingroup% +%<latexrelease>\@tempcnta=1 +%<latexrelease>\loop +%<latexrelease> \catcode\@tempcnta=12 % +%<latexrelease> \advance\@tempcnta\@ne % +%<latexrelease>\ifnum\@tempcnta<32 % +%<latexrelease>\repeat % +%<latexrelease>\catcode`\*=11 % +%<latexrelease>\catcode`\^^M\active% +%<latexrelease>\catcode`\^^L\active\let^^L\relax% +%<latexrelease>\catcode`\^^I\active% +%<latexrelease>\gdef\filec@ntents#1{% +%<latexrelease> \set@curr@file{\filec@ntents@checkdir#1}% +%<latexrelease> \edef\q@curr@file{\expandafter\quote@name\expandafter{\@curr@file}}% +%<latexrelease> \chardef\reserved@c\ifx\directlua\@undefined 15 \else 127 \fi% +%<latexrelease> \openin\@inputcheck\q@curr@file \space % +%<latexrelease> \ifeof\@inputcheck% +%<latexrelease> \@latex@warning@no@line% +%<latexrelease> {Writing file `\@currdir\@curr@file'}% +%<latexrelease> \ch@ck7\reserved@c\write\relax% +%<latexrelease> \immediate\openout\reserved@c\q@curr@file\relax% +%<latexrelease> \else% +%<latexrelease> \if@filesw% +%<latexrelease> \@latex@warning@no@line% +%<latexrelease> {File `\@curr@file' already \filec@ntents@where.\MessageBreak% +%<latexrelease> Not generating it from this source}% +%<latexrelease> \let\write\@gobbletwo% +%<latexrelease> \let\closeout\@gobble% +%<latexrelease> \else% +%<latexrelease> \edef\reserved@a{#1}% +%<latexrelease> \edef\reserved@a{\detokenize\expandafter{\reserved@a}}% +%<latexrelease> \edef\reserved@b{\detokenize\expandafter{\jobname}}% +%<latexrelease> \ifx\reserved@a\reserved@b% +%<latexrelease> \@fileswtrue% +%<latexrelease> \else% +%<latexrelease> \edef\reserved@b{\reserved@b\detokenize{.tex}}% +%<latexrelease> \ifx\reserved@a\reserved@b +%<latexrelease> \@fileswtrue% +%<latexrelease> \fi% +%<latexrelease> \fi% +%<latexrelease> \ch@ck7\reserved@c\write\relax% +%<latexrelease> \if@filesw% % Foul ... trying to overwrite \jobname! +%<latexrelease> \@latex@error{Trying to overwrite `\jobname.tex'}{You can't % +%<latexrelease> write to the file you are reading from!\MessageBreak% +%<latexrelease> Data is written to screen instead.}% +%<latexrelease> \else% +%<latexrelease> \@latex@warning@no@line% +%<latexrelease> {Writing or overwriting file `\@currdir\@curr@file'}% +%<latexrelease> \immediate\openout\reserved@c\q@curr@file\relax% +%<latexrelease> \fi% +%<latexrelease> \fi% +%<latexrelease> \fi% +%<latexrelease> \closein\@inputcheck% +%<latexrelease> \if@tempswa% +%<latexrelease> \immediate\write\reserved@c{% +%<latexrelease> \@percentchar\@percentchar\space% +%<latexrelease> \expandafter\@gobble\string\LaTeX2e file `\@curr@file'^^J% +%<latexrelease> \@percentchar\@percentchar\space generated by the % +%<latexrelease> `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J% +%<latexrelease> \@percentchar\@percentchar\space from source `\jobname' on % +%<latexrelease> \number\year/\two@digits\month/\two@digits\day.^^J% +%<latexrelease> \@percentchar\@percentchar}% +%<latexrelease> \fi% +%<latexrelease> \let\do\@makeother\dospecials% +%<latexrelease> \count@ 128\relax% +%<latexrelease> \loop% +%<latexrelease> \catcode\count@ 11\relax% +%<latexrelease> \advance\count@ \@ne% +%<latexrelease> \ifnum\count@<\@cclvi% +%<latexrelease> \repeat% +%<latexrelease> \edef\E{\@backslashchar end\string{\@currenvir\string}}% +%<latexrelease> \edef\reserved@b{% +%<latexrelease> \def\noexpand\reserved@b% +%<latexrelease> ####1\E####2\E####3\relax}% +%<latexrelease> \reserved@b{% +%<latexrelease> \ifx\relax##3\relax% +%<latexrelease> \immediate\write\reserved@c{##1}% +%<latexrelease> \else% +%<latexrelease> \edef^^M{\noexpand\end{\@currenvir}}% +%<latexrelease> \ifx\relax##1\relax% +%<latexrelease> \else% +%<latexrelease> \@latex@warning{Writing text `##1' before % +%<latexrelease> \string\end{\@currenvir}\MessageBreak as last line of \@curr@file}% +%<latexrelease> \immediate\write\reserved@c{##1}% +%<latexrelease> \fi% +%<latexrelease> \ifx\relax##2\relax% +%<latexrelease> \else% +%<latexrelease> \@latex@warning{% +%<latexrelease> Ignoring text `##2' after \string\end{\@currenvir}}% +%<latexrelease> \fi% +%<latexrelease> \fi% +%<latexrelease> ^^M}% +%<latexrelease> \catcode`\^^L\active% +%<latexrelease> \let\L\@undefined% +%<latexrelease> \def^^L{\expandafter\ifx\csname L\endcsname\relax\fi ^^J^^J}% +%<latexrelease> \catcode`\^^I\active% +%<latexrelease> \let\I\@undefined% +%<latexrelease> \def^^I{\expandafter\ifx\csname I\endcsname\relax\fi\space}% +%<latexrelease> \catcode`\^^M\active% +%<latexrelease> \edef^^M##1^^M{% +%<latexrelease> \noexpand\reserved@b##1\E\E\relax}}% +%<latexrelease>\endgroup% +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\filec@ntents}{Spaces in file names + optional arg}% %<latexrelease> @@ -2142,6 +2726,7 @@ % \end{macrocode} % \end{macro} % \end{macro} +% \end{environment} % % % @@ -2763,7 +3348,7 @@ %<*afterpreamble> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{pkgindoc} - [1994/10/20 v1.1 Package Interface in Document (DPC)] + [2020-08-08 v1.3m 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 |