From 5255c37137345163348d22ab46af2304cf9f55a6 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 2 Oct 2020 21:49:18 +0000 Subject: latex2e (2oct20) git-svn-id: svn://tug.org/texlive/trunk@56514 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/base/ltclass.dtx | 791 +++++++++++++++++++++--- 1 file changed, 688 insertions(+), 103 deletions(-) (limited to 'Master/texmf-dist/source/latex/base/ltclass.dtx') 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} % @@ -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|latexrelease> +% +%\IncludeInRelease{2020/10/01}{\@pushfilename}% +% {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@@} +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@pushfilename}% +% {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%\def\@pushfilename{% +% \xdef\@currnamestack{% +% {\@currname}% +% {\@currext}% +% {\the\catcode`\@}% +% \@currnamestack}} +%\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} +% +%\IncludeInRelease{2020/10/01}{\@popfilename}% +% {Add \@expl@pop@filename@@}% +\def\@popfilename{\@expl@@@hook@curr@name@pop@@ + \expandafter\@p@pfilename\@currnamestack\@nil + \@expl@pop@filename@@} +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@popfilename}% +% {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%\EndIncludeInRelease \@onlypreamble\@popfilename % \end{macrocode} % % \begin{macrocode} +% +%<*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|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\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} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\IfFormatAtLeastTF}{Test format date}% +%\def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} +%\let\IfPackageAtLeastTF\@ifpackagelater +%\let\IfClassAtLeastTF\@ifclasslater +%\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> % \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|latexrelease> -%\IncludeInRelease{2020/02/02}% -% {\@pr@videpackage}{Protection for package info}% +%\IncludeInRelease{2020/10/01}% +% {\@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} % %\EndIncludeInRelease +%\IncludeInRelease{2020/02/02}% +% {\@pr@videpackage}{Protection for package info}% +% +%\def\@pr@videpackage[#1]{% +% \expandafter\protected@xdef % <-- protected... +% \csname ver@\@currname.\@currext\endcsname{#1}% +%\ifx\@currext\@clsextension +% \typeout{Document Class: \@gtempa\space#1}% +% \else +% \protected@wlog{Package: \@gtempa\space#1}% <--- protected +% \fi} +% +%\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\@pr@videpackage}{Protection for package info}% % @@ -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} +% +%\IncludeInRelease{2020/10/01}{\@pass@ptions} +% {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}} +% +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@pass@ptions} +% {\@pass@ptions}% +%\def\@pass@ptions#1#2#3{% +% \expandafter\xdef\csname opt@#3.#1\endcsname{% +% \@ifundefined{opt@#3.#1}\@empty +% {\csname opt@#3.#1\endcsname,}% +% \zap@space#2 \@empty}} +%\EndIncludeInRelease +%<*2ekernel> \@onlypreamble\@pass@ptions % \end{macrocode} % @@ -1050,6 +1189,10 @@ % % The common part of |\ProcessOptions| and |\ProcessOptions*|. % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\@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 +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@process@pti@ns}{Unused options issue}% +% +%\def\@process@pti@ns{% +% \@for\CurrentOption:=\@curroptions\do{% +% \@ifundefined{ds@\CurrentOption}% +% {\@use@ption +% \default@ds}% +% \@use@ption}% +% \@for\CurrentOption:=\@declaredoptions\do{% +% \expandafter\let\csname ds@\CurrentOption\endcsname\relax}% +% \let\CurrentOption\@empty +% \let\@fileswith@pti@ns\@@fileswith@pti@ns +% \AtEndOfPackage{\let\@unprocessedoptions\relax}} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} @@ -1243,12 +1408,44 @@ % \changes{v1.0v}{1996/10/04}{Reset \cs{@unprocessedoptions} for /2269} % Load package `|#1|' with the current option list. % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\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 +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\RequirePackageWithOptions}{Unused options issue}% +% +%\def\RequirePackageWithOptions{% +% \AtEndOfPackage{\let\@unprocessedoptions\relax}% +% \@loadwithoptions\@pkgextension\RequirePackage} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} +% +% + + + + + + % % \begin{macro}{\usepackage} % To begin with, |\usepackage| produces an error. This is reset by @@ -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|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\@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 \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 \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} +% +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@onefilewithoptions}{Hooks and unused options issue}% +% +% \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} +%\def\load@onefilewithoptions#1[#2][#3]#4{% +% \@pushfilename +% \xdef\@currname{#1}% +% \global\let\@currext#4% +% \let\CurrentOption\@empty +% \@reset@ptions +% \makeatletter +% \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 \space to proceed.}}}% +% {\@pass@ptions\@currext{#2}{#1}% +% \global\expandafter +% \let\csname ver@\@currname.\@currext\endcsname\@empty +% \expandafter\let\csname\@currname.\@currext-h@@k\endcsname\@empty +% \InputIfFileExists +% {\@currname.\@currext}% +% {}% +% {\@missingfileerror\@currname\@currext}% +% \let\@unprocessedoptions\@@unprocessedoptions +% \csname\@currname.\@currext-h@@k\endcsname +% \expandafter\let\csname\@currname.\@currext-h@@k\endcsname +% \@undefined +% \@unprocessedoptions}% +% \@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\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi +% \@popfilename +% \@reset@ptions}% +% \reserved@a} +% +%\let \load@onefile@withoptions \@undefined +%\let \@missing@onefilewithoptions \@undefined +% +%\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|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\AtBeginDocument}{Use hook system}% +\DeclareRobustCommand\AtBeginDocument{\AddToHook{begindocument}} +\DeclareRobustCommand\AtEndDocument {\AddToHook{enddocument}} +%\DeclareRobustCommand\AtEndDocument {\AddToHook{env/document/end}} % alternative impl +% \end{macrocode} +% +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\AtBeginDocument}{Use hook system}% +% +%\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} +%\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} +% +%\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|latexrelease> -%\IncludeInRelease{2019/10/01}% -% {\filec@ntents}{Spaces in file names + optional arg}% +%\IncludeInRelease{2020/10/01}% +% {\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} % %\EndIncludeInRelease +%\IncludeInRelease{2019/10/01}% +% {\filec@ntents}{Spaces in file names + optional arg}% +%\def\filecontents{\@tempswatrue\@fileswtrue +% \@ifnextchar[\filec@ntents@opt\filec@ntents +%} +%\@namedef{filecontents*}{\@tempswafalse\@fileswtrue +% \@ifnextchar[\filec@ntents@opt\filec@ntents +%} +%\def\filec@ntents@opt[#1]{% +% \edef\@fortmp{\zap@space#1 \@empty}% +% \@for\reserved@a:=\@fortmp\do{% +% \ifcsname filec@ntents@\reserved@a\endcsname +% \csname filec@ntents@\reserved@a\endcsname +% \else +% \@latex@error{Unknown filecontents option \reserved@a}% +% {Valid options are force (or overwrite), nosearch, noheader}% +% \fi}% +% \filec@ntents +%} +%\let\filec@ntents@force\@fileswfalse +%\let\filec@ntents@overwrite\@fileswfalse % alternative name +%\let\filec@ntents@noheader\@tempswafalse +%\def\filec@ntents@nosearch{% +% \let\filec@ntents@checkdir\@currdir +% \def\filec@ntents@where{in current directory}} +%\let\filec@ntents@checkdir\@empty +%\def\filec@ntents@where{exists on the system} +%\begingroup% +%\@tempcnta=1 +%\loop +% \catcode\@tempcnta=12 % +% \advance\@tempcnta\@ne % +%\ifnum\@tempcnta<32 % +%\repeat % +%\catcode`\*=11 % +%\catcode`\^^M\active% +%\catcode`\^^L\active\let^^L\relax% +%\catcode`\^^I\active% +%\gdef\filec@ntents#1{% +% \set@curr@file{\filec@ntents@checkdir#1}% +% \edef\q@curr@file{\expandafter\quote@name\expandafter{\@curr@file}}% +% \chardef\reserved@c\ifx\directlua\@undefined 15 \else 127 \fi% +% \openin\@inputcheck\q@curr@file \space % +% \ifeof\@inputcheck% +% \@latex@warning@no@line% +% {Writing file `\@currdir\@curr@file'}% +% \ch@ck7\reserved@c\write\relax% +% \immediate\openout\reserved@c\q@curr@file\relax% +% \else% +% \if@filesw% +% \@latex@warning@no@line% +% {File `\@curr@file' already \filec@ntents@where.\MessageBreak% +% Not generating it from this source}% +% \let\write\@gobbletwo% +% \let\closeout\@gobble% +% \else% +% \edef\reserved@a{#1}% +% \edef\reserved@a{\detokenize\expandafter{\reserved@a}}% +% \edef\reserved@b{\detokenize\expandafter{\jobname}}% +% \ifx\reserved@a\reserved@b% +% \@fileswtrue% +% \else% +% \edef\reserved@b{\reserved@b\detokenize{.tex}}% +% \ifx\reserved@a\reserved@b +% \@fileswtrue% +% \fi% +% \fi% +% \ch@ck7\reserved@c\write\relax% +% \if@filesw% % Foul ... trying to overwrite \jobname! +% \@latex@error{Trying to overwrite `\jobname.tex'}{You can't % +% write to the file you are reading from!\MessageBreak% +% Data is written to screen instead.}% +% \else% +% \@latex@warning@no@line% +% {Writing or overwriting file `\@currdir\@curr@file'}% +% \immediate\openout\reserved@c\q@curr@file\relax% +% \fi% +% \fi% +% \fi% +% \closein\@inputcheck% +% \if@tempswa% +% \immediate\write\reserved@c{% +% \@percentchar\@percentchar\space% +% \expandafter\@gobble\string\LaTeX2e file `\@curr@file'^^J% +% \@percentchar\@percentchar\space generated by the % +% `\@currenvir' \expandafter\@gobblefour\string\newenvironment^^J% +% \@percentchar\@percentchar\space from source `\jobname' on % +% \number\year/\two@digits\month/\two@digits\day.^^J% +% \@percentchar\@percentchar}% +% \fi% +% \let\do\@makeother\dospecials% +% \count@ 128\relax% +% \loop% +% \catcode\count@ 11\relax% +% \advance\count@ \@ne% +% \ifnum\count@<\@cclvi% +% \repeat% +% \edef\E{\@backslashchar end\string{\@currenvir\string}}% +% \edef\reserved@b{% +% \def\noexpand\reserved@b% +% ####1\E####2\E####3\relax}% +% \reserved@b{% +% \ifx\relax##3\relax% +% \immediate\write\reserved@c{##1}% +% \else% +% \edef^^M{\noexpand\end{\@currenvir}}% +% \ifx\relax##1\relax% +% \else% +% \@latex@warning{Writing text `##1' before % +% \string\end{\@currenvir}\MessageBreak as last line of \@curr@file}% +% \immediate\write\reserved@c{##1}% +% \fi% +% \ifx\relax##2\relax% +% \else% +% \@latex@warning{% +% Ignoring text `##2' after \string\end{\@currenvir}}% +% \fi% +% \fi% +% ^^M}% +% \catcode`\^^L\active% +% \let\L\@undefined% +% \def^^L{\expandafter\ifx\csname L\endcsname\relax\fi ^^J^^J}% +% \catcode`\^^I\active% +% \let\I\@undefined% +% \def^^I{\expandafter\ifx\csname I\endcsname\relax\fi\space}% +% \catcode`\^^M\active% +% \edef^^M##1^^M{% +% \noexpand\reserved@b##1\E\E\relax}}% +%\endgroup% +%\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\filec@ntents}{Spaces in file names + optional arg}% % @@ -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 -- cgit v1.2.3