diff options
author | Karl Berry <karl@freefriends.org> | 2020-08-31 21:23:42 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-08-31 21:23:42 +0000 |
commit | 559a5f5789eaa2d6b0c848ebcdbb10d9e4997794 (patch) | |
tree | 9bff60e8286b9ddb26d4ffa06cc3e275716821da /Master/texmf-dist/source | |
parent | 0a15ec8dcd6ba524dfb1f80663dd69d0cc2dd899 (diff) |
latex-dev (31aug20)
git-svn-id: svn://tug.org/texlive/trunk@56225 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
34 files changed, 5568 insertions, 2767 deletions
diff --git a/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx b/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx index e3ad7c60420..05b51683496 100644 --- a/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx +++ b/Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx @@ -86,7 +86,7 @@ Bug reports can be opened (category \texttt{#1}) at\\% % \end{macrocode} % % \begin{macrocode} -\ProvidesPackage{amsmath}[2020/03/17 v2.17g AMS math features] +\ProvidesPackage{amsmath}[2020/08/24 v2.17h AMS math features] % \end{macrocode} % % \section{Catcode defenses} @@ -480,7 +480,7 @@ For additional information on amsmath, use the \lq ?\rq\space option.% \let\negthickspace\@undefined % \end{macrocode} % -% +% % \changes{v2.17g}{2020/03/07}{Math/text spacing commands are now in % the \LaTeX{} kernel and are made robust (gh/303)} % \begin{macrocode} @@ -2203,17 +2203,33 @@ Foreign command \@backslashchar#1;\MessageBreak % The minus sign used in constructing these arrow fills is smashed so % that superscripts above the arrows won't be too high. This % primarily affects the \cn{xleftarrow} and \cn{xrightarrow} arrows. -% +% \changes{v2.17h}{2020/08/24}{detect unicode engines and use their commands} % \begin{macrocode} -\mathchardef\std@minus\mathcode`\-\relax -\mathchardef\std@equal\mathcode`\=\relax +\@ifundefined{Umathcode} + {% + \mathchardef\std@minus\mathcode`\-\relax + \mathchardef\std@equal\mathcode`\=\relax + } + {% + \Umathcharnumdef\std@minus\Umathcodenum`\-\relax + \Umathcharnumdef\std@equal\Umathcodenum`\=\relax + } % \end{macrocode} % In case some alternative math fonts are loaded later: % \begin{macrocode} -\AtBeginDocument{% - \mathchardef\std@minus\mathcode`\-\relax - \mathchardef\std@equal\mathcode`\=\relax -} +\@ifundefined{Umathcode} + {% + \AtBeginDocument{% + \mathchardef\std@minus\mathcode`\-\relax + \mathchardef\std@equal\mathcode`\=\relax + }% + } + {% + \AtBeginDocument{% + \Umathcharnumdef\std@minus\Umathcodenum`\-\relax + \Umathcharnumdef\std@equal\Umathcodenum`\=\relax + }% + } % \end{macrocode} % % \begin{macro}{\relbar} @@ -3725,7 +3741,7 @@ and fix things up.} \fi } % \end{macrocode} -% +% % \begin{macro}{\ams@pos@t} % \begin{macro}{\ams@pos@b} % \begin{macro}{\ams@pos@c} @@ -3817,11 +3833,11 @@ and fix things up.} \crcr % \end{macrocode} % If we picked up a bracket group by mistake here is the place to -% return it for processing. +% return it for processing. % \changes{v2.17g}{2020/03/10}{Explicity test for b/t/c and return % optional argument is different (gh/5)} % \begin{macrocode} - \ams@return@opt@arg + \ams@return@opt@arg } % \end{macrocode} % \end{macro} @@ -3920,7 +3936,7 @@ and fix things up.} % \changes{v2.17g}{2020/03/10}{Explicity test for b/t/c and return % optional argument is different (gh/5)} % \begin{macrocode} - \ams@return@opt@arg + \ams@return@opt@arg }{% \endaligned } diff --git a/Master/texmf-dist/source/latex-dev/base/fontdef.dtx b/Master/texmf-dist/source/latex-dev/base/fontdef.dtx index 936db0d7a28..632f1c9be56 100644 --- a/Master/texmf-dist/source/latex-dev/base/fontdef.dtx +++ b/Master/texmf-dist/source/latex-dev/base/fontdef.dtx @@ -39,7 +39,7 @@ %<driver, >\ProvidesFile{fontdef.drv} % \fi % \ProvidesFile{fontdef.dtx} -%<-latexrelease> [2020/04/24 v3.0h LaTeX Kernel +%<-latexrelease> [2020/08/01 v3.0i LaTeX Kernel % \iftrue (\else %<text, >(Text %<math, >(Math @@ -269,7 +269,7 @@ % % \changes{v3.0a}{2016/12/03}{(DPC) Default to TU encoding for Unicode TeX engines} % \begin{macrocode} -\ifx\Umathchar\@undefined +\ifx\Umathcode\@undefined % \end{macrocode} % % We then set the default text font encoding. This will @@ -436,7 +436,7 @@ % The following three definitions set up the meaning for % |\rmfamily|, |\sffamily|, and |\ttfamily|. % \begin{macrocode} -\ifx\Umathchar\@undefined +\ifx\Umathcode\@undefined \newcommand\encodingdefault{OT1} \newcommand\rmdefault{cmr} \newcommand\sfdefault{cmss} @@ -451,7 +451,7 @@ %</text> %<latexrelease>\IncludeInRelease{2017/01/01}% %<latexrelease> {\encodingdefault}{TU encoding default}% -%<latexrelease>\ifx\Umathchar\@undefined +%<latexrelease>\ifx\Umathcode\@undefined %<latexrelease>\renewcommand\encodingdefault{OT1} %<latexrelease>\fontencoding{\encodingdefault} %<latexrelease>\renewcommand\rmdefault{cmr} diff --git a/Master/texmf-dist/source/latex-dev/base/format.ins b/Master/texmf-dist/source/latex-dev/base/format.ins index 5d96b5e1f35..bad21debd27 100644 --- a/Master/texmf-dist/source/latex-dev/base/format.ins +++ b/Master/texmf-dist/source/latex-dev/base/format.ins @@ -162,7 +162,11 @@ the system are in the document `cfgguide.tex'. \from{ltplain.dtx}{2ekernel} \from{ltvers.dtx}{2ekernel} \from{ltluatex.dtx}{2ekernel} +% This is done as soon as possible here before \texttt{ltdefns.dtx} so that +% we have the extensions as soon as possible. + \from{ltexpl.dtx}{2ekernel} % expl3-based extensions \from{ltdefns.dtx}{2ekernel} + \from{lthooks.dtx}{2ekernel} % L3 layer module \from{ltalloc.dtx}{2ekernel} \from{ltcntrl.dtx}{2ekernel} \from{lterror.dtx}{2ekernel} @@ -195,8 +199,10 @@ the system are in the document `cfgguide.tex'. \from{ltidxglo.dtx}{2ekernel} \from{ltbibl.dtx}{2ekernel} \from{ltpage.dtx}{2ekernel} + \from{ltclass.dtx}{2ekernel,tracerollback} + \from{ltfilehook.dtx}{2ekernel} % L3 layer module + \from{ltshipout.dtx}{2ekernel} % L3 layer module \from{ltoutput.dtx}{2ekernel} - \from{ltclass.dtx}{2ekernel,tracerollback} \from{ltfinal.dtx}{2ekernel}} \file{tracefnt.sty}{% \from{ltfsstrc.dtx}{package,trace}} @@ -225,8 +231,19 @@ the system are in the document `cfgguide.tex'. } -% expl3-based extensions -\generate{\file{ltexpl.ltx}{\from{ltexpl.dtx}{2ekernel}}} +% hook management support + +\generate{\file{everyshi-ltx.sty}{\from{ltshipout.dtx}{everyshi-ltx}}} % emulating everyshi +\generate{\file{atbegshi-ltx.sty}{\from{ltshipout.dtx}{atbegshi-ltx}}} % emulating atbegshi +\generate{\file{atveryend-ltx.sty}{\from{ltfilehook.dtx}{atveryend-ltx}}} % emulating atveryend + +\generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}} + +%drafts to get removed +\generate{\file{filehook-ltx.sty}{\from{ltfilehook.dtx}{filehook-draft}}} +\generate{\file{srclfile-ltx.sty}{\from{ltfilehook.dtx}{scrlfile-draft}}} + + % luatex support (TeX part) diff --git a/Master/texmf-dist/source/latex-dev/base/inputenc.dtx b/Master/texmf-dist/source/latex-dev/base/inputenc.dtx index 01a8303ecf1..c1d08b4830f 100644 --- a/Master/texmf-dist/source/latex-dev/base/inputenc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/inputenc.dtx @@ -410,7 +410,7 @@ %<cp1252&!ansinew> \ProvidesFile{cp1252.def} %<cp1250> \ProvidesFile{cp1250.def} %<cp1257> \ProvidesFile{cp1257.def} - [2020/04/14 v1.3c Input encoding file] + [2020/08/01 v1.3d Input encoding file] %<cp850>%% %<cp850>%% If you need a Euro symbol, try cp858 instead. %<cp850>%% @@ -545,7 +545,7 @@ % produces a warning message if no suitable definitions get read. % % \begin{macrocode} -\ifx\Umathchar\@undefined +\ifx\Umathcode\@undefined % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/latex209.dtx b/Master/texmf-dist/source/latex-dev/base/latex209.dtx index 6523e65286f..d08a8001b56 100644 --- a/Master/texmf-dist/source/latex-dev/base/latex209.dtx +++ b/Master/texmf-dist/source/latex-dev/base/latex209.dtx @@ -200,7 +200,7 @@ % \end{macrocode} % Describe the file. % \begin{macrocode} -\ProvidesFile{latex209.def}[2018/08/11 v0.54 Standard LaTeX file] +\ProvidesFile{latex209.def}[2020/08/21 v0.55 Standard LaTeX file] % \end{macrocode} % \changes{v0.24}{1994/05/14}{Removed date.} % \changes{v0.40}{1995/03/21} @@ -469,6 +469,12 @@ \saved@missingfileerror{#1}{#2}% \fi } +\@ifundefined{@missing@onefilewithoptions}{}{% + \def\@missing@onefilewithoptions#1{% + \@pass@ptions\@currext{#1}{\@currname}% + \@missingfileerror\@currname\@currext + \let\@currname\@empty}% +} % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/latexrelease.ins b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins index ff55e7d8c0e..99af17e8fb6 100644 --- a/Master/texmf-dist/source/latex-dev/base/latexrelease.ins +++ b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins @@ -86,7 +86,9 @@ extension .ins) which are part of the distribution. \from{ltvers.dtx} {latexrelease}% \from{latexrelease.dtx}{latexrelease}% \from{ltdirchk.dtx} {latexrelease}% + \from{ltexpl.dtx} {latexrelease}% empty \from{ltdefns.dtx} {latexrelease}% + \from{lthooks.dtx} {latexrelease}% empty % L3 layer module \from{ltalloc.dtx} {latexrelease}% empty \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty @@ -106,6 +108,8 @@ extension .ins) which are part of the distribution. \from{ltidxglo.dtx} {latexrelease}% empty \from{ltbibl.dtx} {latexrelease}% empty \from{ltpage.dtx} {latexrelease}% empty + \from{ltfilehook.dtx} {latexrelease}% empty % L3 layer module + \from{ltshipout.dtx} {latexrelease}% empty % L3 layer module \from{ltoutput.dtx} {latexrelease}% \from{ltclass.dtx} {latexrelease,tracerollback}% \from{ltspace.dtx} {latexrelease}% diff --git a/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx b/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx index 051922b6f3e..e5d5c9264df 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltboxes.dtx} - [2020/03/06 v1.3c LaTeX Kernel (Box Commands)] + [2020/10/01 v1.4a LaTeX Kernel (Box Commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltboxes.dtx} @@ -365,8 +365,13 @@ % \begin{macro}{\@imakepicbox} % picture mode version % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@imakepicbox}{default units}% \long\def\@imakepicbox(#1,#2)[#3]#4{% - \vbox to#2\unitlength + \@defaultunitsset\@tempdimc{#2}\unitlength + \vbox to\@tempdimc {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss \let\mb@t\vss \@tfor\reserved@a :=#3\do{% @@ -376,15 +381,38 @@ \expandafter\let\csname mb@\reserved@a\endcsname\relax \fi}% \mb@t - \hb@xt@ #1\unitlength{\mb@l #4\mb@r}% + \@defaultunitsset\@tempdimc{#1}\unitlength + \hb@xt@\@tempdimc{\mb@l #4\mb@r}% \mb@b % \end{macrocode} % This kern ensures that a |b| option aligns on the bottom of the % text rather than the baseline. this is the documented behaviour in -% the \LaTeX Book. The kern is removed in compatibility mode. +% the \LaTeX\ Book. The kern is removed in compatibility mode. % \begin{macrocode} \kern\z@}} +%</2ekernel|latexrelease> % \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@imakepicbox}{default units}% +%<latexrelease>\long\def\@imakepicbox(#1,#2)[#3]#4{% +%<latexrelease> \vbox to#2\unitlength +%<latexrelease> {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss +%<latexrelease> \let\mb@t\vss +%<latexrelease> \@tfor\reserved@a :=#3\do{% +%<latexrelease> \if s\reserved@a +%<latexrelease> \let\mb@l\relax\let\mb@r\relax +%<latexrelease> \else +%<latexrelease> \expandafter\let\csname mb@\reserved@a\endcsname\relax +%<latexrelease> \fi}% +%<latexrelease> \mb@t +%<latexrelease> \hb@xt@ #1\unitlength{\mb@l #4\mb@r}% +%<latexrelease> \mb@b +%<latexrelease> \kern\z@}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macro} % % diff --git a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx b/Master/texmf-dist/source/latex-dev/base/ltclass.dtx index 152adf82ff2..7b1dbc81275 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/06/05 v1.3l LaTeX Kernel (Class & Package Interface)] + [2020/08/29 v1.3p 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} @@ -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} @@ -561,6 +568,16 @@ %<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}% @@ -582,16 +599,21 @@ \@onlypreamble\@pushfilename % \end{macrocode} % +% +% +% +% % \changes{v1.3l}{2020/06/05}{Added \cs{@expl@pop@filename@@}} % \begin{macrocode} %<latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}{\@popfilename}% %<latexrelease> {Add \@expl@pop@filename@@}% -\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil +\def\@popfilename{\@expl@@@hook@curr@name@pop@@ + \expandafter\@p@pfilename\@currnamestack\@nil \@expl@pop@filename@@} %<latexrelease>\EndIncludeInRelease %<latexrelease> -%<latexrelease>\IncludeInRelease{0000/00/00}{\@pushfilename}% +%<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 @@ -603,6 +625,8 @@ %<*2ekernel> % \end{macrocode} % +% +% % \begin{macrocode} \def\@p@pfilename#1#2#3#4\@nil{% \gdef\@currname{#1}% @@ -1609,6 +1633,11 @@ \@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} @@ -1625,55 +1654,171 @@ %</2ekernel> %<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\@onefilewithoptions}{Unused options issue}% +%<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 + \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} +% 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{\@currname.\@currext}{}{}% +%----------------------------------------- % \end{macrocode} % In older versions of the code |\@unprocessedoptions| would % generate an error for each specified @@ -1717,44 +1862,39 @@ % \begin{macrocode} \expandafter\let \csname unprocessedoptions-\@currname.\@currext\endcsname - \@undefined}% -% \end{macrocode} -% -% \begin{macrocode} - \@ifl@ter\@currext{#1}{#3}{}% - {\@latex@warning@no@line - {You have requested,\on@line, - version\MessageBreak - `#3' of \@cls@pkg\space #1,\MessageBreak - but only version\MessageBreak - `\csname ver@#1.\@currext\endcsname'\MessageBreak - is available}}% + \@undefined % \end{macrocode} -% \changes{v0.2c}{1993/11/17} -% {Added trap for two \cs{LoadClass} commands.} +% And same procedure, James, when we are finished loading, except +% that the hook order is now reversed. % \begin{macrocode} - \ifx\@currext\@clsextension\let\LoadClass\@twoloadclasserror\fi - \@popfilename - \@reset@ptions}% +%----------------------------------------- + \ifx\@currext\@pkgextension + \UseHook{package/after/\@currname}% + \UseHook{package/after}% + \else + \ifx\@currext\@clsextension + \UseHook{class/after/\@currname}% + \UseHook{class/after}% + \fi + \fi}% +%----------------------------------------- \reserved@a} -\@onlypreamble\@onefilewithoptions % \end{macrocode} -% -% The kernel no longer uses \cs{@unprocessedoptions} +% \end{macro} +% % \begin{macrocode} -\let\@unprocessedoptions\@undefined +%</2ekernel|latexrelease> % \end{macrocode} % % \begin{macrocode} -%</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\@onefilewithoptions}{Unused options issue}% +%<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 rollowing back! +% \cs{load@onefilewithoptions} when rolling back! % \begin{macrocode} %<latexrelease>\def\load@onefilewithoptions#1[#2][#3]#4{% %<latexrelease> \@pushfilename @@ -1805,6 +1945,10 @@ %<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} @@ -1846,7 +1990,7 @@ % % \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 @@ -1866,25 +2010,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} @@ -1903,8 +2028,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} @@ -2036,8 +2182,8 @@ % \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| @@ -2080,7 +2226,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 @@ -2106,10 +2252,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). @@ -2270,6 +2418,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> @@ -3015,7 +3293,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 diff --git a/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx b/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx index 3abd251e4c9..ea6a924f98f 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2020/06/04 v1.5i LaTeX Kernel (definition commands)] + [2020/08/21 v1.5m LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -90,6 +90,7 @@ % \changes{v1.0p}{1995/07/13}{Updates to documentation} % \changes{v1.4b}{2015/02/21} % {Removed autoload support} +% \changes{v1.5l}{2020/08/21}{Integration of new hook management interface} % % \section{Definitions} % @@ -101,15 +102,6 @@ %<*2ekernel> % \end{macrocode} % -% \subsection{Loading further extensions} -% -% \changes{v1.5i}{2020-06-04}{Load \textsf{ltexpl} in \texttt{ltdefns}} -% Simply load further code: it's deliberately separate. -% This is done as soon as possible here in \texttt{ltdefns.dtx} so that -% we have the extensions as soon as possible. -% \begin{macrocode} -\input ltexpl.ltx -% \end{macrocode} % % \subsection{Initex initialisations} % @@ -392,8 +384,9 @@ % % \begin{macro}{\@carcube} % |\@carcube T1 ... Tn\@nil| = |T1| |T2| |T3| , $n > 3$ +% \changes{v1.5k}{2020/08/19}{Made \cs{long} for \cs{NewCommandCopy}} % \begin{macrocode} -\def\@carcube#1#2#3#4\@nil{#1#2#3} +\long\def\@carcube#1#2#3#4\@nil{#1#2#3} % \end{macrocode} % \end{macro} % @@ -671,7 +664,7 @@ % \begin{macro}{\@ifdefinable} % \begin{macro}{\@@ifdefinable} % \begin{macro}{\@rc@ifdefinable} -% Test is user is allowed to define a command. +% Test if user is allowed to define a command. % \begin{macrocode} \long\def\@ifdefinable #1#2{% \edef\reserved@a{\expandafter\@gobble\string #1}% @@ -1200,6 +1193,8 @@ % \changes{v1.4a}{2015/01/08}{Added macro} % \changes{v1.5f}{2019/08/27}{Make the assignments global as we may % need to apply them inside a group} +% \changes{v1.5m}{2020/08/21}{Make \cs{MakeRobust} produce the same +% command structure as \cs{DeclareRobustCommand}} % % This macro makes an existing fragile macro robust, but only if it % hasn't been robust in the past, i.e., it checks for the existence @@ -1218,9 +1213,11 @@ % at all. % \begin{macrocode} %</2ekernel> -%<latexrelease>\IncludeInRelease{2019/10/01}{\MakeRobust}{\MakeRobust}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\MakeRobust}{\MakeRobust}% %<*2ekernel|latexrelease> \def\MakeRobust#1{% + \count@=\escapechar + \escapechar=`\\ \@ifundefined{\expandafter\@gobble\string#1}{% \@latex@error{The control sequence `\string#1' is undefined!% \MessageBreak There is nothing here to make robust}% @@ -1232,12 +1229,15 @@ % \verb*=\foo =. If it is already defined do nothing, otherwise set % \verb*=\foo = equal to \verb*=\foo= and redefine \verb*=\foo= so % that it acts like a macro defined with \verb=\DeclareRobustCommand=. +% We use \cs{@kernel@rename@newcommand} to copy \verb*=\foo= over to +% \verb*=\foo =, including a possible default optional argument. % \begin{macrocode} {% \@ifundefined{\expandafter\@gobble\string#1\space}% {% - \global\expandafter\let\csname - \expandafter\@gobble\string#1\space\endcsname=#1% + \expandafter\@kernel@rename@newcommand + \csname\expandafter\@gobble\string#1\space\endcsname + #1% \edef\reserved@a{\string#1}% \def\reserved@b{#1}% \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% @@ -1249,10 +1249,72 @@ \csname\expandafter\@gobble\string#1\space\endcsname}% }% {\@latex@info{The control sequence `\string#1' is already robust}}% - }% + }% + \escapechar=\count@ }% +% \end{macrocode} +% +% \begin{macro}{\@kernel@rename@newcommand} +% This macro renames a command, possibly with an optional argument (defined +% with \cs{newcommand}) from |#2| to |#1|, by renaming the internal macro +% \verb=\\#2= to \verb=\\#1= and defining \verb=\#1= appropriately, then +% undefining \verb=\#2= and \verb=\\#2=. The \cs{afterassignment} trick is +% to make both definitions in \cs{@copy@newcommand} global (which are local +% by default). +% +% In case the macro was defined with \cs{newcommand} and an optional +% argument, to replicate exactly the behaviour of \cs{DeclareRobustCommand} +% we have to move also the internal \verb*=\\foo= to \verb*=\\foo =. In that +% case, \verb=#1= will be a parameterless macro (\cs{robust@command@chk@safe} +% checks that), and \cs{@if@newcommand} will return true (both defined below +% in this file). If so, we can use \cs{@copy@newcommand} rather than plain +% \cs{let} to copy the command over. \cs{@kernel@rename@newcommand} does +% this test and carries out the renaming. +% \begin{macrocode} +\def\@kernel@rename@newcommand#1#2{% + \robust@command@chk@safe#2% + {\@if@newcommand#2% + {\afterassignment\global + \global\@copy@newcommand#1#2% + \global\let#2\@undefined + \global\expandafter\let\csname\string#2\endcsname\@undefined}% + {\global\let#1=#2}}% + {\global\let#1=#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +% +%<latexrelease>\IncludeInRelease{2019/10/01}{\MakeRobust}{\MakeRobust}% +%<latexrelease>\def\MakeRobust#1{% +%<latexrelease> \@ifundefined{\expandafter\@gobble\string#1}{% +%<latexrelease> \@latex@error{The control sequence `\string#1' is undefined!% +%<latexrelease> \MessageBreak There is nothing here to make robust}% +%<latexrelease> \@eha +%<latexrelease> }% +%<latexrelease> {% +%<latexrelease> \@ifundefined{\expandafter\@gobble\string#1\space}% +%<latexrelease> {% +%<latexrelease> \global\expandafter\let\csname +%<latexrelease> \expandafter\@gobble\string#1\space\endcsname=#1% +%<latexrelease> \edef\reserved@a{\string#1}% +%<latexrelease> \def\reserved@b{#1}% +%<latexrelease> \edef\reserved@b{\expandafter\strip@prefix\meaning\reserved@b}% +%<latexrelease> \xdef#1{% +%<latexrelease> \ifx\reserved@a\reserved@b +%<latexrelease> \noexpand\x@protect\noexpand#1% +%<latexrelease> \fi +%<latexrelease> \noexpand\protect\expandafter\noexpand +%<latexrelease> \csname\expandafter\@gobble\string#1\space\endcsname}% +%<latexrelease> }% +%<latexrelease> {\@latex@info{The control sequence `\string#1' is already robust}}% +%<latexrelease> }% +%<latexrelease>}% +%<latexrelease>\let\@kernel@rename@newcommand\@undefined +%<latexrelease>\EndIncludeInRelease +% %<latexrelease>\IncludeInRelease{2015/01/01}{\MakeRobust}{\MakeRobust}% %<latexrelease>\def\MakeRobust#1{% %<latexrelease> \@ifundefined{\expandafter\@gobble\string#1}{% @@ -1278,17 +1340,17 @@ %<latexrelease> {\@latex@info{The control sequence `\string#1' is already robust}}% %<latexrelease> }% %<latexrelease>}% +%<latexrelease>\let\@kernel@rename@newcommand\@undefined %<latexrelease>\EndIncludeInRelease +% %<latexrelease>\IncludeInRelease{0000/00/00}{\MakeRobust}{\MakeRobust}% %<latexrelease>\let\MakeRobust\@undefined +%<latexrelease>\let\@kernel@rename@newcommand\@undefined %<latexrelease>\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} % -% -% - % \begin{macro}{\kernel@make@fragile} % The opposite of |\MakeRobust| execpt that it doesn't do many % checks as it is internal to the kernel. Why does one want such a @@ -1302,7 +1364,7 @@ % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease>\IncludeInRelease{2020/10/01}% %<latexrelease> {\kernel@make@fragile}{Undo robustness}% \def\kernel@make@fragile#1{% \@ifundefined{\expandafter\@gobble\string#1\space}% @@ -1311,16 +1373,39 @@ % \begin{macrocode} {}% % \end{macrocode} -% Otherwise copy \verb*=\foo = back to \verb=\foo= and then undefine -% the payload command. +% Otherwise copy \verb*=\foo = back to \verb=\foo=. +% Then use \cs{@kernel@rename@newcommand} to check and copy +% \verb*=\\foo = back to \verb*=\\foo= in case the command has an optional +% argument. If so, also undefine \verb*=\\foo =, and at the end undefine +% \verb*=\foo =. % \begin{macrocode} {% \global\expandafter\let\expandafter #1\csname - \expandafter\@gobble\string#1\space\endcsname + \expandafter\@gobble\string#1\space\endcsname + \expandafter\@kernel@rename@newcommand + \csname\expandafter\@gobble\string#1\expandafter\endcsname + \csname\expandafter\@gobble\string#1\space\endcsname \global\expandafter\let\csname - \expandafter\@gobble\string#1\space\endcsname\@undefined + \expandafter\@gobble\string#1\space\endcsname\@undefined }% } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +% +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\kernel@make@fragile}{Undo robustness}% +%<latexrelease>\def\kernel@make@fragile#1{% +%<latexrelease> \@ifundefined{\expandafter\@gobble\string#1\space}% +%<latexrelease> {}% +%<latexrelease> {% +%<latexrelease> \global\expandafter\let\expandafter #1\csname +%<latexrelease> \expandafter\@gobble\string#1\space\endcsname +%<latexrelease> \global\expandafter\let\csname +%<latexrelease> \expandafter\@gobble\string#1\space\endcsname\@undefined +%<latexrelease> }% +%<latexrelease>} %<latexrelease>\EndIncludeInRelease %</2ekernel|latexrelease> %<*2ekernel> @@ -1328,6 +1413,552 @@ % \end{macro} % % +% \subsection{Acting on robust commands} +% +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020-10-01}{\robust@command@act} +%<latexrelease> {Add \robust@command@act}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% With most document level commands being robust now there is more of a +% requirement to have a standard way of aliasing (or copying) a command to a +% new name, for example to save an original definition before changing a +% command. \cs{DeclareCommandCopy} is analogous to \TeX's \cs{let}, except +% that it copes with the different types of robust commands defined by +% \LaTeX's mechanisms. +% +% A couple of ``types of robustness'' are defined by the \LaTeXe{} kernel, +% namely robust commands defined with \cs{DeclareRobustCommand} and commands +% with optional arguments defined with \cs{newcommand}. However there are +% other types of robust commands that are frequently used, which are not +% defined in the \LaTeXe{} kernel, like commands defined with +% \textsf{xparse}'s \cs{NewDocumentCommand} and \textsf{etoolbox}'s +% \cs{newrobustcmd}. +% +% In this section we will define a generic extensible machinery to act on +% robust commands. This code will then be used to test if a command is +% robust, considered the different types of robustness, and then either copy +% that definition, if \cs{DeclareCommandCopy} (or similar) is used, or show +% the definition of the command, if \cs{ShowCommmand} is used. +% +% \begin{macro}{\robust@command@act} +% \changes{v1.5k}{2020/08/19}{Made \cs{robust@command@act} +% (was \cs{declare@command@copy}) more generic} +% +% The looping machinery is generic and knows nothing about what is to be done +% for each case. The syntax of the main macro \cs{robust@command@act} is: +% \begin{quote} +% |\robust@command@act|\meta{action-list}\meta{robust-cmd}\\ +% \meta{fallback-action}\meta{act-arg} +% \end{quote} +% \meta{action-list} is a token list of the form: +% \begin{quote} +% |{|\meta{if-type-1} \meta{act-type-1}|}|\\ +% |{|\meta{if-type-2} \meta{act-type-2}|}|\\ +% \ldots +% \end{quote} +% \cs{robust@command@act} will iterate over the \meta{action-list}, evaluating +% each \meta{if-type-$n$}\meta{robust-cmd}|{|\meta{true}|}{|\meta{false}|}|. +% If the \meta{if-type-$n$} conditional returns \meta{true}, then +% \meta{act-type-$n$}\meta{act-arg} is executed, and the loop ends. If the +% conditional returns \meta{false}, then \meta{if-type-$n+1$} is executed in +% the same way, until either one of the conditionals return \meta{true}, or +% the end of the \meta{action-list} is reached. If the end is reached, then +% \meta{fallback-action}\meta{act-arg} is executed before +% \cs{robust@command@act} exits. +% +% \cs{robust@command@act} will start by using \cs{robust@command@act@chk@args} +% to check if the \meta{robust-cmd} (|#2|) is a parameterless (possibly +% \cs{protected}) macro. If it is not, the command is not a robust command: +% these always start with a parameterless user-level macro; in that case, +% \cs{robust@command@act@end} is used to short-circuit the process and do the +% \meta{fallback-action} (|#3|). This first test is necessary because later +% on we need to be able to expand the \meta{robust-cmd} without the risk of it +% Breaking Badly, and as a bonus, this speeds up the process in case we used +% \cs{NewCommandCopy} in a ``normal'' macro. +% \begin{macrocode} +\long\def\robust@command@act#1#2#3#4{% + \robust@command@chk@safe#2% + {\expandafter\robust@command@act@loop + \expandafter#2% + #1{\@nnil\@nnil}% + \robust@command@act@end}% + {\robust@command@act@end}% + {#3}{#4}}% +% \end{macrocode} +% +% \begin{macro}{\robust@command@act@loop} +% \begin{macro}{\robust@command@act@loop@aux} +% \begin{macro}{\robust@command@act@do} +% If \cs{robust@command@act@chk@args} branched to false, then +% \cs{robust@command@act@loop} will loop over the list of items in the +% \meta{action-list} (|#1|), and process each item as described earlier. +% If the \meta{if-type-$n$} command expands to \meta{true} then +% \cs{robust@command@act@do} is used to execute \meta{act-type-$n$} on the +% \meta{act-arg}, otherwise the loop resumes with the next item. +% \begin{macrocode} +\long\def\robust@command@act@loop#1#2{\robust@command@act@loop@aux#1#2} +\long\def\robust@command@act@loop@aux#1#2#3{% + \ifx\@nnil#2% + \else + #2{#1}% + {\robust@command@act@do{#3}}% + {\expandafter\robust@command@act@loop\expandafter#1}% + \fi} +\long\def\robust@command@act@do#1% + \fi#2% + \robust@command@act@end#3#4{% + \fi + #1#4} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\robust@command@act@end} +% If the end is reached and no action was taken, then do +% \meta{fallback-action}\meta{act-arg}. +% \begin{macrocode} +\long\def\robust@command@act@end#1#2{#1#2} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\robust@command@chk@safe} +% \begin{macro}{\robust@command@act@chk@args} +% \begin{macrocode} +\long\def\robust@command@chk@safe#1{% + \begingroup + \escapechar=`\\ + \expandafter\endgroup\expandafter + \robust@command@act@chk@args\meaning#1:->\@nil} +\def\robust@command@act@chk@args#1:->#2\@nil{% + \@expl@str@if@eq@@nnTF{#1}{macro}% + {\@firstoftwo}% + {\@expl@str@if@eq@@nnTF{#1}{\protected macro}% + {\@firstoftwo}% + {\@secondoftwo}}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\robust@command@act} +%<latexrelease> {Add \robust@command@act}% +%<latexrelease>\let\robust@command@act\@undefined +%<latexrelease>\let\robust@command@act@loop\@undefined +%<latexrelease>\let\robust@command@act@loop@aux\@undefined +%<latexrelease>\let\robust@command@act@do\@undefined +%<latexrelease>\let\robust@command@act@end\@undefined +%<latexrelease>\let\robust@command@chk@safe\@undefined +%<latexrelease>\let\robust@command@act@chk@args\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \end{macro} +% +% +% \subsubsection{Copying robust commands} +% +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020-10-01}{\DeclareCommandCopy} +%<latexrelease> {Add \NewCommandCopy, \RenewCommandCopy, and \DeclareCommandCopy}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macro}{\NewCommandCopy} +% \begin{macro}{\RenewCommandCopy} +% \begin{macro}{\DeclareCommandCopy} +% \changes{v1.5j}{2020/05/09}{Added \cs{DeclareCommandCopy} (gh/239)} +% +% \cs{NewCommandCopy} starts by checking if \verb=#1= is already defined, and +% raises an error if so, otherwise the definition is carried out. +% \cs{RenewCommandCopy} does (almost) the opposite. If the command is +% \emph{not} defined, then an error is raised. But the definition is carried +% out anyhow, so the behaviour is consistent with \cs{renewcommand}. +% +% A \cs{ProvideCommandCopy} isn't defined because it's not reasonably useful. +% \verb=\provide...= commands mean ``define this if there's no other +% definition'', but copying a command (usually) implies that the command being +% copied is defined, so \cs{ProvideCommandCopy} doesn't make a lot of sense. +% But more importantly, the most common use case of copying a command is to +% redefine it later, while preserving the old definition, as in: +% \begin{verbatim} +% \ProvideComandCopy \A \B +% \renewcommand \B { ... \A ... } +% \end{verbatim} +% then, if \verb=\A= is already defined the first line is skipped, an in this +% case \verb=\B= won't work as expected. +% +% The three versions call the internal \cs{declare@commandcopy} with the +% proper action. \cs{@firstofone} will carry out the copy. The only case +% when the copy is not made is the \meta{false} case for \cs{NewCommandCopy}, +% in which the command already exists and the definition is aborted. +% \begin{macrocode} +\def\NewCommandCopy{% + \declare@commandcopy + {\@firstofone}% + {\@firstoftwo\@notdefinable}} +\def\RenewCommandCopy{% + \declare@commandcopy + {\@latex@error{Command \@backslashchar\reserved@a\space undefined}\@ehc + \@firstofone}% + {\@firstofone}} +\def\DeclareCommandCopy{% + \declare@commandcopy + {\@firstofone}% + {\@firstofone}} +% \end{macrocode} +% +% \begin{macro}{\declare@commandcopy} +% Start by checking if the command is already defined. The proper action is +% taken by each specific command above. If all's good, then +% \cs{robust@command@act} is called with the proper arguments as described +% earlier, with \cs{@declarecommandcopylisthook} as the \meta{action-list} and +% \cs{declare@commandcopy@let} as the \meta{fallback-action}. +% \begin{macrocode} +\long\def\declare@commandcopy#1#2#3#4{% + \edef\reserved@a{\@expl@cs@to@str@@N#3}% + \@ifundefined\reserved@a{#1}{#2}% + {\robust@command@act + \@declarecommandcopylisthook#4% + \declare@commandcopy@let{#3#4}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@declarecommandcopylisthook} +% The initial definition of \cs{@declarecommandcopylisthook} contains the +% tests for the two types of robust command in the kernel. +% \begin{macrocode} +\def\@declarecommandcopylisthook{% + {\@if@DeclareRobustCommand \@copy@DeclareRobustCommand}% + {\@if@newcommand \@copy@newcommand}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\declare@commandcopy@let} +% The initial definition of \cs{@declarecommandcopylisthook} contains the +% tests for the two types of robust command in the kernel. +% \begin{macrocode} +\long\def\declare@commandcopy@let#1#2{\let#1=#2\relax} +% \end{macrocode} +% \end{macro} +% +% Now the rollback code. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\DeclareCommandCopy} +%<latexrelease> {Undefine \NewCommandCopy, \RenewCommandCopy, and \DeclareCommandCopy}% +%<latexrelease>\let\NewCommandCopy\@undefined +%<latexrelease>\let\RenewCommandCopy\@undefined +%<latexrelease>\let\DeclareCommandCopy\@undefined +%<latexrelease>\let\declare@commandcopy\@undefined +%<latexrelease>\let\@declarecommandcopylisthook\@undefined +%<latexrelease>\let\declare@commandcopy@let\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Showing robust commands} +% +% \begin{macro}{\ShowCommand} +% \changes{v1.5k}{2020/08/19}{Added \cs{ShowCommand} (gh/373)} +% +% Most of the machinery defined for \cs{NewCommandCopy} can be used to show +% the definition of a robust command, in a similar fashion to \texttt{texdef}. +% The difference is that after the command's is detected to has a given type +% of robustness, rather than making a copy, we use a separate routine to show +% its definition. +% +% With all the machinery in place, \cs{ShowCommand} itself is quite simple: +% use \cs{robust@command@act} to iterate through the \cs{@showcommandlisthook} +% list, and if nothing is found, fallback to \cs{show}. +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020-10-01}{\ShowCommand}% +%<latexrelease> {Add \ShowCommand}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +\long\def\ShowCommand#1{% + \robust@command@act + \@showcommandlisthook#1% + \show#1} +% \end{macrocode} +% +% \begin{macro}{\@showcommandlisthook} +% The initial definition of \cs{@showcommandlisthook} contains the same tests +% as used for copying, but \cs{@show@...} commands instead of \cs{@copy@...}. +% Same as before, it is initialised to cope with \cs{DeclareRobustCommand} and +% \cs{newcommand} with optional arguments. +% \begin{macrocode} +\def\@showcommandlisthook{% + {\@if@DeclareRobustCommand \@show@DeclareRobustCommand}% + {\@if@newcommand \@show@newcommand}} +% \end{macrocode} +% \end{macro} +% +% Now the rollback code. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\ShowCommand} +%<latexrelease> {Undefine \ShowCommand}% +%<latexrelease>\let\ShowCommand\@undefined +%<latexrelease>\let\@showcommandlisthook\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020-10-01}{\@if@DeclareRobustCommand} +%<latexrelease> {Add \@if@DeclareRobustCommand, \@if@newcommand, +%<latexrelease> \@copy@DeclareRobustCommand, \@copy@newcommand, +%<latexrelease> \@show@DeclareRobustCommand, \@show@newcommand}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \subsubsection{Commands defined with \cs{DeclareRobustCommand}} +% +% \begin{macro}{\@if@DeclareRobustCommand} +% \changes{v1.5j}{2020/05/09}{Added \cs{DeclareCommandCopy} (gh/239)} +% +% Now that we provided a generic way to copy one macro to another, we need to +% define a way to check if a command is one of \LaTeXe's robust types. These +% tests are heavily based on Heiko's \cs{LetLtxMacro}, but chopped into +% separate macros. +% +% \cs{@if@DeclareRobustCommand} checks if a command \verb=\cmd= was defined by +% \cs{DeclareRobustCommand}. The test returns true if the expansion of +% \verb=\cmd= is exactly \verb*=\protect\cmd =. +% +% \begin{macrocode} +\long\def\@if@DeclareRobustCommand#1{% + \begingroup + \escapechar=`\\ + \edef\reserved@a{\string#1}% + \edef\reserved@b{\detokenize{#1}}% + \xdef\@gtempa{% + \ifx\reserved@a\reserved@b + \noexpand\x@protect + \noexpand#1% + \fi + \noexpand\protect + \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname}% + \endgroup + \ifx\@gtempa#1\relax + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi} +% \end{macrocode} +% +% \begin{macro}{\@copy@DeclareRobustCommand} +% \begin{macro}{\copy@kernel@robust@command} +% If a command was defined by \cs{DeclareRobustCommand} (that is, +% \cs{@if@DeclareRobustCommand} returns true), then to make a copy of \verb=\cmd= +% into \verb=\foo= we define the latter such that it expands to +% \verb*=\protect\foo =, then make \verb*=\foo = equal to \verb*=\cmd =. +% +% There is one detail we need to take care of: if a command was defined with +% \cs{DeclareRobustCommand} it may still have an optional argument, in which +% case there is one more macro layer before the actual definition of the +% command. We use \cs{@if@newcommand} to check that and +% \cs{@copy@newcommand} to do the copying. +% \begin{macrocode} +\long\def\@copy@DeclareRobustCommand#1#2{% + \begingroup + \escapechar=`\\ + \edef\reserved@a{\string#1}% + \edef\reserved@b{\detokenize{#1}}% + \edef\reserved@a{% + \endgroup + \def\noexpand#1{% + \ifx\reserved@a\reserved@b + \noexpand\x@protect + \noexpand#1% + \fi + \noexpand\protect + \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname}% + \noexpand\copy@kernel@robust@command + \expandafter\noexpand\csname\@expl@cs@to@str@@N#1 \endcsname + \expandafter\noexpand\csname\@expl@cs@to@str@@N#2 \endcsname}% + \reserved@a} +\long\def\copy@kernel@robust@command#1#2{% + \robust@command@chk@safe#2% + {\@if@newcommand#2% + {\@copy@newcommand}% + {\declare@commandcopy@let}} + {\declare@commandcopy@let}% + #1#2} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@show@DeclareRobustCommand} +% \begin{macro}{\show@kernel@robust@command} +% Showing the command is pretty simple. This command prints the top-level +% expansion as \TeX's \cs{show} would, but with |robust macro:| rather than +% just |macro:|, then a blank line and then \cs{show} the inner command. +% For a macro defined with, say, |\DeclareRobustCommand\foo[1]{bar}|, it will +% print: +% \begin{verbatim} +% > \foo=robust macro: +% ->\protect \foo . +% +% > \foo =\long macro: +% #1->bar. +% \end{verbatim} +% If the inner command is defined with an optional argument, then +% \cs{@show@newcommand} is also used. +% +% The value of \cs{escapechar} is deliberately not enforced, so +% \cs{ShowCommand} behaves more like \cs{show}. +% \begin{macrocode} +\long\def\@show@DeclareRobustCommand#1{% + \typeout{> \string#1=robust macro:}% + \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}% + \expandafter\show@kernel@robust@command + \csname\@expl@cs@to@str@@N#1 \endcsname} +\long\def\show@kernel@robust@command#1{% + \robust@command@chk@safe#1% + {\@if@newcommand#1% + {\@show@newcommand}% + {\show}}% + {\show}% + #1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \end{macro} +% +% \subsubsection{Commands defined with \cs{newcommand} (with optional argument)} +% +% \begin{macro}{\@if@newcommand} +% A command \verb=\cmd= (or \verb*=\cmd =, if it was defined with +% \cs{DeclareRobustCommand}) with an optional argument will expand to +% \verb*=\@protected@testopt\cmd\\cmd{<opt>}=. To check that we look at the +% first three tokens in the expansion of \verb=\cmd=, and return true or false +% accordingly. +% +% This test \emph{requires} that the command be a parameterless macro, +% otherwise it will not work (and probably break). This is ensured with +% \cs{robust@command@chk@safe} before calling \cs{@if@newcommand}. +% \begin{macrocode} +\long\def\@if@newcommand#1{% + \edef\reserved@a{% + \noexpand\@protected@testopt + \noexpand#1% + \expandafter\noexpand\csname\@backslashchar\@expl@cs@to@str@@N#1\endcsname}% + \edef\reserved@b{% + \unexpanded\expandafter\expandafter\expandafter + {\expandafter\@carcube#1{}{}{}\@nil}}% + \ifx\reserved@a\reserved@b + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi} +% \end{macrocode} +% +% \begin{macro}{\@copy@newcommand} +% Then, if a command \verb=\cmd= takes an optional argument, we copy it to +% \verb=\foo= by defining the latter to expand to +% \verb=\@protected@testopt\foo\\foo{<opt>}=. +% \begin{macrocode} +\long\def\@copy@newcommand#1#2{% + \edef#1{\noexpand\@protected@testopt + \noexpand#1% + \expandafter\noexpand\csname\@backslashchar\@expl@cs@to@str@@N#1\endcsname + \unexpanded\expandafter\expandafter\expandafter + {\expandafter\@gobblethree#2}}% + \expandafter + \let\csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname + \csname\@backslashchar\@expl@cs@to@str@@N#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@show@newcommand} +% \begin{macro}{\@show@newcommand@aux} +% A command being \cs{show}n here is guaranteed to have an optional argument. +% Start by showing the top-level expansion of the command (using \cs{typeout} +% to avoid TeX asking for interaction and extra context lines), then call +% \cs{@show@newcommand@aux} with the internal command, which contains the +% actual definition, and with the expansion of the command to extract the +% default value of the optional argument. +% \begin{macrocode} +\long\def\@show@newcommand#1{% + \typeout{> \string#1=robust macro:}% + \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}% + \expandafter\@show@newcommand@aux + \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname + \expandafter{#1}} +% \end{macrocode} +% +% For a macro defined with, say, |\newcommand\foo[1][opt]{bar}|, it will +% print: +% \begin{verbatim} +% > \foo=robust macro: +% ->\@protected@testopt \foo \\foo {opt}. +% +% > \\foo=\long macro: +% > default #1=opt. +% [#1]->bar. +% \end{verbatim} +% If the command was defined with \cs{DeclareRobustCommand}, then another pair +% of lines show the top-level expansion \verb*|\protect \foo |. +% +% The extra gymnastics with \cs{showtokens} ensures that \cs{showtokens} +% itself, and the internals of this macro aren't showed in the context lines. +% \begin{macrocode} +\long\def\@show@newcommand@aux#1#2{% + \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:}% + \edef\reserved@a{% + default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% + \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}% + \showtokens\expandafter\expandafter\expandafter{\expandafter\reserved@a}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Now the rollback code. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\@if@DeclareRobustCommand} +%<latexrelease> {Undefine \@if@DeclareRobustCommand, \@if@newcommand, +%<latexrelease> \@copy@DeclareRobustCommand, \@copy@newcommand, +%<latexrelease> \@show@DeclareRobustCommand, \@show@newcommand}% +%<latexrelease>\let\@if@DeclareRobustCommand\@undefined +%<latexrelease>\let\@copy@DeclareRobustCommand\@undefined +%<latexrelease>\let\@show@DeclareRobustCommand\@undefined +%<latexrelease>\let\@if@newcommand\@undefined +%<latexrelease>\let\@copy@newcommand\@undefined +%<latexrelease>\let\@show@newcommand\@undefined +% +%<latexrelease>\let\copy@kernel@robust@command\@undefined +%<latexrelease>\let\show@kernel@robust@command\@undefined +%<latexrelease>\let\@show@newcommand@aux\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \end{macro} +% % % \subsection{Internal defining commands} % @@ -1586,7 +2217,7 @@ % \changes{v1.0g}{1994/04/12} % {Define \cs{@dischyph}, was previously in ltboxes.dtx} % \changes{v1.5b}{2017/03/27}{Define \cs{@dischyph} after \cs{-}} -% \changes{v1.5h}{2020/05/11}{Do not overwrite \cs{-} under Lua\TeX} +% \changes{v1.5j}{2020/05/11}{Do not overwrite \cs{-} under Lua\TeX} % \end{macro} % Moved here to be after the definition of |\DeclareRobustCommand|. % @@ -1726,6 +2357,28 @@ %<*2ekernel> % \end{macrocode} % +% +% \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{macrocode} %</2ekernel> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx b/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx index 25fb9480ddd..3abd49aced5 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltdirchk.dtx} - [2019/11/01 v1.3a LaTeX Kernel (System Dependent Parts)] + [2020/08/21 v1.3a LaTeX Kernel (System Dependent Parts)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdirchk.dtx} @@ -172,7 +172,9 @@ %, \LaTeX\ will not work around a bug in old \TeX\ versions, and % so error messages will appear in a very strange format, with |^^J| % appearing instead of line breaks: -% \begingroup\catcode`\==\active \def=#1#2{}\hfuzz\maxdimen +% \begingroup +% ^^A FMi next line doesn't work with hacked class +% ^^A\catcode`\==\active \def=#1#2{}\hfuzz\maxdimen %\begin{verbatim} %! LaTeX Error: \rubbish undefined.^^J^^JSee the LaTeX manual or LaTeX= % Companion diff --git a/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx index 7a567e378f3..16ca26095c1 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2020-07-08 v1.2d LaTeX Kernel (expl3-dependent code)] + [2020/08/21 v1.2e LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -41,6 +41,9 @@ \date{\filedate} \author{% Joseph Wright} + +\providecommand\pkg[1]{\texttt{#1}} + \begin{document} \MaintainedByLaTeXTeam{latex} \maketitle @@ -49,6 +52,9 @@ %</driver> % \fi % +% +% \changes{v1.2d}{2020/08/21}{Dropped unused command} +% % \section{\pkg{expl3}-dependent code} % % \StopEventually{} @@ -218,11 +224,6 @@ % % \subsection{Using expl3 code} % -% \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\@expl@tl@trim@spaces@apply@@nN} -%<latexrelease> {l3 macro for use in include}% -% \end{macrocode} % In order to ease the implemantation of some new features in % \LaTeXe\ we may (temporarily) use some coding based on the % \pkg{expl3}-code. @@ -232,25 +233,68 @@ % packages. These macros will always have the \verb|@expl@| % prefix in their name. % -% \changes{v1.2a}{2020/05/02} -% {Define a macro based on l3 language to support inclusion of -% files with space in the name (gh/217)} +% The rest of the name matches the \pkg{expl3} name but with all +% underscores replaced by \texttt{@}s and the \texttt{:} replaced +% by \texttt{@@}, e.g., +%\begin{verbatim} +% \cs_new_eq:NN \@expl@tl@trim@spaces@apply@@nN \tl_trim_spaces_apply:nN +%\end{verbatim} +% if that \pkg{expl3} command is needed in places that are others +% coded in \LaTeXe{} conventions. +% % \begin{macrocode} \ExplSyntaxOn -\cs_new_eq:NN \@expl@tl@trim@spaces@apply@@nN \tl_trim_spaces_apply:nN -\ExplSyntaxOff +% \end{macrocode} +% +% In this file, each release of LaTeX adds an \cs{IncludeInRelease} +% block, in which the macros copied for that release were defined. +% In case a rollback is requested, the entire block is changed. +% +% Each macro copied has a \cs{changes} entry to explain when and why +% it was copied, so that further to that may spot it easily. +% +% Here \cs{cs\string_gset\string_eq:NN} is used, instead of the |new| +% variant because if different releases use that same name for +% different purposes, each can copy the macro without worrying about +% redefinitions. +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{expl3~2020-10-01}% +%<latexrelease> {expl3~macros~added~for~the~2020-10-01~release}% +% \end{macrocode} +% +% \changes{v1.2e}{2020/08/19} +% {Add \cs{@expl@cs@to@str@@N} and \cs{@expl@str@if@eq@@nnTF} +% for \cs{NewCommandCopy} (gh/239)} +% \begin{macrocode} +\cs_gset_eq:NN \@expl@cs@to@str@@N \cs_to_str:N +\cs_gset_eq:NN \@expl@str@if@eq@@nnTF \str_if_eq:nnTF +% \end{macrocode} +% +% \changes{v1.2e}{2020/08/19} +% {Add \cs{\@expl@cs@\meta{thing}@spec@@N} +% for \cs{ShowCommand} (gh/373)} +% \begin{macrocode} +\cs_gset_eq:NN \@expl@cs@prefix@spec@@N \cs_prefix_spec:N +\cs_gset_eq:NN \@expl@cs@argument@spec@@N \cs_argument_spec:N +\cs_gset_eq:NN \@expl@cs@replacement@spec@@N \cs_replacement_spec:N % \end{macrocode} % % \begin{macrocode} %<latexrelease>\EndIncludeInRelease -%<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\@expl@tl@trim@spaces@apply@@nN} -%<latexrelease> {l3 macro for use in include}% -%<latexrelease> -%<latexrelease>\let\@expl@tl@trim@spaces@apply@@nN\@undefined -%<latexrelease> +%<latexrelease>\IncludeInRelease{0000/00/00}{expl3~2020-10-01}% +%<latexrelease> {expl3~macros~added~for~the~2020-10-01~release}% +%<latexrelease>\cs_undefine:N \@expl@cs@to@str@@N +%<latexrelease>\cs_undefine:N \@expl@str@if@eq@@nnTF +%<latexrelease>\cs_undefine:N \@expl@cs@prefix@spec@@N +%<latexrelease>\cs_undefine:N \@expl@cs@argument@spec@@N +%<latexrelease>\cs_undefine:N \@expl@cs@replacement@spec@@N %<latexrelease>\EndIncludeInRelease %</2ekernel|latexrelease> % \end{macrocode} % +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% % \Finale diff --git a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx index 6c16a9832ea..73018c682d5 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx @@ -1,30 +1,42 @@ % \iffalse meta-comment +%% +%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, +%% Phelype Oleinik & LaTeX Team % -%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file +% This file is part of the LaTeX base system. +% ------------------------------------------- % +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in % https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". % +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. % -% The development version of the bundle can be found below +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi % -% https://github.com/FrankMittelbach/... +% \iffalse % -% for those people who are interested or want to report an issue. +%%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v0.9a} -\providecommand\ltfilehookdate{2020/07/19} +\providecommand\ltfilehookversion{v1.0a} +\providecommand\ltfilehookdate{2020/08/30} % \end{macrocode} % %<*driver> -\RequirePackage{lthooks} % needed for structedlog if running old format - \documentclass{l3doc} % bug fix fo l3doc.cls @@ -107,7 +119,7 @@ % \item[\texttt{file/before}, \texttt{file/before/\meta{file-name}}] % % These hooks are executed in that order just before the file is -% loaded for reading. The code of the first hook is used is used +% loaded for reading. The code of the first hook is used % with every file, while the second is executed only for the % file with matching \meta{file-name} allowing you to specify % code that only applies to one file. @@ -119,8 +131,8 @@ % comes first) so that the \texttt{before} and \texttt{after} % hooks nest properly, which is important if any of them involve % grouping (e.g., contain environments, for example). -% furthermore both hooks are reversed hooks to support correct -% nesting of different packages add code to both +% Furthermore both hooks are reversed hooks to support correct +% nesting of different packages adding code to both % \texttt{/before} and \texttt{/after} hooks. % % \end{description} @@ -139,16 +151,13 @@ % \>\cs{UseHook}\marg{\hook{file/after}} % \end{tabbing} % -% \fmi{With a higher-level interface that doesn't matter, but it -% is a bit weird, if you use \cs{AddToHook} or \cs{hook_gput:nnn} -% directly, so I guess that has to be done differently!} -% % The file hooks only refer to the file by its name and extension, % so the \meta{file name} should be the file name as it is on the % filesystem with extension (if any) and without paths. Different -% from \cs{input} and similar commands, for hooks the \texttt{.tex} -% extension is not assumed, so \texttt{.tex} files must also be given -% with their extension. +% from \cs{input} and similar commands, the \texttt{.tex} +% extension is not assumed in hook \meta{file name}, so \texttt{.tex} +% files must be specified +% with their extension to be recognized. % Files within subfolders should also be addressed by their name and % extension only. % @@ -185,6 +194,18 @@ % in these cases (package and class files, mostly). % \end{variable} % +% \begin{variable}{\CurrentFileUsed,\CurrentFilePathUsed} +% In normal circumstances these are identical to \cs{CurrentFile} and +% \cs{CurrentFilePath}. They will differ when a file substitution +% has occurred for \cs{CurrentFile}. In that case, +% \cs{CurrentFileUsed} and \cs{CurrentFilePathUsed} will hold the +% actual file name and path loaded by \LaTeX, while \cs{CurrentFile} +% and \cs{CurrentFilePath} will hold the names that were +% \emph{asked for}. Unless doing very specific work on the file +% being read, \cs{CurrentFile} and \cs{CurrentFilePath} should be +% enough. +% \end{variable} +% % \subsection{Hooks for package and class files} % % Commands to load package and class files (e.g., \cs{usepackage}, @@ -284,7 +305,7 @@ % % \item[\texttt{include/before}, \texttt{include/before/\meta{name}}] % -% These hooks are executed one after another after the initial +% These hooks are executed (in that order) after the initial % \cs{clearpage} and after \texttt{.aux} file is changed to use % \texttt{\meta{name}.aux}, but before the % \texttt{\meta{name}.tex} file is loaded. In other words they are executed @@ -322,6 +343,58 @@ % \pkg{filehook} or \pkg{scrlfile} do) but think that for package % writers the commands from for hook management are sufficient. % +% +% +% \subsection{Internal interfaces for \LaTeX{}} +% +% \begin{function}{\declare@file@substitution,\undeclare@file@substitution} +% \begin{syntax} +% \cs{declare@file@substitution} \Arg{file} \Arg{replacement-file} +% \cs{undeclare@file@substitution} \Arg{file} +% \end{syntax} +% If \meta{file} is requested for loading replace it with +% \meta{replacement-file}. \cs{CurrentFile} remains pointing to +% \meta{file} but \cs{CurrentFileUsed} will show the file actually +% loaded. +% +% The main use case for this declaration is to provide a corrected +% version of a package that can't be changed (due to its license) +% but no longer functions because of \LaTeX{} kernel changes, for +% example, or to provide a version that makes use of new kernel +% functionality while the original package remains available for +% use with older releases. +% +% The \cs{undeclare@file@substitution} declaration undoes a +% substitution made earlier. +% +% \begin{quote} +% \em +% Please do not misuse this functionality and replace a file with +% another unless if really needed and only if the new version is +% implementating the same functionality as the original one! +% \end{quote} +% \end{function} +% +% \begin{function}{\disable@package@load,\reenable@package@load} +% \begin{syntax} +% \cs{disable@package@load} \Arg{package} \Arg{alternate-code} +% \cs{reenable@package@load} \Arg{package} +% \end{syntax} +% If \meta{package} is requested do not load it but instead run +% \meta{alternate-code} which could issue a warning, error or any +% other code. +% +% The main use case is for classes that want to restrict the set of +% supported packages or contain code that make the use of some +% packages impossible. So rather than waiting until the document +% breaks they can set up informative messages why certain packages +% are not available. +% +% The function is only implemented for packages not for arbitrary +% files. +% \end{function} +% +% % \subsection{A sample package for structuring the log output} % % As an application we provide the package \pkg{structuredlog} that @@ -378,91 +451,176 @@ %<*2ekernel> % \end{macrocode} % -% \subsection{\pkg{expl3} helpers} -% % \begin{macrocode} %<@@=filehook> % \end{macrocode} % +% +% \subsection{Document and package-level commands} +% +% % \begin{macro}{\CurrentFile,\CurrentFilePath} +% \begin{macro}{\CurrentFileUsed,\CurrentFilePathUsed} % User-level macros that hold the current file name and file path. % These are used internally as well because the code takes care to -% protect against a possible redefinition of these macros in the loaded -% file (it's necessary anyway to make hooks work with nested -% \cs{input}). +% protect against a possible redefinition of these macros in the +% loaded file (it's necessary anyway to make hooks work with nested +% \cs{input}). The versions |\...Used| hold the \emph{actual} file +% name and path that is loaded by \LaTeX, whereas the other two hold +% the name as requested. They will differ in case there's a file +% substitution. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\CurrentFile}{Hook management file}% +\ExplSyntaxOn +\tl_new:N \CurrentFile +\tl_new:N \CurrentFilePath +\tl_new:N \CurrentFileUsed +\tl_new:N \CurrentFilePathUsed +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% % \begin{macrocode} -\def\CurrentFile{} -\def\CurrentFilePath{} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\CurrentFile}{Hook management file}% +%<latexrelease> +%<latexrelease>\let \CurrentFile \@undefined +%<latexrelease>\let \CurrentFilePath \@undefined +%<latexrelease>\let \CurrentFileUsed \@undefined +%<latexrelease>\let \CurrentFilePathUsed \@undefined +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} +% \end{macro} +% +% +% +% \subsection{\pkg{expl3} helpers} % -% \begin{macro}{\l_@@_internal_tl} -% \begin{macro}{\@filehook@set@curr@file,\@@_normalise_file_name:n} -% When inputting a file, \cs{@filehook@set@curr@file} does a file -% lookup (in \cs{input@path} and \cs{l_file_search_path_seq}) and -% returns the actual file name (\meta{base} plus \meta{ext}) in -% \cs{CurrentFile}. Only the base and extension are returned, -% regardless of the input (both \texttt{path/to/file.tex} and -% \texttt{file.tex} end up as \texttt{file.tex} in \cs{CurrentFile}). -% The path is returned in \cs{CurrentFilePath}, in case it's needed. -% \cs{CurrentFile} is then used to run the file hooks with -% \texttt{file/before/\cs{CurrentFile}} and -% \texttt{file/after/\cs{CurrentFile}}. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@@_file_parse_full_name:nN}{File helpers}% \ExplSyntaxOn -\tl_new:N \l_@@_internal_tl -\cs_new_protected:Npn \@filehook@set@curr@file #1 - { \exp_args:NV \@@_normalise_file_name:n #1 } -\cs_new_protected:Npn \@@_normalise_file_name:n #1 +% \end{macrocode} +% +% \begin{macro}{ +% \@@_file_parse_full_name:nN, +% \@@_full_name:nn, +% \@@_set_curr_file_assign:nnnNN +% } +% A utility macro to trigger \pkg{expl3}'s file-parsing and lookup, +% and return a normalized representation of the file name. If the +% queried file doesn't exist, no normalisation takes place. +% The output of \cs{@@_file_parse_full_name:nN} is passed on to the +% |#2|---a 3-argument macro that takes the \meta{path}, \meta{base}, +% and \meta{ext} parts of the file name. +% +% \begin{macrocode} +\cs_new:Npn \@@_file_parse_full_name:nN #1 { - \file_if_exist:nTF {#1} + \exp_args:Nf \file_parse_full_name_apply:nN { - \exp_args:Nx \file_parse_full_name:nNNN - { \file_full_name:n {#1} } + \exp_args:Nf \@@_full_name:nn + { \file_full_name:n {#1} } {#1} } - { \file_parse_full_name:nNNN {#1} } - \CurrentFilePath \CurrentFile \l_@@_internal_tl - \tl_set:Nx \CurrentFile { \CurrentFile \l_@@_internal_tl } + } +\cs_new:Npn \@@_full_name:nn #1 #2 + { + \tl_if_empty:nTF {#1} + { \tl_trim_spaces:n {#2} } + { \tl_trim_spaces:n {#1} } } % \end{macrocode} % \end{macro} +% +% \begin{macro}{ +% \@@_if_no_extension:nTF, +% \@@_drop_extension:N +% } +% Some actions depend on whether the file extension was explicitly +% given, and sometimes the extension has to be removed. The macros +% below use \cs{@@_file_parse_full_name:nN} to split up the file name +% and either check if \meta{ext} (|#3|) is empty, or discard it. +% \begin{macrocode} +\cs_new:Npn \@@_if_no_extension:nTF #1 + { + \exp_args:Ne \tl_if_empty:nTF + { \file_parse_full_name_apply:nN {#1} \use_iii:nnn } + } +\cs_new_protected:Npn \@@_drop_extension:N #1 + { + \tl_gset:Nx #1 + { + \exp_args:NV \@@_file_parse_full_name:nN #1 + \@@_drop_extension_aux:nnn + } + } +\cs_new:Npn \@@_drop_extension_aux:nnn #1 #2 #3 + { \tl_if_empty:nF {#1} { #1 / } #2 } +% \end{macrocode} % \end{macro} % -% \begin{macro}{\g_@@_input_file_seq} -% \begin{macro}{\@filehook@file@push,\@filehook@file@pop} -% \begin{macro}{\@@_file_pop_assign:nn} +% \begin{macro}{\g_@@_input_file_seq,\l_@@_internal_tl} +% \begin{macro}{\@@_file_push:,\@@_file_pop:} +% \begin{macro}{\@@_file_pop_assign:nnnn} % Yet another stack, to keep track of \cs{CurrentFile} and % \cs{CurrentFilePath} with nested \cs{input}s. At the beginning of % \cs{InputIfFileExists}, the current value of \cs{CurrentFilePath} % and \cs{CurrentFile} is pushed to \cs{g_@@_input_file_seq}, and -% at the end, it is popped and the value reassigned. -% \cs{IfFileExists} does \cs{set@curr@file} internally, which changes -% \cs{CurrentFile}, so \cs{@filehook@file@push} has to be executed -% before \cs{IfFileExists}. +% at the end, it is popped and the value reassigned. Some other +% places don't use \cs{InputIfFileExists} directly (\cs{include}) or +% need \cs{CurrentFile} earlier (\cs{@onefilewithoptions}), so these +% are manually used elsewhere as well. % \begin{macrocode} +\tl_new:N \l_@@_internal_tl \seq_new:N \g_@@_input_file_seq -\cs_new_protected:Npn \@filehook@file@push +\cs_new_protected:Npn \@@_file_push: { \seq_gpush:Nx \g_@@_input_file_seq - { { \CurrentFilePath } { \CurrentFile } } + { + { \CurrentFilePathUsed } { \CurrentFileUsed } + { \CurrentFilePath } { \CurrentFile } + } } -\cs_new_protected:Npn \@filehook@file@pop +\cs_new_protected:Npn \@@_file_pop: { \seq_gpop:NNTF \g_@@_input_file_seq \l_@@_internal_tl - { \exp_after:wN \@@_file_pop_assign:nn \l_@@_internal_tl } - { \ERROR_should_not_happen } + { \exp_after:wN \@@_file_pop_assign:nnnn \l_@@_internal_tl } + { + \msg_error:nnn { hooks } { should-not-happen } + { Tried~to~pop~from~an~empty~file~name~stack. } + } } -\cs_new_protected:Npn \@@_file_pop_assign:nn #1 #2 +\cs_new_protected:Npn \@@_file_pop_assign:nnnn #1 #2 #3 #4 { - \tl_set:Nn \CurrentFilePath {#1} - \tl_set:Nn \CurrentFile {#2} + \tl_set:Nn \CurrentFilePathUsed {#1} + \tl_set:Nn \CurrentFileUsed {#2} + \tl_set:Nn \CurrentFilePath {#3} + \tl_set:Nn \CurrentFile {#4} } \ExplSyntaxOff % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} % +% \begin{macrocode} +%<@@=> +% \end{macrocode} % % \subsection{Declaring the file-related hooks} % @@ -475,13 +633,14 @@ % automatically declared as reversed hooks if filled with code, so this % is also automatically taken care of. % -% \subsection{Patching \LaTeX{} commands (need proper integration later)} % -% Most of what we have to do is adding \cs{UseHook} into several -% \LaTeXe{} core commands, which is done for now by patching them. -% \begin{macrocode} -%<@@=> -% \end{macrocode} +% +% +% \subsection{Patching \LaTeX{}'s \cs{InputIfFileExists} command} +% +% Most of what we have to do is adding \cs{UseHook} into several +% \LaTeXe{} core commands, because of some circular dependencies in the +% kernel we do this only now and not in \texttt{ltfiles}. % % \begin{macro}{\InputIfFileExists} % \cs{InputIfFileExists} loads any file if it is available so we @@ -489,21 +648,34 @@ % \texttt{file/after} in the right places. If the file doesn't % exist no hooks should be executed. % \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\InputIfFileExists}{Hook management (files)}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} \let\InputIfFileExists\@undefined -\DeclareRobustCommand \InputIfFileExists[3]{% - \@filehook@file@push +\DeclareRobustCommand \InputIfFileExists[2]{% \IfFileExists{#1}% {% + \@expl@@@filehook@file@push@@ + \@filehook@set@CurrentFile % \end{macrocode} -% If the file exists then \cs{@curr@file} holds its name. But we +% If the file exists then \cs{CurrentFile} holds its name. But we % can't rely on that still being true after the file has been % processed. Thus for using the name in the file hooks we need to % preserve the name and then restored it for the % \texttt{file/after/...} hook. % -% The hook always refers to the \emph{actual} file that will be -% operated on, regardless of how the user had it written in the -% document. \pkg{expl3}'s \cs{file_full_name:n} normalizes the file +% The hook always refers to the file requested by the user. The hook +% is \emph{always} loaded for \cs{CurrentFile} which usually is the +% same as \cs{CurrentFileUsed}. In the case of a file replacement, +% the \cs{CurrentFileUsed} holds the actual file loaded. In any case +% the file names are normalized so that the hooks work on the real +% file name, rather than what the user typed in. +% +% \pkg{expl3}'s \cs{file_full_name:n} normalizes the file % name (to factor out differences in the |.tex| extension), and % then does a file lookup to take into account a possible path from % \cs{l_file_search_path_seq} and \cs{input@path}. However only @@ -512,9 +684,11 @@ % returned in \cs{CurrentFilePath}. % \begin{macrocode} \edef\reserved@a{\@filef@und - \def\noexpand\CurrentFile{\CurrentFile}% - \def\noexpand\CurrentFilePath{\CurrentFilePath}% - }% + \@expl@@@filehook@file@pop@assign@@nnnn + {\CurrentFilePathUsed}% + {\CurrentFileUsed}% + {\CurrentFilePath}% + {\CurrentFile}}% \expandafter\@swaptwoargs\expandafter {\reserved@a}% {% @@ -522,7 +696,7 @@ \@addtofilelist{#1}% \UseHook{file/before}% % \end{macrocode} -% The current file name is available in \cs{@curr@file} so we use +% The current file name is available in \cs{CurrentFile} so we use % that in the specific hook. % \begin{macrocode} \UseHook{file/before/\CurrentFile}% @@ -533,356 +707,592 @@ % \begin{macrocode} \UseHook{file/after/\CurrentFile}% \UseHook{file/after}% - \@filehook@file@pop + \@expl@@@filehook@file@pop@@ }% - {\@filehook@file@pop #3}% } +%<latexrelease>\EndIncludeInRelease +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \changes{v0.9b} +% {1993/12/04}{Macro added} +% \changes{v0.9p} +% {1994/01/18}{New Definition} +% \changes{v0.3b}{1994/03/13} +% {Use new cmd \cs{@addtofilelist}} +% Now define |\InputIfFileExists| to input |#1| if it seems to exist. +% Immediately prior to the input, |#2| is executed. +% If the file |#1| does not exist, execute `|#3|'. +% \changes{v1.0t}{1995/05/25} +% {(CAR) added \cs{long}} +% \changes{v1.1o}{2019/02/07}{Expand \cs{@filef@und} before executing +% second argument (github/109)} +% \changes{v1.2b}{2019/08/27}{Make command robust} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\InputIfFileExists}{Hook management (files)}% +%<latexrelease> +%<latexrelease>\DeclareRobustCommand \InputIfFileExists[2]{% +%<latexrelease> \IfFileExists{#1}% +%<latexrelease> {% +%<latexrelease> \expandafter\@swaptwoargs\expandafter +%<latexrelease> {\@filef@und}{#2\@addtofilelist{#1}\@@input}}} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\InputIfFileExists}{Hook management (files)}% +%<latexrelease>\long\def \InputIfFileExists#1#2{% +%<latexrelease> \IfFileExists{#1}% +%<latexrelease> {#2\@addtofilelist{#1}\@@input \@filef@und}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsection{Declaring a file substitution} +% +% \begin{macrocode} +%<@@=filehook> +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@@_subst_add:nn}{Declaring file substitution}% +\ExplSyntaxOn +% \end{macrocode} +% +% +% \begin{macro}{\@@_subst_add:nn,\@@_subst_remove:n, +% \@@_subst_file_normalize:n,\@@_subst_empty_name_chk:NN} +% \cs{@@_substitution_lthooadd:nn} declares a file substitution by +% doing a (global) definition of the form +% |\def|\cs{@file-subst@\meta{file}}|{|\meta{replacement}|}|. +% The file names are properly sanitised, and normalized with the same +% treatment done for the file hooks. That is, a file replacement is +% declared by using the file name (and extension, if any) only, and +% the file path should not be given. If a file name is empty it is +% replaced by |.tex| (the empty csname is used to check that). +% \begin{macrocode} +\cs_new_protected:Npn \@@_subst_add:nn #1 #2 + { + \group_begin: + \cs_set:cpx { } { \exp_not:o { \cs:w\cs_end: } } + \int_set:Nn \tex_escapechar:D { -1 } + \cs_gset:cpx { @file-subst@ \@@_subst_file_normalize:n {#1} } + { \@@_subst_file_normalize:n {#2} } + \group_end: + } +\cs_new_protected:Npn \@@_subst_remove:n #1 + { + \group_begin: + \cs_set:cpx { } { \exp_not:o { \cs:w\cs_end: } } + \int_set:Nn \tex_escapechar:D { -1 } + \cs_undefine:c { @file-subst@ \@@_subst_file_normalize:n {#1} } + \group_end: + } +\cs_new:Npn \@@_subst_file_normalize:n #1 + { + \exp_after:wN \@@_subst_empty_name_chk:NN + \cs:w \exp_after:wN \cs_end: + \cs:w \@@_file_parse_full_name:nN {#1} \use_ii_iii:nnn \cs_end: + } +\cs_new:Npn \@@_subst_empty_name_chk:NN #1 #2 + { \if_meaning:w #1 #2 .tex \else: \token_to_str:N #2 \fi: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\use_ii_iii:nnn} +% A variant of \cs[no-index]{use_...} to discard the first of three +% arguments. +% \fmi{this should move to \pkg{expl3}} +% \begin{macrocode} +\cs_gset:Npn \use_ii_iii:nnn #1 #2 #3 {#2 #3} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} +% +% +% +% \begin{macro}{\declare@file@substitution} +% \begin{macro}{\undeclare@file@substitution} +% For two internals we provide \LaTeXe{} names so that we can use +% them elsewhere in the kernel (and so that they can be used in +% packages if really needed, e.g., \pkg{scrlfile}). +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\declare@file@substitution}{File substitution}% +\ExplSyntaxOn +\cs_new_eq:NN \declare@file@substitution \@@_subst_add:nn +\cs_new_eq:NN \undeclare@file@substitution \@@_subst_remove:n +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\declare@file@substitution}{File substitution}% +%<latexrelease> +%<latexrelease>\let \declare@file@substitution \@undefined +%<latexrelease>\let \undeclare@file@substitution \@undefined +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} % \end{macro} % -% \begin{macro}{\set@curr@file} -% Now we just hook into \cs{set@curr@file} to add -% \cs{@filehook@set@curr@file} at the end, after \cs{@curr@file} is -% set. +% +% +% % \begin{macrocode} +%<@@=> +\ExplSyntaxOff +% \end{macrocode} +% +% \subsection{Selecting a file (\cs{set@curr@file})} +% +% \begin{macro}{\set@curr@file,\@curr@file,\@curr@file@reqd} +% Now we hook into \cs{set@curr@file} to resolve a possible file +% substitution, and add \cs{@expl@@@filehook@set@curr@file@@N} at the end, after +% \cs{@curr@file} is set. +% +% A file name is built using +% \cs{expandafter}\cs{string}\cs{csname}\meta{filename}\cs{endcsname} +% to avoid expanding utf8 active characters. The \cs{csname} expands +% the normalisation machinery and the routine to resolve a file +% substitution, returning a control sequence with the same name as the +% file. +% +% It happens that when \meta{filename} is empty, the generated control +% sequence is \cs{csname\cs{endcsname}}, and doing \cs{string} on +% that results in the file |csnameendcsname.tex|. To guard against +% that we \cs{ifx}-compare the generated control sequence with the +% empty csname. To do so, \cs{csname\cs{endcsname}} has to be +% defined, otherwise it would be equal to \cs{relax} and we would have +% false positives. Here we define \cs{csname\cs{endcsname}} to +% expand to itself to avoid it matching the definition of some other +% control sequence. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\set@curr@file}{Setting current file name}% \def\set@curr@file#1{% \begingroup \escapechar\m@ne - \xdef\@curr@file{% - \expandafter\expandafter\expandafter\unquote@name - \expandafter\expandafter\expandafter{% - \expandafter\string - \csname\@firstofone#1\@empty\endcsname}}% - \endgroup - \@filehook@set@curr@file{\@curr@file}% -} + \expandafter\def\csname\expandafter\endcsname + \expandafter{\csname\endcsname}% % \end{macrocode} -% \end{macro} +% Two file names are set here: \cs{@curr@file@reqd} which is the file +% requested by the user, and \cs{@curr@file} which should be the same, +% except when we have a file substitution, in which case it holds the +% actual loaded file. \cs{@curr@file} is resolved first, to check if +% a substitution happens. If it doesn't, +% \cs{@expl@@@filehook@if@file@replaced@@TF} short-cuts and just copies +% \cs{@curr@file}, otherwise the full normalisation procedure is +% executed. +% +% At this stage the file name is parsed and normalized, but if the +% input doesn't have an extension, the default |.tex| is \emph{not} +% added to \cs{@curr@file} because for applications other than +% \cs{input} (graphics, for example) the default extension may not +% be |.tex|. First check if the input has an extension, then if the +% input had no extension, call \cs{@expl@@@filehook@drop@extension@@N}. In case +% of a file substitution, \cs{@curr@file} will have an extension. +% \begin{macrocode} + \@expl@@@filehook@if@no@extension@@nTF{#1}% + {\@tempswatrue}{\@tempswafalse}% + \@kernel@make@file@csname\@curr@file + \@expl@@@filehook@resolve@file@subst@@w {#1}% + \@expl@@@filehook@if@file@replaced@@TF + {\@kernel@make@file@csname\@curr@file@reqd + \@expl@@@filehook@normalize@file@name@@w{#1}% + \if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file@reqd \fi}% + {\if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file \fi + \global\let\@curr@file@reqd\@curr@file}% + \endgroup} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\set@curr@file}{Setting current file name}% +%<latexrelease>\def\set@curr@file#1{% +%<latexrelease> \begingroup +%<latexrelease> \escapechar\m@ne +%<latexrelease> \xdef\@curr@file{% +%<latexrelease> \expandafter\expandafter\expandafter\unquote@name +%<latexrelease> \expandafter\expandafter\expandafter{% +%<latexrelease> \expandafter\string +%<latexrelease> \csname\@firstofone#1\@empty\endcsname}}% +%<latexrelease> \endgroup +%<latexrelease>} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\set@curr@file}{Setting current file name}% +%<latexrelease>\let\set@curr@file\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\load@onefilewithoptions} -% This macro is used when loading packages or classes. -% \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 <return> \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}% - {% -%----------------------------------------- -% \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} -% The value of \cs{CurrentFile} holds during \cs{InputIfFileExists}, -% so the hooks above have that available for using. However at this -% point \cs{CurrentFile} is reset to its previous value by -% \cs{@filehook@file@pop} because it doesn't know that we'll have -% more hooks ahead. So here (still in the \meta{true} branch of -% \cs{InputIfFileExists}, right after actually reading the file in) -% we'll cheat: use \cs{@filehook@file@push} once more, so there are -% two entries for the current file in the name stack, so that when -% \cs{InputIfFileExists} pops it, there's still one (identical) left. -% \begin{macrocode} - \@filehook@file@push -%----------------------------------------- - }% - {\@missingfileerror\@currname\@currext}% - \let\@unprocessedoptions\@@unprocessedoptions - \csname\@currname.\@currext-h@@k\endcsname - \expandafter\let\csname\@currname.\@currext-h@@k\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 -% \end{macrocode} -% Now here we do \cs{@filehook@file@pop} to restore the -% \cs{CurrentFile} before this file being loaded and fix what we've -% done in the stack right above. -% \begin{macrocode} - \@filehook@file@pop -%----------------------------------------- - \@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} -% \end{macrocode} -% -% The code for this macro has changed between 2020/02/02 and -% 2020/10/01 so the never version is this: -% \begin{macrocode} -\@ifl@t@r\fmtversion{2020/10/01} -{% -\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 <return> \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}% - {% -%----------------------------------------- - \ifx\@currext\@pkgextension - \UseHook{package/before}% - \UseHook{package/before/\@currname}% - \else - \ifx\@currext\@clsextension - \UseHook{class/before}% - \UseHook{class/before/\@currname}% - \fi - \fi - \@filehook@file@push -%----------------------------------------- - }% - {\@missingfileerror\@currname\@currext}% - \expandafter\let\csname unprocessedoptions-\@currname.\@currext\endcsname - \@@unprocessedoptions - \csname\@currname.\@currext-h@@k\endcsname - \expandafter\let\csname\@currname.\@currext-h@@k\endcsname - \@undefined - \ifx\@unprocessedoptions\relax - \let\@unprocessedoptions\@undefined - \else - \csname unprocessedoptions-\@currname.\@currext\endcsname - \fi - \expandafter\let - \csname unprocessedoptions-\@currname.\@currext\endcsname - \@undefined -%----------------------------------------- - \ifx\@currext\@pkgextension - \UseHook{package/after/\@currname}% - \UseHook{package/after}% - \else - \ifx\@currext\@clsextension - \UseHook{class/after/\@currname}% - \UseHook{class/after}% - \fi - \fi - \@filehook@file@pop -%----------------------------------------- - }% - \@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} -}{}% +% +% +% +% \begin{macro}{\@filehook@set@CurrentFile} +% \begin{macro}{\@kernel@make@file@csname,\@set@curr@file@aux} +% +% \fmi{This should get internalized using \texttt{@expl@} names} +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@kernel@make@file@csname}{Make file csname}% % \end{macrocode} -% \end{macro} - - - - -% \begin{macro}{\@include} -% \begin{macrocode} -\def\@include#1 {% - \clearpage - \if@filesw - \immediate\write\@mainaux{\string\@input{#1.aux}}% - \fi - \@tempswatrue - \if@partsw - \@tempswafalse - \edef\reserved@b{#1}% - \@for\reserved@a:=\@partlist\do - {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% - \fi - \if@tempswa - \let\@auxout\@partaux - \if@filesw - \immediate\openout\@partaux #1.aux - \immediate\write\@partaux{\relax}% - \fi -%----------------------------------------- -% \end{macrocode} -% First we need to fix \cs{CurrentFile}, because due the pesky -% space-delimited \cs{@include}, \cs{CurrentFile} contains the -% \cs{include}'d file with a space. To fix that, we re-do -% \cs{set@curr@file}. The 2020/10/01 release doesn't need this as -% \cs{include} was changed to do \cs{set@curr@file} on the correct -% file name, rather than one with a trailing space. -% \begin{macrocode} - \set@curr@file{#1}% -% \end{macrocode} -% Execute the \texttt{before} hooks just after we switched the -% \texttt{.aux} file \ldots -% \begin{macrocode} - \UseHook{include/before}% - \UseHook{include/before/#1}% -%----------------------------------------- - \@input@{#1.tex}% -% \end{macrocode} -% \ldots{} then \texttt{end} hooks \ldots -% \begin{macrocode} -%----------------------------------------- - \UseHook{include/end/#1}% - \UseHook{include/end}% -%----------------------------------------- - \clearpage -% \end{macrocode} -% \ldots{} and after the \cs{clearpage} the \texttt{after} hooks -% followed by another \cs{clearpage} just in case new material got -% added (after all we need to be in well defined state after the -% \cs{include}). -% \begin{macrocode} -%----------------------------------------- - \UseHook{include/after/#1}% - \UseHook{include/after}% -% \end{macrocode} -% The additional \cs{clearpage} is needed to ensure that switching -% the \texttt{.aux} files happen at a defined point even if the -% above hooks add further material. -% \begin{macrocode} - \clearpage -%----------------------------------------- - \@writeckpt{#1}% - \if@filesw - \immediate\closeout\@partaux - \fi +% +% \begin{macrocode} +\def\@kernel@make@file@csname#1#2#3{% + \xdef#1{\expandafter\@set@curr@file@aux + \csname\expandafter#2\@firstofone#3\@nil\endcsname}} +% \end{macrocode} +% This auxiliary compares \cs{\meta{filename}} with +% \cs{csname\cs{endcsname}} to check if the empty |.tex| file was +% requested. +% \begin{macrocode} +\def\@set@curr@file@aux#1{% + \expandafter\ifx\csname\endcsname#1% + .tex\else\string#1\fi} +% \end{macrocode} +% +% Then we call \cs{@expl@@@filehook@set@curr@file@@N} once for \cs{@curr@file} +% to set \cs[no-index]{CurrentFile(Path)Used} and once for +% \cs{@curr@file@reqd} to set \cs[no-index]{CurrentFile(Path)}. +% Here too the slower route is only used if a substitution happened, +% but here \cs{@expl@@@filehook@if@file@replaced@@TF} can't be used because the +% flag is reset at the \cs{endgroup} above, so we check if +% \cs{@curr@file} and \cs{@curr@file@reqd} differ. This macro is +% issued separate from \cs{set@curr@file} because it changes +% \cs{CurrentFile}, and side-effects would quickly get out of control. +% \begin{macrocode} +\def\@filehook@set@CurrentFile{% + \@expl@@@filehook@set@curr@file@@N{\@curr@file}% + \CurrentFileUsed\CurrentFilePathUsed + \ifx\@curr@file@reqd\@curr@file + \let\CurrentFile\CurrentFileUsed + \let\CurrentFilePath\CurrentFilePathUsed \else - \deadcycles\z@ - \@nameuse{cp@#1}% - \fi - \let\@auxout\@mainaux -} + \@expl@@@filehook@set@curr@file@@N{\@curr@file@reqd}% + \CurrentFile\CurrentFilePath + \fi} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} +% \end{macro} +% \end{macro} % -% The code for this macro has changed between 2020/02/02 and -% 2020/10/01 so the never version is this: -% \begin{macrocode} -\@ifl@t@r\fmtversion{2020/10/01} -{% -\def\@include#1 {% - \clearpage - \if@filesw - \immediate\write\@mainaux{\string\@input{"#1.aux"}}% - \fi - \@tempswatrue - \if@partsw - \@tempswafalse - \edef\reserved@b{#1}% - \@for\reserved@a:=\@partlist\do - {\ifx\reserved@a\reserved@b\@tempswatrue\fi}% - \fi - \if@tempswa - \let\@auxout\@partaux - \if@filesw - \immediate\openout\@partaux "#1.aux" - \immediate\write\@partaux{\relax}% - \fi -%----------------------------------------- - \UseHook{include/before}% - \UseHook{include/before/#1}% -%----------------------------------------- - \@input@{#1.tex}% -%----------------------------------------- - \UseHook{include/end/#1}% - \UseHook{include/end}% -%----------------------------------------- - \clearpage -%----------------------------------------- - \UseHook{include/after/#1}% - \UseHook{include/after}% - \clearpage -%----------------------------------------- - \@writeckpt{#1}% - \if@filesw - \immediate\closeout\@partaux - \fi - \else - \deadcycles\z@ - \@nameuse{cp@#1}% - \fi - \let\@auxout\@mainaux} -}{} +% +% +% \begin{macro}{\@@_set_curr_file:N, +% \@@_set_curr_file:nNN, +% \@@_set_curr_file_assign:nnnNN} +% When inputting a file, \cs{set@curr@file} does a file lookup +% (in \cs{input@path} and \cs{l_file_search_path_seq}) and returns the +% actual file name (\meta{base} plus \meta{ext}) in +% \cs{CurrentFileUsed}, and in case there's a file substitution, the +% requested file in \cs{CurrentFile} (otherwise both are the same). +% Only the base and extension are returned, +% regardless of the input (both \texttt{path/to/file.tex} and +% \texttt{file.tex} end up as \texttt{file.tex} in \cs{CurrentFile}). +% The path is returned in \cs{CurrentFilePath}, in case it's needed. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {@@_set_curr_file:N}{Set curr file}% +\ExplSyntaxOn +%<@@=filehook> +\cs_new_protected:Npn \@@_set_curr_file:N #1 + { \exp_args:NV \@@_set_curr_file:nNN #1 } % \end{macrocode} -% \end{macro} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_curr_file:nNN #1 + { + \@@_file_parse_full_name:nN {#1} + \@@_set_curr_file_assign:nnnNN + } +\cs_new_protected:Npn \@@_set_curr_file_assign:nnnNN #1 #2 #3 #4 #5 + { + \str_set:Nn #5 {#1} + \str_set:Nn #4 {#2#3} + } +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Replacing a file and detecting loops} +% +% \begin{macro}{\@@_resolve_file_subst:w} +% \begin{macro}{\@@_normalize_file_name:w} +% \begin{macro}{\@@_file_name_compose:nnn} +% Start by sanitising the file with \cs{@@_file_parse_full_name:nN} +% then do \cs{@@_file_subst_begin:nnn}\Arg{path}\Arg{name}\Arg{ext}. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@@_resolve_file_subst:w}{Replace files detect loops}% +\ExplSyntaxOn +\cs_new:Npn \@@_resolve_file_subst:w #1 \@nil + { \@@_file_parse_full_name:nN {#1} \@@_file_subst_begin:nnn } +\cs_new:Npn \@@_normalize_file_name:w #1 \@nil + { \@@_file_parse_full_name:nN {#1} \@@_file_name_compose:nnn } +\cs_new:Npn \@@_file_name_compose:nnn #1 #2 #3 + { \tl_if_empty:nF {#1} { #1 / } #2#3 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{flag @@_file_replaced} +% \begin{macro}{\@@_if_file_replaced:TF} +% Since the file replacement is done expandably in a \cs{csname}, use +% a flag to remember if a substitution happened. We use this in +% \cs{set@curr@file} to short-circuit some of it in case no +% substitution happened (by far the most common case, so it's worth +% optimising). +% \begin{macrocode} +\flag_new:n { @@_file_replaced } +\cs_new:Npn \@@_if_file_replaced:TF #1 #2 + { \flag_if_raised:nTF { @@_file_replaced } {#1} {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_file_subst_begin:nnn} +% First off, start by checking if the current file ($\meta{name} + +% \meta{ext}$) has a declared substitution. If not, then just put +% that as the name (including a possible \meta{path} in this case): +% this is the default case with no substitutions, so it's the first to +% be checked. The auxiliary \cs{@@_file_subst_tortoise_hare:nn} sees +% that there's no replacement for |#2#3| and does nothing else. +% \begin{macrocode} +\cs_new:Npn \@@_file_subst_begin:nnn #1 #2 #3 + { + \@@_file_subst_tortoise_hare:nn { #2#3 } { #2#3 } + { \@@_file_name_compose:nnn {#1} {#2} {#3} } + } +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsubsection{The Tortoise and Hare algorithm} +% +% \begin{macro}{\@@_file_subst_tortoise_hare:nn} +% \begin{macro}{\@@_file_subst_loop:NN,\@@_file_subst_loop:cc} +% If there is a substitution (\meta{true} in the first +% \cs{cs_if_exist:cTF} below), then first check if there is no +% substitution down the line: this should be the second most common +% case, of one file replaced by another. In that case just leave the +% substitution there and the job is done. If any substitution +% happens, then the \cs{flag @@_file_replaced} is raised +% (conditionally, because checking if a flag is raised is much faster +% than raising it over and over again). +% +% If, however there are more substitutions, then we need to check for +% a possible loop in the substitutions, which would otherwise put +% \TeX{} in an infinite loop if just an exhaustive expansion was used. +% +% To detect a loop, the \emph{Tortoise and Hare} algorithm is used. +% The name of the algorithm is an analogy to Aesop's fable, in which +% the Hare outruns a Tortoise. The two pointers here are the csnames +% which contains each file replacement, both of which start at the +% position zero, which is the file requested. In the inner part of +% the macro below, \cs{@@_file_subst_loop:cc} is called with +% \cs[no-index]{@file-subst@\meta{file}} and +% \cs[no-index]{@file-subst@\cs[no-index]{@file-subst@\meta{file}}}; +% that is, the substitution of \meta{file} and the substution of that +% substution: the Tortoise walks one step while the Hare walks two. +% +% Within \cs{@@_file_subst_loop:NN} the two substitutions are +% compared, and if they lead to the same file it means that there is +% a loop in the substitutions. If there's no loop, +% \cs{@@_file_subst_tortoise_hare:nn} is called again with the +% Tortoise at position~1 and the hare at~2. Again, the substitutions +% are checked ahead of the Hare pointer to check that it won't run too +% far; in case there is no loop in the declarations, eventually one +% of the \cs{cs_if_exist:cTF} below will go \meta{false} and the +% algorithm will end; otherwise it will run until the Hare reaches +% the same spot as the tortoise and a loop is detected. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@@_file_subst_tortoise_hare:nn}{Tortoise and Hare}% +\ExplSyntaxOn +\cs_new:Npn \@@_file_subst_tortoise_hare:nn #1 #2 #3 + { + \cs_if_exist:cTF { @file-subst@ #2 } + { + \flag_if_raised:nF { @@_file_replaced } + { \flag_raise:n { @@_file_replaced } } + \cs_if_exist:cTF { @file-subst@ \use:c { @file-subst@ #2 } } + { + \@@_file_subst_loop:cc + { @file-subst@ #1 } + { @file-subst@ \use:c { @file-subst@ #2 } } + } + { \use:c { @file-subst@ #2 } } + } + { #3 } + } +% \end{macrocode} +% This is just an auxiliary to check if a loop was found, and continue +% the algorithm otherwise. If a loop is found, the |.tex| file is +% used as fallback and \cs{@@_file_subst_cycle_error:cN} is called to +% report the error. +% \begin{macrocode} +\cs_new:Npn \@@_file_subst_loop:NN #1 #2 + { + \token_if_eq_meaning:NNTF #1 #2 + { + .tex + \@@_file_subst_cycle_error:cN { @file-subst@ #1 } #1 + } + { \@@_file_subst_tortoise_hare:nn {#1} {#2} {#2} } + } +\cs_generate_variant:Nn \@@_file_subst_loop:NN { cc } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{ +% \@@_file_subst_cycle_error:NN, +% \@@_file_subst_cycle_error:cN, +% } +% Showing this type of error expandably is tricky, as we have a very +% limited amount of characters to show and a potentially large list. +% As a work around, several errors are printed, each showing one step +% of the loop, until all the error messages combined show the loop. +% \begin{macrocode} +\cs_new:Npn \@@_file_subst_cycle_error:NN #1 #2 + { + \__kernel_msg_expandable_error:nnff { kernel } { file-cycle } + {#1} { \use:c { @file-subst@ #1 } } + \token_if_eq_meaning:NNF #1 #2 + { \@@_file_subst_cycle_error:cN { @file-subst@ #1 } #2 } + } +\cs_generate_variant:Nn \@@_file_subst_cycle_error:NN { c } +% \end{macrocode} +% +% And the error message: +% \begin{macrocode} +\__kernel_msg_new:nnn { kernel } { file-cycle } + { File~loop!~#1~replaced~by~#2... } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% +% \subsection{Preventing a package from loading} +% +% We support the use case of preventing a package from loading but not +% any other type of files (e.g., classes). +% +% \begin{macro}{\disable@package@load} +% \begin{macro}{\reenable@package@load} +% \begin{macro}{\@disable@packageload@do} +% \cs{disable@package@load} defines +% \cs[no-index]{@pkg-disable@\meta{package}} to expand to some code |#2| +% instead of loading the package. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\disable@package@load}{Disable packages}% +\def\disable@package@load#1#2{% + \global\@namedef{@pkg-disable@#1.\@pkgextension}{#2}} +% \end{macrocode} +% +% \begin{macrocode} +\def\@disable@packageload@do#1#2{% + \@ifundefined{@pkg-disable@#1}{#2}% + {\@nameuse{@pkg-disable@#1}}} +% \end{macrocode} +% +% \cs{reenable@package@load} undefines +% \cs[no-index]{@pkg-disable@\meta{package}} to reallow loading a package. +% \begin{macrocode} +\def\reenable@package@load#1{% + \global\expandafter\let + \csname @pkg-disable@#1.\@pkgextension \endcsname \@undefined} +% \end{macrocode} +% +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\disable@package@load}{Disable packages}% +%<latexrelease> +%<latexrelease>\let\disable@package@load \@undefined +%<latexrelease>\let\@disable@packageload@do\@undefined +%<latexrelease>\let\reenable@package@load \@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% % % % @@ -895,13 +1305,231 @@ % % % +% \subsection{Internal commands needed elsewhere} +% +% Here we set up a few horrible (but consistent) \LaTeXe{} names to +% allow for internal commands to be used outside this module (and +% in parts that still use \LaTeXe{} syntax. We have to unset the +% \texttt{@\/@} since we want double ``at'' sign in place of double +% underscores. +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@expl@@@filehook@if@no@extension@@nTF}{2e tmp interfaces}% +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@if@no@extension@@nTF + \__filehook_if_no_extension:nTF +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@set@curr@file@@N + \__filehook_set_curr_file:N +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@resolve@file@subst@@w + \__filehook_resolve_file_subst:w +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@normalize@file@name@@w + \__filehook_normalize_file_name:w +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@if@file@replaced@@TF + \__filehook_if_file_replaced:TF + +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@drop@extension@@N + \__filehook_drop_extension:N +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@file@push@@ + \__filehook_file_push: +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@file@pop@@ + \__filehook_file_pop: +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@expl@@@filehook@file@pop@assign@@nnnn + \__filehook_file_pop_assign:nnnn +% \end{macrocode} +% +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% This ends the kernel code in this file. % \begin{macrocode} %</2ekernel> % \end{macrocode} % % % -% \section{Package emulation for compatibility} +% \section{A sample package for structuring the log output} +% +% \begin{macrocode} +%<*structuredlog> +%<@@=filehook> +% \end{macrocode} +% +% \begin{macrocode} +\ProvidesExplPackage + {structuredlog}{\ltfilehookdate}{\ltfilehookversion} + {Structuring the TeX transcript file} +% \end{macrocode} +% +% \begin{macro}{\g_@@_nesting_level_int} +% Stores the current package nesting level. +% \begin{macrocode} +\int_new:N \g_@@_nesting_level_int +% \end{macrocode} +% Initialise the counter with the number of files in the +% \cs{@currnamestack} (the number of items divided by $3$) minus one, +% because this package is skipped when printing to the log. +% \begin{macrocode} +\int_gset:Nn \g_@@_nesting_level_int + { ( \tl_count:N \@currnamestack ) / 3 - 1 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_log_file_record:n} +% This macro is responsible for increasing and decresing the file +% nesting level, as well as printing to the log. The argument is +% either |STOPTART| or |STOP| and the action it takes on the nesting +% integer depends on that. +% \begin{macrocode} +\cs_new_protected:Npn \@@_log_file_record:n #1 + { + \str_if_eq:nnT {#1} {START} { \int_gincr:N \g_@@_nesting_level_int } + \iow_term:x + { + \prg_replicate:nn { \g_@@_nesting_level_int } { = } ~ + ( LEVEL ~ \int_use:N \g_@@_nesting_level_int \c_space_tl #1 ) ~ + \CurrentFileUsed +% \end{macrocode} +% If there was a file replacement, show that as well: +% \begin{macrocode} + \str_if_eq:NNF \CurrentFileUsed \CurrentFile + { ~ ( \CurrentFile \space requested ) } + \iow_newline: + } + \str_if_eq:nnT {#1} {STOP} { \int_gdecr:N \g_@@_nesting_level_int } + } +% \end{macrocode} +% +% Now just hook the macro above in the generic |file/before|\ldots +% \begin{macrocode} +\AddToHook{file/before}{ \@@_log_file_record:n { START } } +% \end{macrocode} +% \ldots and |file/after| hooks. +% We don't want to install the \hook{file/after} hook immediately, +% because that would mean it is the first time executed when the +% package finishes. We therefore put the declaration inside +% \cs{AddToHookNext} so that it gets only installed when we have +% left this package. +% \begin{macrocode} +\AddToHookNext{file/after} + { \AddToHook{file/after}{ \@@_log_file_record:n { STOP } } } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<@@=> +%</structuredlog> +% \end{macrocode} +% +% +% +% +% +% +% \section{Package emulations} +% +% +% \subsection{Package \pkg{atveryend} emulation} +% +% With the new hook management and the hooks in \cs{enddocument} +% all of \pkg{atveryend} is taken care of. +% We can make an emulation only here after the substitution +% functionality is available: +% \begin{macrocode} +%<*2ekernel> +\declare@file@substitution{atveryend.sty}{atveryend-ltx.sty} +%</2ekernel> +% \end{macrocode} +% +% Here is the package file we point to: +% \begin{macrocode} +%<*atveryend-ltx> +\ProvidesPackage{atveryend} + [2020/08/19 v1.0a + Emulation of the original atvery package^^Jwith kernel methods] +% \end{macrocode} +% +% +% Here are new definitions for its interfaces now pointing to the +% hooks in \cs{enddocument} +% \begin{macrocode} +\newcommand\AfterLastShipout {\AddToHook{enddocument/afterlastpage}} +\newcommand\AtVeryEndDocument {\AddToHook{enddocument/afteraux}} +% \end{macrocode} +% Next one is a bit of a fake, but the result should normally be as +% expected. If not, one needs to add a rule to sort the code chunks +% in \hook{enddocument/info}. +% \begin{macrocode} +\newcommand\AtEndAfterFileList{\AddToHook{enddocument/info}} +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtVeryVeryEnd {\AddToHook{enddocument/end}} +% \end{macrocode} +% +% \begin{macro}{\BeforeClearDocument} +% This one is the only one we don't implement or rather don't have +% a dedicated hook in the code. +% \begin{macrocode} +\ExplSyntaxOn +\newcommand\BeforeClearDocument[1] + { \AtEndDocument{#1} + \atveryend@DEPRECATED{BeforeClearDocument \tl_to_str:n{#1}} + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn\atveryend@DEPRECATED #1 + {\iow_term:x{======~DEPRECATED~USAGE~#1~==========}} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +%</atveryend-ltx> +% \end{macrocode} % % % \subsection{Package \pkg{filehook} emulation} @@ -1083,79 +1711,11 @@ % % % -% \section{A sample package for structuring the log output} -% -% \begin{macrocode} -%<*structuredlog> -%<@@=filehook> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesExplPackage - {structuredlog}{\ltfilehookdate}{\ltfilehookversion} - {Structuring the TeX transcript file} -% \end{macrocode} - - - -% \begin{macrocode} -\int_new:N \g_@@_nesting_level_int -% \end{macrocode} - -% \begin{macrocode} -\tl_new:N \g_@@_nesting_prefix_tl -\tl_gset:Nn \g_@@_nesting_prefix_tl { } -% \end{macrocode} -% -% \begin{macrocode} -\AddToHook{file/before}{ - \int_gincr:N \g_@@_nesting_level_int - \tl_gput_right:Nn\g_@@_nesting_prefix_tl {=} - \iow_term:x { - \g_@@_nesting_prefix_tl \space - ( LEVEL~ \int_use:N \g_@@_nesting_level_int \space START )~ - \CurrentFile ^^J - } -} -% \end{macrocode} -% We don't want to install the \hook{file/after} hook immediately, -% because that would mean it is the first time executed when the -% package finishes. We therefore put the declaration inside -% \cs{AddToHookNext} so that it gets only installed when we have -% left the package. -% \begin{macrocode} -\AddToHookNext{file/after}{ - \AddToHook{file/after}{ - \iow_term:x { - \g_@@_nesting_prefix_tl \space - ( LEVEL~ \int_use:N \g_@@_nesting_level_int \space STOP )~ - \CurrentFile ^^J - } - \int_gdecr:N \g_@@_nesting_level_int - \tl_gset:Nx \g_@@_nesting_prefix_tl - {\exp_after:wN \use_none:n \g_@@_nesting_prefix_tl} - } -} -% \end{macrocode} -% -% We have to manually increment the level because now that we have -% installed the code in \texttt{file/after} it gets decremented -% when we leave the package without ever being incremented upon -% entry. -% \begin{macrocode} -%\int_incr:N\g_@@_nesting_level_int -% \end{macrocode} -% -% \begin{macrocode} -%</structuredlog> -% \end{macrocode} - % \Finale % - - +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +% diff --git a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx index 60b6a23e5c2..a5ad754bfdc 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2020-06-05 v1.2h LaTeX Kernel (File Handling)] + [2020/08/21 v1.2i LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -47,6 +47,8 @@ Chris Rowley\and Rainer Sch\"opf} +\providecommand\pkg[1]{\texttt{#1}} + \begin{document} \MaintainedByLaTeXTeam{latex} \maketitle @@ -55,6 +57,8 @@ %</driver> % \fi % +% \providecommand\hook[1]{\texttt{#1}} +% % % \changes{v1.0h}{1994/05/21}{Use new error commands} % \changes{v1.0n}{1994/11/17} @@ -62,6 +66,7 @@ % \changes{v1.0u}{1995/07/13}{Updates to docu} % \changes{v1.1m}{2015/02/21} % {Removed autoload support} +% \changes{v1.2i}{2020/08/21}{Integration of new hook management interface} % % \section{File Handling} % @@ -234,22 +239,28 @@ % \changes{v0.9e}{1993/12/09}{Hook added} % \begin{macrocode} %</2ekernel> -%<latexrelease>\IncludeInRelease{2020/06/05}% +%<latexrelease>\IncludeInRelease{2020/10/01}% %<latexrelease> {\document}{Added hook to load l3backend code}% %<*2ekernel|latexrelease> +\def\document{% % \end{macrocode} -% Cancel the |\begingroup| from |\begin|. +% We do cancel the grouping as part of the \cs{begin} handling +% (this is now done inside \cs{begin} instead) so that the +% \hook{env/\meta{env}/begin} hook is not hidden inside \cs{begingroup} +% \texttt{...} \cs{endgroup}. % \begin{macrocode} -\def\document{\endgroup +% \endgroup % \end{macrocode} -% \changes{v1.2h}{2020/06/05}{Added hook to load \textsf{l3backend} code} +% % \begin{macrocode} - \@expl@sys@load@backend@@ + \UseOneTimeHook{begindocument/before}% + \@kernel@after@begindocument@before % \end{macrocode} -% If some options on |\documentclass| haven't been used by any -% package we will now give a warning since this is most certainly a -% misspelling. +% +% Added hook to load \textsf{l3backend} code: +% \changes{v1.2h}{2020/06/05}{Added hook to load \textsf{l3backend} code} % \begin{macrocode} + \@expl@sys@load@backend@@ \ifx\@unusedoptionlist\@empty\else \@latex@warning@no@line{Unused global option(s):^^J% \@spaces[\@unusedoptionlist]}% @@ -352,9 +363,11 @@ % \changes{v1.1e}{1996/04/24} % {(DPC) Reset \cs{AtBeginDocument} eg for latex/1297} % \begin{macrocode} - \let\AtBeginDocument\@firstofone - \@begindocumenthook + \@kernel@before@begindocument + \UseOneTimeHook{begindocument}% + \@kernel@after@begindocument % \end{macrocode} +% % Most of the following assignments will be done globally in case % the user adds something like |\begin{multicols}| to the document % hook, i.e. starts are group in |\begin{document}|. @@ -403,16 +416,73 @@ % \begin{macrocode} \global\let\do\noexpand % \end{macrocode} +% +% \begin{macrocode} + \UseOneTimeHook{begindocument/end}% +% \end{macrocode} % \changes{v1.1c}{1995/12/05}{\cs{ignorespaces} added for latex/1933} -% Use of |\AtBeginDocument| hook might mean that we are already in +% Use of the hook might mean that we are already in % horizontal mode, so ignore the space after |\begin{document}|. % \begin{macrocode} \ignorespaces} +% \end{macrocode} +% +% The \hook{begindocument} hook already existed in the kernel since +% 1994 under the name \cs{atbegindocumenthook} the +% additional ones are originally from the \pkg{etoolbox} +% package under the names \cs{@endpreamblehook} \cs{afterpreamble}. +% \begin{macrocode} +\NewHook{begindocument} +\NewHook{begindocument/before} +\NewHook{begindocument/end} +% \end{macrocode} + + + +% \begin{macro}{\@kernel@after@begindocument@before, +% \@kernel@before@begindocument, +% \@kernel@after@begindocument} +% +% Above we used two kernel only hooks to be run after the public +% \hook{begindocument/before} and after \hook{begindocument} +% hooks. +% +% In \cs{@kernel@after@begindocument@before} we already place one +% action: drop the fast execution code for the +% \hook{env/document/begin} hook. That hook marks the end of the +% preamble and should therefore only be run once. In a normal +% document that is anyway the case (so the code would just sit +% there taking up space afterwards, which these days is rather +% harmless), however, in more complicated scenarios where several +% full documents are combined to a single document it might get +% applied several times with harmful effects. We therefore +% explicitly drop it at this point. the coing is somewhat obscure +% due to the name of the macro which requires constructing. +% \begin{macrocode} +\edef \@kernel@after@begindocument@before {% + \let\expandafter\noexpand\csname + g__hook_env/document/begin_code_tl\endcsname + \noexpand\@empty} +% \end{macrocode} +% +% \begin{macrocode} +\let \@kernel@before@begindocument \@empty +\let \@kernel@after@begindocument \@empty +% \end{macrocode} +% +% \end{macro} +% + +% +% \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease -%<latexrelease> +% \end{macrocode} +% +% \begin{macrocode} %<latexrelease>\IncludeInRelease{2017/04/15}% %<latexrelease> {\document}{Save language for hyphenation}% +%<latexrelease> %<latexrelease>\def\document{\endgroup %<latexrelease> \ifx\@unusedoptionlist\@empty\else %<latexrelease> \@latex@warning@no@line{Unused global option(s):^^J% @@ -601,43 +671,14 @@ % \end{macrocode} % % -% \begin{macro}{\includeonly} +% \begin{macro}{\include,\includeonly} +% \changes{v0.9p}{1994/01/18} +% {Use \cs{@input@} so include files are listed.} % \changes{v1.0p}{1995/04/22}{Allow blanks in argument} % \changes{v1.2a}{2019/07/01}{Support UTF-8} % \changes{v1.2g}{2020/05/02}{Improved support for spaces in filenames % (gh/217)} -% \begin{macrocode} -%</2ekernel> -%<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\includeonly}{Spaces in file names}% -\def\includeonly#1{% - \@partswtrue -% \end{macrocode} -% Because the argument to |\includeonly| is a comma-separated list -% of filenames where there may be comma's precedeing some of the -% filenames or trailing them. Therefore we need to take the list -% apart, remove the unwanted spaces while leaving the spaces -% \emph{in} the filenames intact. -% \begin{macrocode} - \let\@partlist\@empty - \@for\reserved@a:=#1 \do - { - \expandafter\set@curr@file@trim@spaces\expandafter{\reserved@a}% - \ifx\@partlist\@empty - \edef\@partlist{\@curr@file}% - \else - \edef\@partlist{\@partlist,\@curr@file}% - \fi - }% - } -\@onlypreamble\includeonly -% \end{macrocode} -% \end{macro} % -% \begin{macro}{\include} -% \changes{v0.9p}{1994/01/18} -% {Use \cs{@input@} so include files are listed.} % In the definition of |\include|, |\def\reserved@b| changed to % |\edef\reserved@b| to be consistent with the |\edef| in % |\includeonly|. @@ -655,12 +696,26 @@ % from the filename (gh/217)} % \changes{v1.2g}{2020-05-02}{Pass the filename to \cs{@include} by % value instead of by reference (gh/217)} +% +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\includeonly}{Spaces in file names}% +% \end{macrocode} +% % \begin{macrocode} \def\include#1{\relax \ifnum\@auxout=\@partaux \@latex@error{\string\include\space cannot be nested}\@eha \else - \set@curr@file@trim@spaces{#1}% +% \end{macrocode} +% Here the normalisation will add |.tex| for all files, (it uses the +% the same normalisation as the hooks), so we need to remove that +% manually. \cs{@strip@tex@ext} does that. +% \begin{macrocode} + \set@curr@file{#1}% + \edef\@curr@file{\@strip@tex@ext\@curr@file}% % \end{macrocode} % For historical reasons \cs{@include} expects an argument % delimited by a space. This is kept (though uncessary now) to avoid @@ -669,27 +724,56 @@ \expandafter\@include\expandafter{\@curr@file} % deliberate space \fi} % \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\set@curr@file@trim@spaces} % -% For |\include| and |\includeonly| we need a variant that removes -% any leading and trailing spaces from the filename, while leaving -% any spaces \emph{inside} the filename intact. In order simplify -% the implementaion we borrow some code from the \texttt{expl3} -% language, \textbf{\emph{beware}: this may change unannounced}. +% Here in \cs{includeonly} we also need to strip |.tex| after +% normalisation: % \begin{macrocode} -\def\set@curr@file@trim@spaces#1{% - \@expl@tl@trim@spaces@apply@@nN {#1} \set@curr@file } +\def\includeonly#1{% + \@partswtrue % \end{macrocode} -% \end{macro} -% +% Because the argument to |\includeonly| is a comma-separated list +% of filenames where there may be comma's precedeing some of the +% filenames or trailing them. Therefore we need to take the list +% apart, remove the unwanted spaces while leaving the spaces +% \emph{in} the filenames intact. +% \begin{macrocode} + \let\@partlist\@empty + \@for\reserved@a:=#1 \do + {% + \expandafter\set@curr@file\expandafter{\reserved@a}% + \ifx\@partlist\@empty + \edef\@partlist{\@strip@tex@ext\@curr@file}% + \else + \edef\@partlist{\@partlist,\@strip@tex@ext\@curr@file}% + \fi + }% + } +\@onlypreamble\includeonly +% \end{macrocode} +% \end{macro} % +% \begin{macro}{\@strip@tex@ext,\@strip@tex@ext@aux} +% These macros take a (\cs{detokenize}d file name and remove any +% |.tex| extension). Extra care is taken to not remove the string +% |.tex| from the middle of a file name: it is only removed if it's +% the very last thing in the file name. +% \begin{macrocode} +\def\reserved@a#1{% +\def\@strip@tex@ext##1{% + \expandafter\@strip@tex@ext@aux + ##1\@nil\@nil + #1\@nil\relax\@nnil} +\def\@strip@tex@ext@aux##1#1\@nil##2\@nnil{% + \ifx\relax##2\@empty + \expandafter\@cdr\expandafter\@empty\@cdr{}##1% + \else##1\fi}}% +\expandafter\reserved@a +\expandafter{\detokenize{.tex}} +%</2ekernel|latexrelease> +% \end{macrocode} +% \end{macro} % % \begin{macrocode} -%</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2019/10/01}% %<latexrelease> {\includeonly}{Spaces in file names}% @@ -708,7 +792,9 @@ %<latexrelease> \expandafter\@include\@curr@file %<latexrelease> \fi} %<latexrelease> -%<latexrelease>\let\set@curr@file@trim@spaces\@undefined +%<latexrelease>\let\@strip@tex@ext\@undefined +%<latexrelease>\let\@strip@tex@ext@aux\@undefined +%<latexrelease> %<latexrelease>\EndIncludeInRelease % \end{macrocode} % @@ -727,7 +813,6 @@ %<latexrelease>\EndIncludeInRelease %<*2ekernel> % \end{macrocode} - % % \begin{macro}{\@include} % \changes{v1.2g}{2020/05/02}{Support spaces in filenames by enclosing @@ -736,7 +821,7 @@ %</2ekernel> %<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\@include}{Spaces in file names}% +%<latexrelease> {\@include}{Spaces in file names and hooks}% % \end{macrocode} % % \begin{macrocode} @@ -758,8 +843,38 @@ \immediate\openout\@partaux "#1.aux" \immediate\write\@partaux{\relax}% \fi +% \end{macrocode} +% Now before going to the hooks we need to set \cs{CurrentFile}: +% \begin{macrocode} +%----------------------------------------- + \@filehook@set@CurrentFile +% \end{macrocode} +% Execute the \texttt{before} hooks just after we switched the +% \texttt{.aux} file \ldots +% \begin{macrocode} + \UseHook{include/before}% + \UseHook{include/before/#1}% +%----------------------------------------- \@input@{#1.tex}% +%----------------------------------------- +% \end{macrocode} +% \ldots{} then \texttt{end} hooks \ldots +% \begin{macrocode} + \UseHook{include/end/#1}% + \UseHook{include/end}% +%----------------------------------------- \clearpage +%----------------------------------------- +% \end{macrocode} +% \ldots{} and after the \cs{clearpage} the \texttt{after} hooks +% followed by another \cs{clearpage} just in case new material got +% added (after all we need to be in well defined state after the +% \cs{include}). +% \begin{macrocode} + \UseHook{include/after/#1}% + \UseHook{include/after}% + \clearpage +%----------------------------------------- \@writeckpt{#1}% \if@filesw \immediate\closeout\@partaux @@ -776,7 +891,10 @@ \fi \let\@auxout\@mainaux} %<latexrelease>\EndIncludeInRelease -%<latexrelease> +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\@include}{Spaces in file names}% %<latexrelease>\def\@include#1 {% @@ -859,7 +977,6 @@ % % % - % \begin{macro}{\@curr@file} % \begin{macro}{\set@curr@file} % @@ -887,11 +1004,11 @@ % \changes{v1.2c}{2019/10/11}{Remove one brace group} % \changes{v1.2d}{2019/10/26}{remove quotes} % \changes{v1.2e}{2019/11/09}{expand and \cs{string} before removing quotes} +% +% The definition below is from 2019 and only used during kernel +% bootstrapping, later on in \texttt{ltfilehook.dtx} it will get +% overwritten. % \begin{macrocode} -%</2ekernel> -%<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\set@curr@file}{Quote file names}% \def\set@curr@file#1{% \begingroup \escapechar\m@ne @@ -918,6 +1035,10 @@ % -> "" %\end{verbatim} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\quote@name}{Quote file names}% \def\quote@name#1{"\quote@@name#1\@gobble""} \def\quote@@name#1"{#1\quote@@name} % \end{macrocode} @@ -999,12 +1120,11 @@ %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\set@curr@file}{Quote file names}% +%<latexrelease> {\quote@name}{Quote file names}% %<latexrelease> %<latexrelease>\let\quote@name\@undefined %<latexrelease>\let\quote@@name\@undefined %<latexrelease>\let\unquote@name\@undefined -%<latexrelease>\let\set@curr@file\@undefined %<latexrelease> %<latexrelease>\let\IfFileExists@\@undefined %<latexrelease> @@ -1044,25 +1164,14 @@ % % % \begin{macro}{\InputIfFileExists} -% \changes{v0.9b} -% {1993/12/04}{Macro added} -% \changes{v0.9p} -% {1994/01/18}{New Definition} -% \changes{v0.3b}{1994/03/13} -% {Use new cmd \cs{@addtofilelist}} -% Now define |\InputIfFileExists| to input |#1| if it seems to exist. -% Immediately prior to the input, |#2| is executed. -% If the file |#1| does not exist, execute `|#3|'. -% \changes{v1.0t}{1995/05/25} -% {(CAR) added \cs{long}} -% \changes{v1.1o}{2019/02/07}{Expand \cs{@filef@und} before executing -% second argument (github/109)} -% \changes{v1.2b}{2019/08/27}{Make command robust} -% \begin{macrocode} -%</2ekernel> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\InputIfFileExists}{Don't lose the file name}% -%<*2ekernel|latexrelease> +% +% Now define |\InputIfFileExists| to input |#1| if it seems to exist. +% Immediately prior to the input, |#2| is executed. +% If the file |#1| does not exist, execute `|#3|'. +% +% This here is a temporary definition for the kernel. The real one +% comes somewhat later in the file \texttt{ltfilehook.dtx}. +% % \begin{macrocode} \DeclareRobustCommand \InputIfFileExists[2]{% \IfFileExists{#1}% @@ -1079,25 +1188,23 @@ % Swap two arguments and return them unbraced (like % \cs{@firstoftwo} etc). % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\@swaptwoargs}{Don't lose the file name}% \long\def\@swaptwoargs#1#2{#2#1} % \end{macrocode} -% \end{macro} -% % % \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\InputIfFileExists}{Don't lose the file name}% -%<latexrelease>\long\def \InputIfFileExists#1#2{% -%<latexrelease> \IfFileExists{#1}% -%<latexrelease> {#2\@addtofilelist{#1}\@@input \@filef@und}} -%<latexrelease> +%<latexrelease> {\@swaptwoargs}{Don't lose the file name}% %<latexrelease>\let\@swaptwoargs\@undefined %<latexrelease>\EndIncludeInRelease %<*2ekernel> % \end{macrocode} -% +% \end{macro} % % % \begin{macro}{\input} @@ -1114,20 +1221,51 @@ % Define |\@iinput| (i.e., |\input|) in terms of % |\InputIfIfileExists|. % \changes{v0.9b}{1993/12/04}{Macro reimplemented} +% +% Changes to \cs{@iinput}: adapt to the changes to +% \cs{@missingfileerror}. % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\@iinput}{Quote file names}% +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@iinput}{Change in file error handling}% \def\@iinput#1{% \InputIfFileExists{#1}{}% {\filename@parse\@curr@file \edef\reserved@a{\noexpand\@missingfileerror {\filename@area\filename@base}% {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% +% \end{macrocode} +% This line now just sets \cs[no-index]{@missingfile@\meta{part}}: +% \begin{macrocode} + \reserved@a +% \end{macrocode} +% Now here we have to use it. The file here is guaranteed to exist, +% because \cs{@missingfileerror} ensures so, but we have to use +% \cs{InputIfFileExists} because it executes the file hooks. +% \begin{macrocode} + \edef\reserved@a{\noexpand\@iinput{% + \@missingfile@area\@missingfile@base.\@missingfile@ext}}% \reserved@a}} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\@iinput}{Quote file names}% +%<latexrelease> +%<latexrelease>\def\@iinput#1{% +%<latexrelease> \InputIfFileExists{#1}{}% +%<latexrelease> {\filename@parse\@curr@file +%<latexrelease> \edef\reserved@a{\noexpand\@missingfileerror +%<latexrelease> {\filename@area\filename@base}% +%<latexrelease> {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% +%<latexrelease> \reserved@a}} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\@iinput}{Quote file names}% %<latexrelease>\def\@iinput#1{% @@ -1172,6 +1310,11 @@ % \end{macrocode} % \end{macro} % +% +% +% +% +% % \begin{macro}{\@missingfileerror} % This `error' command avoids \TeX's primitive missing file loop. % @@ -1189,7 +1332,16 @@ % {Move here from ltclass} % \changes{v1.0w}{1995/10/06} % {Autoload error} +% +% Changes to \cs{@missingfileerror}: rather than trying to input the +% file by force, now \cs{@missingfileerror} just returns three +% \cs[no-index]{@missingfile@\meta{part}} and the caller macro is +% responsible for doing the right thing with it. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@missingfileerror}{Do not load missing file immediately}% \gdef\@missingfileerror#1#2{% \typeout{^^J! LaTeX Error: File `#1.#2' not found.^^J^^J% Type X to quit or <RETURN> to proceed,^^J% @@ -1198,20 +1350,74 @@ {\endlinechar\m@ne \global\read\m@ne to\@gtempa}% \ifx\@gtempa\@empty +% \end{macrocode} +% If the user answers with \meta{return}, fallback to the |.tex| file +% (previously it did nothing). +% \begin{macrocode} + \let\@missingfile@area\@empty + \let\@missingfile@base\@empty + \def\@missingfile@ext{tex}% \else - \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi - \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi +% \end{macrocode} +% Use \cs{batchmode}\cs{read}|-1 to |\meta{tl} to end the \TeX{} run, +% same as \pkg{expl3} does (it was \cs{batchmode}\cs{@@end} before). +% \begin{macrocode} + \def\reserved@b{\batchmode\read-1 to \reserved@a}% + \def\reserved@a{x}\ifx\reserved@a\@gtempa\reserved@b\fi + \def\reserved@a{X}\ifx\reserved@a\@gtempa\reserved@b\fi \filename@parse\@gtempa \edef\filename@ext{% \ifx\filename@ext\relax#2\else\filename@ext\fi}% \edef\reserved@a{% - \noexpand\InputIfFileExists +% \end{macrocode} +% Only check \cs{IfFileExists} (it was \cs{InputIfFileExists}). +% \begin{macrocode} + \noexpand\IfFileExists {\filename@area\filename@base.\filename@ext}% - {}% +% \end{macrocode} +% If the file exists, define \cs[no-index]{@missingfile@\meta{part}}. +% \begin{macrocode} + {\def\noexpand\@missingfile@area{\filename@area}% + \def\noexpand\@missingfile@base{\filename@base}% + \def\noexpand\@missingfile@ext {\filename@ext}}% {\noexpand\@missingfileerror {\filename@area\filename@base}{\filename@ext}}}% \reserved@a - \fi} + \fi +} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@missingfileerror}{Do not load missing file immediately}% +%<latexrelease> +%<latexrelease>\gdef\@missingfileerror#1#2{% +%<latexrelease> \typeout{^^J! LaTeX Error: File `#1.#2' not found.^^J^^J% +%<latexrelease> Type X to quit or <RETURN> to proceed,^^J% +%<latexrelease> or enter new name. (Default extension: #2)^^J}% +%<latexrelease> \message{Enter file name: }% +%<latexrelease> {\endlinechar\m@ne +%<latexrelease> \global\read\m@ne to\@gtempa}% +%<latexrelease> \ifx\@gtempa\@empty +%<latexrelease> \else +%<latexrelease> \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi +%<latexrelease> \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi +%<latexrelease> \filename@parse\@gtempa +%<latexrelease> \edef\filename@ext{% +%<latexrelease> \ifx\filename@ext\relax#2\else\filename@ext\fi}% +%<latexrelease> \edef\reserved@a{% +%<latexrelease> \noexpand\InputIfFileExists +%<latexrelease> {\filename@area\filename@base.\filename@ext}% +%<latexrelease> {}% +%<latexrelease> {\noexpand\@missingfileerror +%<latexrelease> {\filename@area\filename@base}{\filename@ext}}}% +%<latexrelease> \reserved@a +%<latexrelease> \fi} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx b/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx index 9089c8a7055..2555e21a349 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2020-07-16 v2.2f LaTeX Kernel (Final Settings)] + [2020-08-21 v2.2i LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -88,6 +88,7 @@ % argument.} % \changes{v2.0r}{2016/10/15}{Require e\TeX{}} % \changes{v2.0s}{2016/10/15}{Tidy up status of char 127} +% \changes{v2.2i}{2020/08/21}{Integration of new hook management interface} % % \subsection{Debugging} % @@ -590,7 +591,7 @@ % Skip this section in Unicode TeX, or if MLTeX and EncTeX are enabled. % \begin{macrocode} \ifnum0% - \ifx\Umathchar\@undefined\else 1\fi + \ifx\Umathcode\@undefined\else 1\fi \ifx\mubyte\@undefined\else 1\fi \ifx\charsubdef\@undefined\else 1\fi =\z@ @@ -1134,230 +1135,11 @@ % This is a good place to load code that hasn't yet been % integrated into the other files \ldots % \begin{macrocode} -%</2ekernel> -%<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\ShowHook}{The hook management}% -\input lthooks.ltx -\input ltshipout.ltx -\input ltfilehook.ltx -%</2ekernel|latexrelease> -%<latexrelease>\EndIncludeInRelease -%<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\ShowHook}{The hook management}% - -%<latexrelease> -%<latexrelease>\DeclareRobustCommand*\begin[1]{% -%<latexrelease> \@ifundefined{#1}% -%<latexrelease> {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% -%<latexrelease> {\def\reserved@a{\def\@currenvir{#1}% -%<latexrelease> \edef\@currenvline{\on@line}% -%<latexrelease> \csname #1\endcsname}}% -%<latexrelease> \@ignorefalse -%<latexrelease> \begingroup\@endpefalse\reserved@a} -%<latexrelease> -%<latexrelease>\@namedef{end }#1{% -%<latexrelease> \csname end#1\endcsname\@checkend{#1}% -%<latexrelease> \expandafter\endgroup\if@endpe\@doendpe\fi -%<latexrelease> \if@ignore\@ignorefalse\ignorespaces\fi} -%<latexrelease> -%<latexrelease>\DeclareDocumentCommand \NewHook {m}{} -%<latexrelease>\DeclareDocumentCommand \NewReversedHook {m}{} -%<latexrelease>\DeclareDocumentCommand \NewMirroredHookPair {mm}{} -%<latexrelease> -%<latexrelease>\DeclareDocumentCommand \AddToHookNext {m+m}{} -%<latexrelease>\DeclareDocumentCommand \RemoveFromHook {mo}{} -%<latexrelease>\def \UseHook #1{} -%<latexrelease>\def \UseOneTimeHook #1{} -%<latexrelease>\def \ShowHook #1{} -%<latexrelease>\let \DebugHookOn \@empty -%<latexrelease>\let \DebugHookOff\@empty -%<latexrelease> -%<latexrelease>\DeclareDocumentCommand \DeclareHookRule {mmmm}{} -%<latexrelease>\DeclareDocumentCommand \DeclareDefaultHookRule {mmm}{} -%<latexrelease>\DeclareDocumentCommand \ClearHookRule {mmm}{} -% \end{macrocode} -% If the hook management is not provided we make the test for existence -% false and the test for empty true in the hope that this is most -% of the time reasonable. If not a package would need to guard -% against running in an old kernel. -% \begin{macrocode} -%<latexrelease>\DeclareExpandableDocumentCommand \IfHookExistTF {mmm}{#3} -%<latexrelease>\DeclareExpandableDocumentCommand \IfHookEmptyTF {mmm}{#2} -%<latexrelease> -%<latexrelease>\DeclareRobustCommand\AtBeginDocument{\g@addto@macro\@begindocumenthook} -%<latexrelease>\DeclareRobustCommand\AtEndDocument{\g@addto@macro\@enddocumenthook} -%<latexrelease> -%<latexrelease>\let\AtBeginEnvironment \@undefined -%<latexrelease>\let\AtEndEnvironment \@undefined -%<latexrelease>\let\BeforeBeginEnvironment \@undefined -%<latexrelease>\let\AfterEndEnvironment \@undefined -%<latexrelease> -%<latexrelease>\def\@pushfilename{% -%<latexrelease> \@expl@push@filename@@ -%<latexrelease> \xdef\@currnamestack{% -%<latexrelease> {\@currname}% -%<latexrelease> {\@currext}% -%<latexrelease> {\the\catcode`\@}% -%<latexrelease> \@currnamestack}% -%<latexrelease> \@expl@push@filename@aux@@} -%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil -%<latexrelease> \@expl@pop@filename@@} -%<latexrelease> -%<latexrelease> -%<latexrelease>% next goes away again when etoolbox is updated ... -%<latexrelease>\expandafter\let\csname ver@etoolbox.sty\endcsname\@undefined -%<latexrelease> -%<latexrelease>\def\document{\endgroup -%<latexrelease> \@expl@sys@load@backend@@ -%<latexrelease> \ifx\@unusedoptionlist\@empty\else -%<latexrelease> \@latex@warning@no@line{Unused global option(s):^^J% -%<latexrelease> \@spaces[\@unusedoptionlist]}% -%<latexrelease> \fi -%<latexrelease> \@colht\textheight -%<latexrelease> \@colroom\textheight \vsize\textheight -%<latexrelease> \columnwidth\textwidth -%<latexrelease> \@clubpenalty\clubpenalty -%<latexrelease> \if@twocolumn -%<latexrelease> \advance\columnwidth -\columnsep -%<latexrelease> \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue -%<latexrelease> \fi -%<latexrelease> \hsize\columnwidth \linewidth\hsize -%<latexrelease> \begingroup\@floatplacement\@dblfloatplacement -%<latexrelease> \makeatletter\let\@writefile\@gobbletwo -%<latexrelease> \global \let \@multiplelabels \relax -%<latexrelease> \@input{\jobname.aux}% -%<latexrelease> \endgroup -%<latexrelease> \if@filesw -%<latexrelease> \immediate\openout\@mainaux\jobname.aux -%<latexrelease> \immediate\write\@mainaux{\relax}% -%<latexrelease> \fi -%<latexrelease> \process@table -%<latexrelease> \let\glb@currsize\@empty % Force math initialization. -%<latexrelease> \normalsize -%<latexrelease> \everypar{}% -%<latexrelease> \ifx\normalsfcodes\@empty -%<latexrelease> \ifnum\sfcode`\.=\@m -%<latexrelease> \let\normalsfcodes\frenchspacing -%<latexrelease> \else -%<latexrelease> \let\normalsfcodes\nonfrenchspacing -%<latexrelease> \fi -%<latexrelease> \fi -%<latexrelease> \ifx\document@default@language\m@ne -%<latexrelease> \chardef\document@default@language\language -%<latexrelease> \fi -%<latexrelease> \@noskipsecfalse -%<latexrelease> \let \@refundefined \relax -%<latexrelease> \let\AtBeginDocument\@firstofone -%<latexrelease> \@begindocumenthook -%<latexrelease> \ifdim\topskip<1sp\global\topskip 1sp\relax\fi -%<latexrelease> \global\@maxdepth\maxdepth -%<latexrelease> \global\let\@begindocumenthook\@undefined -%<latexrelease> \ifx\@listfiles\@undefined -%<latexrelease> \global\let\@filelist\relax -%<latexrelease> \global\let\@addtofilelist\@gobble -%<latexrelease> \fi -%<latexrelease> \gdef\do##1{\global\let ##1\@notprerr}% -%<latexrelease> \@preamblecmds -%<latexrelease> \global\let \@nodocument \relax -%<latexrelease> \global\let\do\noexpand -%<latexrelease> \ignorespaces} -%<latexrelease> -%<latexrelease>\def\enddocument{% -%<latexrelease> \let\AtEndDocument\@firstofone -%<latexrelease> \@enddocumenthook -%<latexrelease> \@checkend{document}% -%<latexrelease> \clearpage -%<latexrelease> \begingroup -%<latexrelease> \if@filesw -%<latexrelease> \immediate\closeout\@mainaux -%<latexrelease> \let\@setckpt\@gobbletwo -%<latexrelease> \let\@newl@bel\@testdef -%<latexrelease> \@tempswafalse -%<latexrelease> \makeatletter \@@input\jobname.aux -%<latexrelease> \fi -%<latexrelease> \@dofilelist -%<latexrelease> \ifdim \font@submax >\fontsubfuzz\relax -%<latexrelease> \@font@warning{Size substitutions with differences\MessageBreak -%<latexrelease> up to \font@submax\space have occurred.\@gobbletwo}% -%<latexrelease> \fi -%<latexrelease> \@defaultsubs -%<latexrelease> \@refundefined -%<latexrelease> \if@filesw -%<latexrelease> \ifx \@multiplelabels \relax -%<latexrelease> \if@tempswa -%<latexrelease> \@latex@warning@no@line{Label(s) may have changed. -%<latexrelease> Rerun to get cross-references right}% -%<latexrelease> \fi -%<latexrelease> \else -%<latexrelease> \@multiplelabels -%<latexrelease> \fi -%<latexrelease> \fi -%<latexrelease> \endgroup -%<latexrelease> \deadcycles\z@\@@end} -%<latexrelease> -%<latexrelease>\expandafter\let\csname ver@atveryend.sty\endcsname\@undefined -%<latexrelease>\let\AfterLastShipout \@undefined -%<latexrelease>\let\AtVeryEndDocument \@undefined -%<latexrelease>\let\AtEndAfterFileList \@undefined -%<latexrelease>\let\AtVeryVeryEnd \@undefined -%<latexrelease>\let\BeforeClearDocument \@undefined -%<latexrelease> -%<latexrelease> -%<latexrelease>\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname -%<latexrelease> -%<latexrelease>\let \ShipoutBox\@undefined -%<latexrelease>\let \ReadonlyShipoutCounter \@undefined -%<latexrelease>\let \c@totalpages \@undefined -%<latexrelease>\let \thetotalpages \@undefined -%<latexrelease> -%<latexrelease>\let \DiscardShipoutBox \@undefined -%<latexrelease>\let \DebugShipoutOn \@undefined -%<latexrelease>\let \DebugShipoutOff \@undefined -%<latexrelease> -%<latexrelease>\DeclareRobustCommand \AtBeginDvi [1]{% -%<latexrelease> \global \setbox \@begindvibox -%<latexrelease> \vbox{\unvbox \@begindvibox #1}% -%<latexrelease>} -%<latexrelease> -%<latexrelease>\let \AtBeginShipout \@undefined -%<latexrelease>\let \AtBeginShipoutNext \@undefined -%<latexrelease> -%<latexrelease>\let \AtBeginShipoutFirst \@undefined -%<latexrelease> -%<latexrelease>\let \ShipoutBoxHeight \@undefined -%<latexrelease>\let \ShipoutBoxDepth \@undefined -%<latexrelease>\let \ShipoutBoxWidth \@undefined -%<latexrelease> -%<latexrelease>\let \AtBeginShipoutDiscard \@undefined -%<latexrelease> -%<latexrelease>\let \AtBeginShipoutAddToBox \@undefined -%<latexrelease>\let \AtBeginShipoutAddToBoxForeground \@undefined -%<latexrelease>\let \AtBeginShipoutUpperLeft \@undefined -%<latexrelease>\let \AtBeginShipoutUpperLeftForeground \@undefined -%<latexrelease> -%<latexrelease>\expandafter\let\csname ver@atbegshi.sty\endcsname \@undefined -%<latexrelease> -%<latexrelease>\let \EveryShipout \@undefined -%<latexrelease>\let \AtNextShipout \@undefined -%<latexrelease>\expandafter \let \csname ver@everyshi.sty\endcsname \@undefined -%<latexrelease> -%<latexrelease>\let \AtEndDvi \@undefined -%<latexrelease>\expandafter\let \csname ver@atenddvi.sty\endcsname \@undefined -%<latexrelease> -%<latexrelease>\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} -%<latexrelease> -%<latexrelease>\EndIncludeInRelease -%<*2ekernel> % \end{macrocode} % % \subsection{Some last minute initializations \ldots} % -% This initializes the 2020/02/02 extensions to NFSS after any changes -% in the preamble. % \begin{macrocode} -\g@addto@macro\@kernel@after@env@document@begin - {\reinstall@nfss@defs\init@series@setup} % \end{macrocode} % % diff --git a/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx index 08a0ff1b4c3..d8e4286b786 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssaxes.dtx} - [2020/05/19 v1.0f LaTeX Kernel (NFSS Axes handing)] + [2020/08/21 v1.0g LaTeX Kernel (NFSS Axes handing)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -1294,6 +1294,35 @@ %<latexrelease>\let\reinstall@nfss@defs\relax %<latexrelease>\EndIncludeInRelease %<*2ekernel> +% \end{macrocode} +% +% This initializes the 2020/02/02 extensions to NFSS after any changes +% in the preamble. +% \changes{v1.0g}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\reinstall@nfss@defs}{NFSS series init}% +\g@addto@macro\@kernel@after@begindocument@before + {\reinstall@nfss@defs\init@series@setup} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% The initialization was introduced in 2020/02/02 but +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/02/02}% +%<latexrelease> {\reinstall@nfss@defs}{NFSS series init}% +%<latexrelease>\AtBeginDocument{\reinstall@nfss@defs\init@series@setup} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\reinstall@nfss@defs}{NFSS series init}% +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> %</2ekernel> % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx index 952025375b3..61d0a793a07 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx @@ -36,7 +36,7 @@ % % \ProvidesFile{ltfssini.dtx} - [2020/05/19 v3.2a LaTeX Kernel (NFSS Initialisation)] + [2020/08/27 v3.2c LaTeX Kernel (NFSS Initialisation)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -388,326 +388,6 @@ -% \begin{macro}{\expand@font@defaults} -% \begin{macro}{\rm@def@ult} -% \begin{macro}{\sf@def@ult} -% \begin{macro}{\tt@def@ult} -% \begin{macro}{\md@def@ult} -% \begin{macro}{\bf@def@ult} -% -% The family specific defaults are fully expanded, i.e., they are -% defined via \cs{edef} inside \cs{DeclareFontSeriesDefault}. -% However, the overall defaults, e.g., \cs{bfdefault} may have been -% redefined by the user and thus may not be fully expanded. So to -% enable reliable comparison we make expanded versions of -% them. That we rerun each time. The alternative would be to only -% allow for changes before begin document. -% \begin{macrocode} -\def\expand@font@defaults{% - \edef\rmdef@ult{\rmdefault}% - \edef\sfdef@ult{\sfdefault}% - \edef\ttdef@ult{\ttdefault}% -% \end{macrocode} -% The series defaults may contain some surplus \texttt{m} that we -% need to drop here. -% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from \cs{bfdef@ult} -% and \cs{mddef@ult} (gh/291)} -% \begin{macrocode} - \series@maybe@drop@one@m\bfdefault\bfdef@ult - \series@maybe@drop@one@m\mddefault\mddef@ult -% \end{macrocode} -% Formats that set up parallel fonts, e.g., for Japanese, can use -% this hook to add additional code here. -% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} -% \begin{macrocode} - \@expandfontdefaultshook -} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} - - - -% \begin{macro}{\bfseries} -% This document command switches to the bold series. -% \begin{macrocode} -\DeclareRobustCommand\bfseries{% - \not@math@alphabet\bfseries\mathbf -% \end{macrocode} -% In the original NFSS definition it then called \cs{fontseries} -% with the value \cs{bfdefault}. In the new scheme we have more -% alternatives and therefore check if the current family -% (\cs{f@family}) is the current \cs{rmdef@ult}, \cs{sfdef@ult} or -% \cs{ttdef@ult} and the select the correct family default in that case. -% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside -% of \cs{fontseries} argument so that it is not done several times} -% \begin{macrocode} - \expand@font@defaults -% \end{macrocode} -% If \cs{bfdefault} and \cs{befdefault@previous} are different then -% the default got changed directly through the legacy interface -% (i.e., via \cs{def} or \cs{renewcommand}. In that case we reset -% all meta family defaults so that the document behaves like it was -% the case before the new mechanism was introduced. -% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault} -% and \cs{mddefault} (gh/306)} -% \begin{macrocode} - \ifx\bfdefault\bfdefault@previous\else -% \end{macrocode} -% We add \cs{@empty} and then let \cs{bfdefault@previous} to -% \cs{bfdefault} so that we can detect any further change. -% \begin{macrocode} - \expandafter\def\expandafter\bfdefault - \expandafter{\bfdefault\@empty}% - \let\bfseries@previous\bfdefault -% \end{macrocode} -% And we reset the meta family defaults (\cs{bfdef@ult} is an -% expanded version of \cs{bfdefault}. -% \begin{macrocode} - \let\bfseries@rm\bfdef@ult - \let\bfseries@sf\bfdef@ult - \let\bfseries@tt\bfdef@ult -% \end{macrocode} -% -% Formats that set up parallel fonts, e.g., for Japanese, can use -% this hook to add resets here. -% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} -% \begin{macrocode} - \@setbfseriesdefaultshook - \fi -% \end{macrocode} -% -% \begin{macrocode} - \ifx\f@family\rmdef@ult \fontseries\bfseries@rm - \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf - \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt -% \end{macrocode} -% If not \cs{bfdefault} is used. -% \begin{macrocode} - \else \fontseries\bfdefault - \fi\fi\fi - \selectfont -} -% \end{macrocode} -% \end{macro} - - - -% \begin{macro}{\mdseries} -% This document command switches to the medium series. -% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside -% of \cs{fontseries} argument so that it is not done several times} -% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault} -% and \cs{mddefault} (gh/306)} -% \begin{macrocode} -\DeclareRobustCommand\mdseries{% - \not@math@alphabet\mdseries\relax - \expand@font@defaults - \ifx\mddefault\mddefault@previous\else - \expandafter\def\expandafter\mddefault\expandafter{\mddefault\@empty}% - \let\mdseries@previous\mddefault - \let\mdseries@rm\mddef@ult - \let\mdseries@sf\mddef@ult - \let\mdseries@tt\mddef@ult -% \end{macrocode} -% -% Formats that set up parallel fonts, e.g., for Japanese, can use -% this hook to add resets here. -% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} -% \begin{macrocode} - \@setmdseriesdefaultshook - \fi - \ifx\f@family\rmdef@ult \fontseries\mdseries@rm - \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf - \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt - \else \fontseries\mddefault - \fi\fi\fi - \selectfont -} -% \end{macrocode} -% \end{macro} - - -% \begin{macro}{\rmfamily} -% Here are the document level commands for changing the main font -% families, or rather, here is a documented outline of the code, -% the actual code is then streamlined and somewhat generalized. -%\begin{verbatim} -%\DeclareRobustCommand\rmfamily{% -% \not@math@alphabet\rmfamily\mathrm -%\end{verbatim} -% If families are changed then we have to do a bit more work. -% In the original NFSS implementation -% a family change kept encoding, series shape and size unchanged -% but now we can't any -% longer simply reuse the current series value. Instead we may have -% to change it from one family default to the next. -%\begin{verbatim} -% \expand@font@defaults -%\end{verbatim} -% We have to do the testing while the current family is still -% unchanged but we have to do the adjustment of the series after it -% got changed (because the new family might has different sets -% ofshapes available and we certainly don't want to see -% substituation going on. So we use \cs{target@series@value} to -% hold the target series (if any). -%\begin{verbatim} -% \let\target@series@value\@empty -%\end{verbatim} -% Thus, if the current family is the sans family -%\begin{verbatim} -% \ifx\f@family\sfdef@ult -%\end{verbatim} -% and if we using the medium series of the sans family -%\begin{verbatim} -% \ifx\f@series\mdseries@sf -%\end{verbatim} -% then lets switch to the medium series for the serif family -%\begin{verbatim} -% \let\target@series@value\mdseries@rm -%\end{verbatim} -% and if we use the bold series of the sans family switch to the -% bold default of the serif family: -%\begin{verbatim} -% \else\ifx\f@series\bfseries@sf \let\target@series@value\bfseries@rm -%\end{verbatim} -% However, the sans family may not have any specific defaults set, -% so we also compare with the overall defaults. -%\begin{verbatim} -% \else\ifx\f@series\mddef@ult \let\target@series@value\mdseries@rm -% \else\ifx\f@series\bfdef@ult \let\target@series@value\bfseries@rm -%\end{verbatim} -% If neither test was true we leave the series alone. This way a -% special manual setting such as \verb=\fontseries{lc}= is not -% undone if the family changes (of course there may not be any -% support for it in the new family but then the NFSS -% substitution kicks in and sorts it out). -%\begin{verbatim} -% \fi\fi\fi\fi -% -%\end{verbatim} -% We need to do the same if the current family is the typewriter family: -%\begin{verbatim} -% \else\ifx\f@family\ttdef@ult -% \ifx\f@series\mdseries@tt \let\target@series@value\mdseries@rm -% \else\ifx\f@series\bfseries@tt \let\target@series@value\bfseries@rm -% \else\ifx\f@series\mddef@ult \let\target@series@value\mdseries@rm -% \else\ifx\f@series\bfdef@ult \let\target@series@value\bfseries@rm -% \fi\fi\fi\fi -% \fi\fi -%\end{verbatim} -% With these preparations for series out of the way we can now -% change the font family to \cs{rmdefault}. -%\begin{verbatim} -% \fontfamily\rmdefault -%\end{verbatim} -% -% If \cs{target@series@value} is still empty there is nothing more -% to do other than selecting the new family. However, if not then -% we should update the font series now as well. But there is one -% further subtle issue. We may not have loaded an \texttt{.fd} file -% for our target font family yet. In the past that was done in -% \cs{selectfont} if necessary but since we are now doing all the -% comparisons in \cs{fontseries} we need to make sure that the font -% family specifications are already loaded prior to calling -% \cs{fontseries}. -%\begin{verbatim} -% \ifx\target@series@value\@empty \else -% \maybe@load@fontshape -%\end{verbatim} -% Updating the series in this case means directly changing -% \cs{f@series} to the target value. We don't want to go through -% \cs{fontseries} because that would apply the mappings and then -% \texttt{bx + b} would keep \texttt{bx} instead of changing to -% \texttt{b} as desired. -% as -%\begin{verbatim} -% \let\f@series\target@series@value -% \fi -% \selectfont} -%\end{verbatim} -% -% So now for the real definition: most of the code above gets -% delegated to a helper command \cs{prepare@family@series@update} -% so that the definition becomes again fairly short. In addition we -% add a hook, mainly for our Japanese friends so that the code can -% be extended prior to the call to \cs{selectfont}. -% -% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} -% \begin{macrocode} -\DeclareRobustCommand\rmfamily{% - \not@math@alphabet\rmfamily\mathrm -% \end{macrocode} -% This holds all the code discussed above, first argument is the -% meta family, i.e., \texttt{rm} in this case, and second argument -% is the default family name, e.g., \texttt{cmr} indirectly -% accessed via \cs{rmdefault}. This is calling \cs{fontfamily} and -% if necessary \cs{fontseries} as outline above. -% \begin{macrocode} - \prepare@family@series@update{rm}\rmdefault -% \end{macrocode} -% Then comes the hook code (by default a no-op) and finally the call -% to \cs{selectfont}. -% \begin{macrocode} - \@rmfamilyhook - \selectfont} -% \end{macrocode} -% -% \begin{macro}{\sffamily} -% \begin{macro}{\ttfamily} -% The definitions for \cs{sffamily} and \cs{ttfamily} are similar, -% the differences are only in what font families get checked. -% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} -% \begin{macrocode} -\DeclareRobustCommand\sffamily{% - \not@math@alphabet\sffamily\mathsf - \prepare@family@series@update{sf}\sfdefault - \@sffamilyhook - \selectfont} -% \end{macrocode} -% -% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} -% \begin{macrocode} -\DeclareRobustCommand\ttfamily{% - \not@math@alphabet\ttfamily\mathtt - \prepare@family@series@update{tt}\ttdefault - \@ttfamilyhook - \selectfont} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\@expandfontdefaultshook} -% \begin{macro}{\@setbfseriesdefaultshook} -% \begin{macro}{\@setmdseriesdefaultshook} -% \begin{macro}{\@rmfamilyhook} -% \begin{macro}{\@sffamilyhook} -% \begin{macro}{\@ttfamilyhook} -% By default the hooks do nothing. -% \begin{macrocode} -\let\@expandfontdefaultshook\@empty -\let\@setbfseriesdefaultshook\@empty -\let\@setmdseriesdefaultshook\@empty -% \end{macrocode} -% -% \begin{macrocode} -\let\@rmfamilyhook\@empty -\let\@sffamilyhook\@empty -\let\@ttfamilyhook\@empty -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% % % % @@ -767,7 +447,7 @@ % \begin{itemize} % \item \cs{bfseries} is called for a family using \texttt{bx} % (e.g., CMR) -% \item Switch to a font family that is none of the the meta +% \item Switch to a font family that is none of the meta % families, e.g., via \verb=\fontfamily{ptm}\selectfont= % \item Then none of the real meta families, match but the final % \verb=\@elt{??}= will. @@ -944,16 +624,19 @@ % \cs{DeclareFontSeriesDefault} interface. % \begin{macrocode} \ifx\bfseries@rm@kernel\bfseries@rm - \expandafter\in@\expandafter{\rmdefault}{cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% + \expandafter\in@\expandafter{\rmdefault}% + {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% \ifin@ \else \def\bfseries@rm{b}\fi\fi % \end{macrocode} % Same approach for \cs{bfseries@sf} and \cs{bfseries@tt}: % \begin{macrocode} \ifx\bfseries@sf@kernel\bfseries@sf - \expandafter\in@\expandafter{\sfdefault}{cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% + \expandafter\in@\expandafter{\sfdefault}% + {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% \ifin@ \else \def\bfseries@sf{b}\fi\fi \ifx\bfseries@tt@kernel\bfseries@tt - \expandafter\in@\expandafter{\ttdefault}{cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% + \expandafter\in@\expandafter{\ttdefault}% + {cmr,cmss,cmtt,lcmss,lcmtt,lmr,lmss,lmtt}% \ifin@ \else \def\bfseries@tt{b}\fi\fi % \end{macrocode} % @@ -1033,9 +716,431 @@ %<latexrelease>\let\mdseries@rm\@undefined %<latexrelease>\let\mdseries@sf\@undefined %<latexrelease>\let\mdseries@tt\@undefined -%<latexrelease>\let\expand@font@defaults\@undefined %<latexrelease>\expandafter\let\csname ver@mweights.sty\endcsname\@undefined %<latexrelease> +%<latexrelease>\let\@meta@family@list\@undefined +%<latexrelease>\let\prepare@family@series@update\@undefined +%<latexrelease>\let\update@series@target@value\@undefined +%<latexrelease> +% \end{macrocode} +% This is always called in \cs{document} so don't make it undefined. +% \begin{macrocode} +%<latexrelease>\let\init@series@setup\relax +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\bfseries}{Custom series with hooks}% +% \end{macrocode} + + +% \begin{macro}{\expand@font@defaults} +% \begin{macro}{\rm@def@ult} +% \begin{macro}{\sf@def@ult} +% \begin{macro}{\tt@def@ult} +% \begin{macro}{\md@def@ult} +% \begin{macro}{\bf@def@ult} +% +% The family specific defaults are fully expanded, i.e., they are +% defined via \cs{edef} inside \cs{DeclareFontSeriesDefault}. +% However, the overall defaults, e.g., \cs{bfdefault} may have been +% redefined by the user and thus may not be fully expanded. So to +% enable reliable comparison we make expanded versions of +% them. That we rerun each time. The alternative would be to only +% allow for changes before begin document. +% \begin{macrocode} +\def\expand@font@defaults{% + \edef\rmdef@ult{\rmdefault}% + \edef\sfdef@ult{\sfdefault}% + \edef\ttdef@ult{\ttdefault}% +% \end{macrocode} +% The series defaults may contain some surplus \texttt{m} that we +% need to drop here. +% \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from \cs{bfdef@ult} +% and \cs{mddef@ult} (gh/291)} +% \begin{macrocode} + \series@maybe@drop@one@m\bfdefault\bfdef@ult + \series@maybe@drop@one@m\mddefault\mddef@ult +% \end{macrocode} +% Formats that set up parallel fonts, e.g., for Japanese, can use +% this hook to add additional code here. +% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} + \UseHook{expand@font@defaults}% +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} + + +% \begin{macro}{\bfseries} +% This document command switches to the bold series. +% \begin{macrocode} +\DeclareRobustCommand\bfseries{% + \not@math@alphabet\bfseries\mathbf +% \end{macrocode} +% In the original NFSS definition it then called \cs{fontseries} +% with the value \cs{bfdefault}. In the new scheme we have more +% alternatives and therefore check if the current family +% (\cs{f@family}) is the current \cs{rmdef@ult}, \cs{sfdef@ult} or +% \cs{ttdef@ult} and the select the correct family default in that case. +% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside +% of \cs{fontseries} argument so that it is not done several times} +% \begin{macrocode} + \expand@font@defaults +% \end{macrocode} +% If \cs{bfdefault} and \cs{befdefault@previous} are different then +% the default got changed directly through the legacy interface +% (i.e., via \cs{def} or \cs{renewcommand}. In that case we reset +% all meta family defaults so that the document behaves like it was +% the case before the new mechanism was introduced. +% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault} +% and \cs{mddefault} (gh/306)} +% \begin{macrocode} + \ifx\bfdefault\bfdefault@previous\else +% \end{macrocode} +% We add \cs{@empty} and then let \cs{bfdefault@previous} to +% \cs{bfdefault} so that we can detect any further change. +% \begin{macrocode} + \expandafter\def\expandafter\bfdefault + \expandafter{\bfdefault\@empty}% + \let\bfseries@previous\bfdefault +% \end{macrocode} +% And we reset the meta family defaults (\cs{bfdef@ult} is an +% expanded version of \cs{bfdefault}. +% \begin{macrocode} + \let\bfseries@rm\bfdef@ult + \let\bfseries@sf\bfdef@ult + \let\bfseries@tt\bfdef@ult +% \end{macrocode} +% +% Formats that set up parallel fonts, e.g., for Japanese, can use +% this hook to add resets here. Not that this hook is only run when +% resets are necessary. +% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} + \UseHook{bfseries/defaults}% + \fi +% \end{macrocode} +% +% \begin{macrocode} + \ifx\f@family\rmdef@ult \fontseries\bfseries@rm + \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf + \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt +% \end{macrocode} +% If not \cs{bfdefault} is used. +% \begin{macrocode} + \else \fontseries\bfdefault + \fi\fi\fi +% \end{macrocode} +% This hook in contrast is always executed. +% \begin{macrocode} + \UseHook{bfseries}% + \selectfont +} +% \end{macrocode} +% \end{macro} + + + +% \begin{macro}{\mdseries} +% This document command switches to the medium series. +% \changes{v3.1i}{2020/02/18}{Make the \cs{ifx} selection outside +% of \cs{fontseries} argument so that it is not done several times} +% \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault} +% and \cs{mddefault} (gh/306)} +% \begin{macrocode} +\DeclareRobustCommand\mdseries{% + \not@math@alphabet\mdseries\relax + \expand@font@defaults + \ifx\mddefault\mddefault@previous\else + \expandafter\def\expandafter\mddefault\expandafter{\mddefault\@empty}% + \let\mdseries@previous\mddefault + \let\mdseries@rm\mddef@ult + \let\mdseries@sf\mddef@ult + \let\mdseries@tt\mddef@ult +% \end{macrocode} +% +% Formats that set up parallel fonts, e.g., for Japanese, can use +% this hook to add resets here. +% \changes{v3.1m}{2020/04/06}{Hook added (gh/306)} +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} + \UseHook{mdseries/defaults}% + \fi + \ifx\f@family\rmdef@ult \fontseries\mdseries@rm + \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf + \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt + \else \fontseries\mddefault + \fi\fi\fi + \UseHook{mdseries}% + \selectfont +} +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\rmfamily} +% Here are the document level commands for changing the main font +% families, or rather, here is a documented outline of the code, +% the actual code is then streamlined and somewhat generalized. +%\begin{verbatim} +%\DeclareRobustCommand\rmfamily{% +% \not@math@alphabet\rmfamily\mathrm +%\end{verbatim} +% If families are changed then we have to do a bit more work. +% In the original NFSS implementation +% a family change kept encoding, series shape and size unchanged +% but now we can't any +% longer simply reuse the current series value. Instead we may have +% to change it from one family default to the next. +%\begin{verbatim} +% \expand@font@defaults +%\end{verbatim} +% We have to do the testing while the current family is still +% unchanged but we have to do the adjustment of the series after it +% got changed (because the new family might has different sets +% ofshapes available and we certainly don't want to see +% substituation going on. So we use \cs{target@series@value} to +% hold the target series (if any). +%\begin{verbatim} +% \let\target@series@value\@empty +%\end{verbatim} +% Thus, if the current family is the sans family +%\begin{verbatim} +% \ifx\f@family\sfdef@ult +%\end{verbatim} +% and if we using the medium series of the sans family +%\begin{verbatim} +% \ifx\f@series\mdseries@sf +%\end{verbatim} +% then lets switch to the medium series for the serif family +%\begin{verbatim} +% \let\target@series@value\mdseries@rm +%\end{verbatim} +% and if we use the bold series of the sans family switch to the +% bold default of the serif family: +%\begin{verbatim} +% \else\ifx\f@series\bfseries@sf \let\target@series@value\bfseries@rm +%\end{verbatim} +% However, the sans family may not have any specific defaults set, +% so we also compare with the overall defaults. +%\begin{verbatim} +% \else\ifx\f@series\mddef@ult \let\target@series@value\mdseries@rm +% \else\ifx\f@series\bfdef@ult \let\target@series@value\bfseries@rm +%\end{verbatim} +% If neither test was true we leave the series alone. This way a +% special manual setting such as \verb=\fontseries{lc}= is not +% undone if the family changes (of course there may not be any +% support for it in the new family but then the NFSS +% substitution kicks in and sorts it out). +%\begin{verbatim} +% \fi\fi\fi\fi +% +%\end{verbatim} +% We need to do the same if the current family is the typewriter family: +%\begin{verbatim} +% \else\ifx\f@family\ttdef@ult +% \ifx\f@series\mdseries@tt \let\target@series@value\mdseries@rm +% \else\ifx\f@series\bfseries@tt \let\target@series@value\bfseries@rm +% \else\ifx\f@series\mddef@ult \let\target@series@value\mdseries@rm +% \else\ifx\f@series\bfdef@ult \let\target@series@value\bfseries@rm +% \fi\fi\fi\fi +% \fi\fi +%\end{verbatim} +% With these preparations for series out of the way we can now +% change the font family to \cs{rmdefault}. +%\begin{verbatim} +% \fontfamily\rmdefault +%\end{verbatim} +% +% If \cs{target@series@value} is still empty there is nothing more +% to do other than selecting the new family. However, if not then +% we should update the font series now as well. But there is one +% further subtle issue. We may not have loaded an \texttt{.fd} file +% for our target font family yet. In the past that was done in +% \cs{selectfont} if necessary but since we are now doing all the +% comparisons in \cs{fontseries} we need to make sure that the font +% family specifications are already loaded prior to calling +% \cs{fontseries}. +%\begin{verbatim} +% \ifx\target@series@value\@empty \else +% \maybe@load@fontshape +%\end{verbatim} +% Updating the series in this case means directly changing +% \cs{f@series} to the target value. We don't want to go through +% \cs{fontseries} because that would apply the mappings and then +% \texttt{bx + b} would keep \texttt{bx} instead of changing to +% \texttt{b} as desired. +% as +%\begin{verbatim} +% \let\f@series\target@series@value +% \fi +% \selectfont} +%\end{verbatim} +% +% So now for the real definition: most of the code above gets +% delegated to a helper command \cs{prepare@family@series@update} +% so that the definition becomes again fairly short. In addition we +% add a hook, mainly for our Japanese friends so that the code can +% be extended prior to the call to \cs{selectfont}. +% +% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} +% \begin{macrocode} +\DeclareRobustCommand\rmfamily{% + \not@math@alphabet\rmfamily\mathrm +% \end{macrocode} +% This holds all the code discussed above, first argument is the +% meta family, i.e., \texttt{rm} in this case, and second argument +% is the default family name, e.g., \texttt{cmr} indirectly +% accessed via \cs{rmdefault}. This is calling \cs{fontfamily} and +% if necessary \cs{fontseries} as outline above. +% \begin{macrocode} + \prepare@family@series@update{rm}\rmdefault +% \end{macrocode} +% Then comes the hook code (by default a no-op) and finally the call +% to \cs{selectfont}. +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} + \UseHook{rmfamily}% + \selectfont} +% \end{macrocode} +% +% \begin{macro}{\sffamily} +% \begin{macro}{\ttfamily} +% The definitions for \cs{sffamily} and \cs{ttfamily} are similar, +% the differences are only in what font families get checked. +% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} +\DeclareRobustCommand\sffamily{% + \not@math@alphabet\sffamily\mathsf + \prepare@family@series@update{sf}\sfdefault + \UseHook{sffamily}% + \selectfont} +% \end{macrocode} +% +% \changes{v3.1f}{2020/01/11}{Streamlined implementation with hook} +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} +\DeclareRobustCommand\ttfamily{% + \not@math@alphabet\ttfamily\mathtt + \prepare@family@series@update{tt}\ttdefault + \UseHook{ttfamily}% + \selectfont} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{rmfamily,sffamily,ttfamily,normalfont,expand@font@defaults, +% bfseries,bfseries/defaults,mdseries,mdseries/defaults} +% Declare the hooks used above. +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} +\NewHook{rmfamily} +\NewHook{sffamily} +\NewHook{ttfamily} +\NewHook{normalfont} +\NewHook{expand@font@defaults} +\NewHook{bfseries} +\NewHook{bfseries/defaults} +\NewHook{mdseries} +\NewHook{mdseries/defaults} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@rmfamilyhook} +% \begin{macro}{\@sffamilyhook} +% \begin{macro}{\@ttfamilyhook} +% These four hooks have legacy versions used in 2020/02/02 so we +% should support them until they aren't any longer used. +% \begin{macrocode} +\let\@rmfamilyhook\@empty +\let\@sffamilyhook\@empty +\let\@ttfamilyhook\@empty +\let\@defaulfamilyhook\@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/02/02}% +%<latexrelease> {\bfseries}{Custom series with hooks}% +%<latexrelease> +%<latexrelease>\def\expand@font@defaults{% +%<latexrelease> \edef\rmdef@ult{\rmdefault}% +%<latexrelease> \edef\sfdef@ult{\sfdefault}% +%<latexrelease> \edef\ttdef@ult{\ttdefault}% +%<latexrelease> \edef\bfdef@ult{\bfdefault}% +%<latexrelease> \edef\mddef@ult{\mddefault}% +%<latexrelease> \edef\famdef@ult{\familydefault}% +%<latexrelease>} +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\bfseries{% +%<latexrelease> \not@math@alphabet\bfseries\mathbf +%<latexrelease> \expand@font@defaults +%<latexrelease> \ifx\f@family\rmdef@ult \fontseries\bfseries@rm +%<latexrelease> \else\ifx\f@family\sfdef@ult \fontseries\bfseries@sf +%<latexrelease> \else\ifx\f@family\ttdef@ult \fontseries\bfseries@tt +%<latexrelease> \else \fontseries\bfdefault +%<latexrelease> \fi\fi\fi +%<latexrelease> \selectfont +%<latexrelease>} +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\mdseries{% +%<latexrelease> \not@math@alphabet\mdseries\relax +%<latexrelease> \expand@font@defaults +%<latexrelease> \ifx\f@family\rmdef@ult \fontseries\mdseries@rm +%<latexrelease> \else\ifx\f@family\sfdef@ult \fontseries\mdseries@sf +%<latexrelease> \else\ifx\f@family\ttdef@ult \fontseries\mdseries@tt +%<latexrelease> \else \fontseries\mddefault +%<latexrelease> \fi\fi\fi +%<latexrelease> \selectfont +%<latexrelease>} +%<latexrelease> +%<latexrelease>\DeclareRobustCommand\rmfamily{% +%<latexrelease> \not@math@alphabet\rmfamily\mathrm +%<latexrelease> \prepare@family@series@update{rm}\rmdefault +%<latexrelease> \@rmfamilyhook +%<latexrelease> \selectfont} +%<latexrelease>\DeclareRobustCommand\sffamily{% +%<latexrelease> \not@math@alphabet\sffamily\mathsf +%<latexrelease> \prepare@family@series@update{sf}\sfdefault +%<latexrelease> \@sffamilyhook +%<latexrelease> \selectfont} +%<latexrelease>\DeclareRobustCommand\ttfamily{% +%<latexrelease> \not@math@alphabet\ttfamily\mathtt +%<latexrelease> \prepare@family@series@update{tt}\ttdefault +%<latexrelease> \@ttfamilyhook +%<latexrelease> \selectfont} +%<latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\bfseries}{Custom series with hooks}% +%<latexrelease> +%<latexrelease>\let\expand@font@defaults\@undefined +%<latexrelease> %<latexrelease>\DeclareRobustCommand\bfseries %<latexrelease> {\not@math@alphabet\bfseries\mathbf %<latexrelease> \fontseries\bfdefault\selectfont} @@ -1052,20 +1157,9 @@ %<latexrelease> {\not@math@alphabet\ttfamily\mathtt %<latexrelease> \fontfamily\ttdefault\selectfont} %<latexrelease> -%<latexrelease>\let\@expandfontdefaultshook\@undefined -%<latexrelease>\let\@setbfseriesdefaultshook\@undefined -%<latexrelease>\let\@setmdseriesdefaultshook\@undefined %<latexrelease>\let\@rmfamilyhook\@undefined %<latexrelease>\let\@sffamilyhook\@undefined %<latexrelease>\let\@ttfamilyhook\@undefined -%<latexrelease>\let\@meta@family@list\@undefined -%<latexrelease>\let\prepare@family@series@update\@undefined -%<latexrelease>\let\update@series@target@value\@undefined -%<latexrelease> -% \end{macrocode} -% This is always called in \cs{document} so don't make it undefined. -% \begin{macrocode} -%<latexrelease>\let\init@series@setup\relax %<latexrelease> %<latexrelease>\EndIncludeInRelease %<*2ekernel> @@ -1110,7 +1204,10 @@ %</2ekernel> %<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}% -%<latexrelease> {\IfFontSeriesContext}{Font series context}% +%<latexrelease> {\IfFontSeriesContextTF}{Font series context}% +% \end{macrocode} +% +% \begin{macrocode} \DeclareRobustCommand\IfFontSeriesContextTF[1]{% \expand@font@defaults % \end{macrocode} @@ -1217,7 +1314,7 @@ % % \begin{macrocode} %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\IfFontSeriesContext}{Font series context}% +%<latexrelease> {\IfFontSeriesContextTF}{Font series context}% %<latexrelease> %<latexrelease>\let\IfFontSeriesContextTF\@undefined %<latexrelease>\let\test@font@series@context\@undefined @@ -1668,8 +1765,14 @@ \edef\f@shape{\shapedefault}% % \end{macrocode} % +% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} +% \begin{macrocode} + \UseHook{normalfont}% +% \end{macrocode} +% This is the old name for the hook introduced in 2020/02/02. +% It will be removed in one of the future releases! % \begin{macrocode} - \@defaultfamilyhook + \@defaultfamilyhook % hookname from 2020/02 will vanish \selectfont} % \end{macrocode} % @@ -1684,7 +1787,7 @@ % By default the hooks do nothing. % \changes{v3.1h}{2020/02/10}{Add \cs{@defaultfamilyhook} to \cs{normalfont} (gh/269)} % \begin{macrocode} -\let\@defaultfamilyhook\@empty +\let\@defaultfamilyhook\@empty %FMi sort out % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx index 603b472e44a..b1e3985704a 100644 --- a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx +++ b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx @@ -1,29 +1,41 @@ % \iffalse meta-comment +%% +%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, +%% Phelype Oleinik & LaTeX Team % -%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file +% This file is part of the LaTeX base system. +% ------------------------------------------- % +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in % https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". % +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. % -% The development version of the bundle can be found below +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. % -% https://github.com/FrankMittelbach/... +% \fi % -% for those people who are interested or want to report an issue. +% \iffalse +% +%%% From File: lthooks.dtx % % \begin{macrocode} -\providecommand\lthooksversion{v0.9b} -\providecommand\lthooksdate{2020/07/19} +\def\lthooksversion{v1.0a} +\def\lthooksdate{2020/08/31} % \end{macrocode} % %<*driver> -\RequirePackage[debug]{lthooks} - \documentclass{l3doc} % bug fix fo l3doc.cls @@ -160,17 +172,14 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % - - - +% +% +% % \begin{function}{\UseHook} % \begin{syntax} % \cs{UseHook} \Arg{hook} % \end{syntax} -% Execute the hook code inside a command or environment.\footnote{For -% legacy hooks such as \hook{begindocument} it is also -% possible to call \cs{@...hook}, e.g., \cs{@begindocumenthook}, -% but this syntax is discouraged.} +% Execute the hook code inside a command or environment. % % Before \verb=\begin{document}= the fast execution code for a hook % is not set up, so in order to use a hook there it is explicitly @@ -258,6 +267,12 @@ % % \medskip % +% In contrast to the \texttt{voids} relationship between two labels +% in a \cs{DeclareHookrule} this is a destructive operation as the +% labeled code is removed from the hook data structure, whereas the +% relationship setting can be undone by providing a different +% relationship later. +% % A useful application for this declaration inside the document body % is when one wants to temporarily add code to hooks and later remove % it again, e.g., @@ -298,8 +313,19 @@ % used several times before the hook is executed then all code is % executed in the order in which it was declared.\footnotemark % -% The hook doesn't have to exist for code to be added to it. This -% allows for hooks to work regardless of package loading order. +% It is possible to nest declarations using the same hook (or +% different hooks), e.g., +% \begin{quote} +% \cs{AddToHookNext}\Arg{hook}\verb={=\meta{code-1}^^A +% \cs{AddToHookNext}\Arg{hook}\Arg{code-2}\verb=}= +% \end{quote} +% will execute \meta{code-1} next time the \meta{hook} is used and at +% that point puts \meta{code-2} into the \meta{hook} so that it gets +% executed on following time the hook is run. +% +% A hook doesn't have to exist for code to be added to it. This +% allows for hooks to work regardless of package loading +% order. % See section~\ref{sec:querying}. % % The \meta{hook} can be specified using the dot-syntax to denote @@ -337,7 +363,7 @@ % name---see~\cs{DeclareDefaultHookLabel}). % A \enquote{|.|} or \enquote{|./|} anywhere else in a \meta{hook} or in % \meta{label} is treated literally and is not replaced. - +% % For example, % inside the package \texttt{mypackage.sty}, the default label is % \texttt{mypackage}, so the instructions: @@ -345,15 +371,15 @@ % \NewHook {./hook} % \AddToHook {./hook}[.]{code} % Same as \AddToHook{./hook}{code} % \AddToHook {./hook}[./sub]{code} -% \DeclareHookRule{begindocument}{.}{<}{babel} +% \DeclareHookRule{begindocument}{.}{before}{babel} % \AddToHook {file/after/foo.tex}{code} % \end{verbatim} % are equivalent to: % \begin{verbatim} -% \NewHook {mypackage/hook}[mypackage]{code} +% \NewHook {mypackage/hook} % \AddToHook {mypackage/hook}[mypackage]{code} % \AddToHook {mypackage/hook}[mypackage/sub]{code} -% \DeclareHookRule{begindocument}{mypackage}{<}{babel} +% \DeclareHookRule{begindocument}{mypackage}{before}{babel} % \AddToHook {file/after/foo.tex}{code} % unchanged % \end{verbatim} % @@ -376,7 +402,7 @@ % because the hook is most of the time used outside of the package file % in which it was defined. This syntax is also not available in the hook % conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}) and -% \cs{IfHookExistTF} (and \cs{hook_if_exist:nTF}) because these +% \cs{IfHookExistsTF} (and \cs{hook_if_exist:nTF}) because these % conditionals are used in some performance-critical parts of the hook % management code, and because they are usually used to refer to other % package's hooks, so the dot-syntax doesn't make much sense. @@ -426,7 +452,7 @@ % \cs{DeclareHookRule} \Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} % \end{syntax} % Defines a relation between \meta{label1} and \meta{label2} for a -% given \meta{hook}. If \meta{hook} is \texttt{??} this defines a +% given \meta{hook}. If \meta{hook} is \texttt{??} this defines a default % relation for all hooks that use the two labels, i.e., that have % chunks of code labeled with \meta{label1} and \meta{label2}. % Rules specific to a given hook take precedence over default @@ -455,7 +481,7 @@ % \LaTeX{} error is raised, and the code for both labels are % dropped from that hook until the conflict is resolved. % -% \item[\texttt{removes}] +% \item[\texttt{voids}] % % Code for \meta{label1} overwrites code for \meta{label2}. More % precisely, code for \meta{label2} is dropped for that @@ -470,10 +496,15 @@ % specified earlier. % % \end{itemize} +% There can only be a single relation between two labels for a +% given hook, +% i.e., a later \cs{DeclareHookrule} overwrites any previous +% delcaration. % % The \meta{hook} and \meta{label} can be specified using the % dot-syntax to denote the current package name. % See section~\ref{sec:default-label}. +% % \end{function} % % @@ -553,9 +584,9 @@ % A leading |.| is treated literally. % \end{function} % -% \begin{function}[EXP]{\IfHookExistTF} +% \begin{function}[EXP]{\IfHookExistsTF} % \begin{syntax} -% \cs{IfHookExistTF} \Arg{hook} \Arg{true code} \Arg{false code} +% \cs{IfHookExistsTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{hook} exists (if it was created with either % \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and @@ -590,10 +621,8 @@ % the code chunks (and their labels) added to it, % \item % any rules set up to order them, -% \fmi{currently this is missing the default rules that apply, -% guess that needs fixing} % \item -% the computed order (if already defined), +% the computed order in which the chunks are executed, % \item % any code executed on the next invocation only. % \end{itemize} @@ -605,9 +634,9 @@ % % \subsubsection{Debugging hook code} % -% \begin{function}{\DebugHookOn,\DebugHookOff} +% \begin{function}{\DebugHooksOn,\DebugHooksOff} % \begin{syntax} -% \cs{DebugHookOn} +% \cs{DebugHooksOn} % \end{syntax} % Turn the debugging of hook code on or off. This displays changes % made to the hook data structures. The output is rather coarse and @@ -706,8 +735,8 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % - - +% +% % \begin{function}{\hook_gremove_code:nn} % \begin{syntax} % \cs{hook_gremove_code:nn} \Arg{hook} \Arg{label} @@ -728,8 +757,8 @@ % dot-syntax to denote the current package name. % See section~\ref{sec:default-label}. % \end{function} - - +% +% % \begin{function}{\hook_gset_rule:nnnn} % \begin{syntax} % \cs{hook_gset_rule:nnnn} \Arg{hook} \Arg{label1} \Arg{relation} \Arg{label2} @@ -747,7 +776,7 @@ % % \begin{function}[pTF]{\hook_if_empty:n} % \begin{syntax} -% \cs{hook_if_empty:n} \Arg{hook} \Arg{true code} \Arg{false code} +% \cs{hook_if_empty:nTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{hook} is empty (\emph{i.e.}, no code was added to % it using either \cs{AddToHook} or \cs{AddToHookNext}), and @@ -760,7 +789,7 @@ % % \begin{function}[pTF]{\hook_if_exist:n} % \begin{syntax} -% \cs{hook_if_exist:n} \Arg{hook} \Arg{true code} \Arg{false code} +% \cs{hook_if_exist:nTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{hook} exists (if it was created with either % \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and @@ -938,6 +967,69 @@ % % % +% \subsection{Difference between \enquote{normal} and +% \enquote{one-time} hooks} +% +% When executing a hook a developer has the choice of using +% either \cs{UseHook} or \cs{UseOneTimeHook} (or their \pkg{expl3} +% equivalents \cs{hook_use:n} and \cs{hook_use_once:n}). +% This choice affects how \cs{AddToHook} is handled after the hook +% has been executed for the first time. +% +% With normal hooks adding code via \cs{AddToHook} means that the +% code chunk is added to the hook data structure and then used each time +% \cs{UseHook} is called. +% +% With one-time hooks it this is handled slightly differently: +% After \cs{UseOneTimeHook} has been called, any further attempts to +% add code to the hook via \cs{AddToHook} will simply execute the +% \meta{code} immediately. +% +% This has some consequences one needs to be aware of: +% \begin{itemize} +% \item +% +% If \meta{code} is added to a normal hook after the hook was +% executed and it is never executed again for one or the other +% reason, then this new \meta{code} will never be executed. +% +% \item +% +% In contrast if that happens with a one-time hook the \meta{code} is +% executed immediately. +% +% \end{itemize} +% In particular this means that construct such as +%\begin{quote} +% \cs{AddToHook}\verb={myhook}=\\ +% \phantom{\cs{AddToHook}}\verb={= \meta{code-1} +% \cs{AddToHook}\verb={myhook}=\Arg{code-2} +% \meta{code-3} \verb=}= +%\end{quote} +% works for one-time hooks\footnote{This is sometimes used with +% \cs{AtBeginDocument} which is why it is supported.} (all three +% code chunks are executed one after another), but it makes little +% sense with a normal hook, because with a normal hook the first time +% \verb=\UseHook{myhook}= is executed it would +% \begin{itemize} +% \item +% execute \meta{code-1}, +% \item +% then execute \verb=\AddToHook{myhook}{code-2}= which adds the +% code chunk \meta{code-2} to the hook for use on the next invocation, +% \item +% and finally execute \meta{code-3}. +% \end{itemize} +% The second time \cs{UseHook} is called it would execute the +% above and in addition \meta{code-2} as that was added as a code +% chunk to the hook in the meantime. So each time the hook is used +% another copy of \meta{code-2} is added and so that code chunk +% is executed $\meta{\# of invocations} -1$ times. +% +% +% +% +% % \subsection{Private \LaTeX{} kernel hooks} % % There are a few places where it is absolutely essential for @@ -1025,6 +1117,21 @@ % This hook is discussed in conjunction with the shipout hooks. % \end{function} % +% \bigskip +% +% The few hooks that existed previously in \LaTeXe{} used internally +% commands such as \cs{@begindocumenthook} and packages sometimes +% augemented them directly rather than working through +% \cs{AtBeginDocumement}. For that reason there is currently support +% for this, that is, if the system detects that such an internal +% legacy hook command contains code it adds it to the new hook +% system under the label \texttt{legacy} so that it doesn't get +% lost. +% +% However, over time the remaining cases of direct usage need +% updating because in one of the future release of \LaTeX{} we will +% turn this legacy support off, as it does unnecessary slow down +% the processing. % % % \subsection{\LaTeXe{} commands and environments augmented by @@ -1052,26 +1159,31 @@ % % \item[\hook{env/\meta{env}/end}] % -% This is executed as part of \cs{end} directly in front of the +% This hook is executed as part of \cs{end} directly in front of the % code specific to the end of the environment (e.g., the third % argument of \cs{newenvironment}). % % \item[\hook{env/\meta{env}/after}] % -% This is executed as part of \cs{end} after the +% This hook is executed as part of \cs{end} after the % code specific to the environment end and after the environment % group has ended. % Its scope is therefore not restricted by the environment. % -% This hook is implemented as a reversed hook so if two packages +% The hook is implemented as a reversed hook so if two packages % add code to \hook{env/\meta{env}/before} and to % \hook{env/\meta{env}/after} they can add surrounding % environments and the order of closing them happens in the % right sequence. % % \end{description} -% In contrast to other hooks these hooks do not need to be declared -% using \cs{NewHook}. +% Generic environment hooks are never one-time hooks even with +% environments that are supposed to appear only once in a +% document.\footnote{Thus if one adds code to such hooks after the +% environment has been processed, it will only be executed if the +% environment appears again and if that doesn't happen the code +% will never get executed.} In contrast to other hooks there is +% also no need to declare them using \cs{NewHook}. % % The hooks are only executed if \cs{begin}\Arg{env} and % \cs{end}\Arg{env} is used. If the environment code is executed @@ -1087,47 +1199,78 @@ % to add the outer hooks, etc. % % +% \begin{function}{\BeforeBeginEnvironment} +% \begin{syntax} +% \cs{BeforeBeginEnvironment} \oarg{label} \Arg{code} +% \end{syntax} +% This declaration adds to the \hook{env/\meta{env}/before} hook +% using by default the current package or class name as a label or +% \texttt{top-level} if used in the document directly. +% \end{function} +% +% \begin{function}{\AtBeginEnvironment} +% \begin{syntax} +% \cs{AtBeginEnvironment} \oarg{label} \Arg{code} +% \end{syntax} +% Like \cs{BeforeBeginEnvironment} but adds to the \hook{env/\meta{env}/begin} hook. +% \end{function} +% +% \begin{function}{\AtEndEnvironment} +% \begin{syntax} +% \cs{AtEndEnvironment} \oarg{label} \Arg{code} +% \end{syntax} +% Like \cs{BeforeBeginEnvironment} but adds to the \hook{env/\meta{env}/end} hook. +% \end{function} +% +% \begin{function}{\AfterEndEnvironment} +% \begin{syntax} +% \cs{AfterEndEnvironment} \oarg{label} \Arg{code} +% \end{syntax} +% Like \cs{BeforeBeginEnvironment} but adds to the \hook{env/\meta{env}/after} hook. +% \end{function} +% +% +% % % \subsubsection{Hooks provided by \cs{begin}\texttt{\{document\}}} % % Until 2020 \cs{begin}\texttt{\{document\}} offered exactly one -% hook that one had to fill using \cs{AtBeginDocument}. Experience -% has shown that this single hook in one place was not enough and -% as part of adding the general hook management system a number of -% additional hooks have been added at this point. The places for -% hooks have been chosen to provide the same support as offered by -% external packages, such as \pkg{etoolbox} and others that -% augmented \cs{document} to gain better control. -% -% Supported are now the following hooks: +% hook that one could add to using +% \cs{AtBeginDocument}. Experiences over the years have shown that +% this single hook in one place was not enough and as part of +% adding the general hook management system a number of additional +% hooks have been added at this point. The places for these hooks have +% been chosen to provide the same support as offered by external +% packages, such as \pkg{etoolbox} and others that augmented +% \cs{document} to gain better control. +% +% Supported are now the following hooks (all of them one-time hooks): % \begin{description} % -% \item[\hook{env/document/before}] % -% This is the generic environment hook executed effectively -% before \verb=\begin{document}= starts, i.e., one can think of -% it as a hook for code at the end of the preamble section. +% \item[\hook{begindocument/before}] % -% \item[\hook{env/document/begin}] +% This hook is executed at the very start of \cs{document}, one can +% think of it as a hook for code at the end of the preamble +% section and this is how it is used by \pkg{etoolbox}'s +% \cs{AtEndPreamble}. % -% This is the second generic environment hook that is executed -% after the environment has started its group. But given that for the -% \texttt{document} environment this group is canceled there is -% little difference to the previous one as the two are directly -% executed one after another (the only difference is that in this -% hook \cs{@currenvir} is now set to \texttt{document} but -% anybody adding to this hook would know that already). % % % \item[\hook{begindocument}] % -% This hook is added to by \cs{AtBeginDocument} and is executed +% This hook is added to when using \cs{AtBeginDocument} and it is executed % after the \texttt{.aux} file as be read in and most % initialization are done, so they can be altered and inspected by % the hook code. It is followed by a small number of further % initializations that shouldn't be altered and are therefore % coming later. % +% The hook should not be used to add material for typesetting as +% we are still in \LaTeX's initialization phase and not in the +% document body. If such material needs to be added to the document +% body use the next hook instead. +% % \item[\hook{begindocument/end}] % % This hook is executed at the end of the \cs{document} code in @@ -1135,6 +1278,10 @@ % command that follows it is \cs{ignorespaces}. % % \end{description} +% The generic hooks executed by \cs{begin} also exist, i.e., +% \hook{env/document/before} and \hook{env/document/begin}, but +% with this special environment it is better use the dedicated +% one-time hooks above. % % % @@ -1156,17 +1303,13 @@ % to add code in various places in a controlled way without the % need for overwriting or patching the core code. % -% Supported are now the following hooks: +% Supported are now the following hooks (all of them one-time hooks): % \begin{description} % -% \item[\hook{env/document/end}] The generic hook inside \cs{end}. -% % \item[\hook{enddocument}] - +% % The hook associated with \cs{AtEndDocument}. It is immediately -% called after the previous hook so there could be just -% one.\footnote{We could make \cs{AtEndDocument} just fill the -% \hook{env/document/end} but maybe that is a bit confusing.} +% called at the beginning of \cs{enddocument}. % % When this hook is executed there may be still unprocessed % material (e.g., floats on the deferlist) and the hook may add @@ -1230,6 +1373,16 @@ % page. See section~\ref{sec:shipout} for where to find the details. % % +% It is in also possible to use the generic \hook{env/document/end} +% hook which is execuded by \cs{end}, i.e., just in front of the +% first hook above. Note however that the other generic \cs{end} +% environment hook, i.e., \hook{env/document/after} will never get +% executed, because by that time \LaTeX{} has finished the document +% processing. +% +% +% +% % \subsubsection{Hooks provided \cs{shipout} operations} % \label{sec:shipout} % @@ -1239,7 +1392,7 @@ % \texttt{ltshipout-code.pdf}. % % -% \subsubsection{Hooks provided file loading operations} +% \subsubsection{Hooks provided by file loading operations} % % There are several hooks added to \LaTeX{}'s % process of loading file via its high-level interfaces such as @@ -1248,17 +1401,87 @@ % \texttt{ltfilehook-code.pdf}. % % - +% \subsubsection{Hooks provided in NFSS commands} +% +% In languages that need to support for more than one script in +% parallel (and thus several sets of fonts), e.g., Latin and +% Japanese fonts, NFSS font commands, such as \cs{sffamily}, need +% to switch both the Latin family to ``Sans Serif'' and in addition +% alter a second set of fonts. +% +% To support this several NFSS have hooks in which such support can +% be added. +% \begin{description} +% +% \item[\hook{rmfamily}] +% +% After \cs{rmfamily} has done its initial checks and prepared a +% any font series update this hook is executed and only +% afterwards \cs{selectfont}. +% +% \item[\hook{sffamily}] +% +% Like the \hook{rmfamily} hook but for the \cs{sffamily} command. +% +% \item[\hook{ttfamily}] +% +% Like the \hook{rmfamily} hook but for the \cs{ttfamily} command. +% +% \item[\hook{normalfont}] +% +% The \cs{normalfont} command resets font encoding family series +% and shape to their document defaults. It then executes this +% hook and finally calls \cs{selectfont}. +% +% \item[\hook{expand@font@defaults}] +% +% The internal \cs{expand@font@defaults} command expands and +% saves the current defaults for the meta families (rm/sf/tt) and +% the meta series (bf/md). If the NFSS machinery has been +% augmented, e.g., for Chinese or Japanese fonts, then further +% defaults may need to be set at this point. This can be done in +% this hook which is executed at the end of this macro. +% +% \item[\hook{bfseries/defaults}, \hook{bfseries}] +% +% If the \cs{bfdefault} was explicitly changed by the user its +% new value is used to set the bf series defaults for the meta +% families (rm/sf/tt) when \cs{bfseries} is called. In the +% \hook{bfseries/defaults} hook further adjustments can be made +% in this case. This hook is only executed if such a change is +% detected. In contrast the \hook{bfseries} hook is always +% executed just before \cs{selectfont} is called to change to the +% new series. +% +% +% \item[\hook{mdseries/defaults}, \hook{mdseries}] +% +% These two hooks are like the previous ones but used in +% \cs{mdseries} command. +% +% \end{description} +% +% % \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } % % % \section{The Implementation} +% +% +% \subsection{Loading further extensions} +% % \begin{macrocode} %<@@=hook> % \end{macrocode} % +% +% At the moment the whole module rolls back in one go, but if we +% make any modifications in later releases this will then need +% splitting. % \begin{macrocode} -%<*2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\NewHook}{The hook management}% % \end{macrocode} % % \begin{macrocode} @@ -1300,7 +1523,7 @@ % \end{macro} % \end{macro} % \end{macro} - +% % % % \subsection{Borrowing from internals of other kernel modules} @@ -1315,6 +1538,13 @@ % % \subsection{Declarations} % +% \begin{macro}{\l_@@_tmpa_bool} +% Scratch boolean used throughout the package. +% \begin{macrocode} +\bool_new:N \l_@@_tmpa_bool +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\l_@@_return_tl,\l_@@_tmpa_tl,\l_@@_tmpb_tl} % Scratch variables used throughout the package. % \begin{macrocode} @@ -1333,7 +1563,7 @@ % \end{macro} % % \begin{macro}{\g_@@_removal_list_prop} -% A property list to hold delayed removals. +% A token list to hold delayed removals. % \begin{macrocode} \tl_new:N \g_@@_removal_list_tl % \end{macrocode} @@ -1346,11 +1576,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\g_@@_code_temp_prop} -% A property list to temporarily save the original one so that it -% isn't permanently changed during sorting. +% \begin{macro}{\l_@@_work_prop} +% A property list holding a copy of the +% \cs[no-index]{g_@@_\meta{hook}_code_prop} of the hook being sorted +% to work on, so that changes don't act destructively on the hook data +% structure. % \begin{macrocode} -\prop_new:N \g_@@_code_temp_prop +\prop_new:N \l_@@_work_prop % \end{macrocode} % \end{macro} % @@ -1387,8 +1619,7 @@ % % \subsection{Providing new hooks} % -% \begin{macro}{\g_@@_..._code_prop,\g_@@_..._rules_prop, -% \g_@@_..._code_tl,\g_@@_..._next_code_tl} +% \begin{macro}{\g_@@_..._code_prop,\g_@@_..._code_tl,\g_@@_..._code_next_tl} % % Hooks have a \meta{name} and for each hook we have to provide a number of % data structures. These are @@ -1398,27 +1629,36 @@ % package names that add code to the hook, but it is possible % for packages to define other keys. % -% \item[\cs{g_@@_\meta{name}_rules_prop}] A property listing holding -% relation info how the code chunks should be ordered within a -% hook. This is used for debugging only. The actual rule for a -% \meta{hook} is stored in a separate token lists named -% \cs[no-index]{g_@@_\meta{hook}_rule_\meta{label1}\string|\meta{label2}_tl} -% for a pair of labels. +% \item[{\cs[no-index]{g_@@_\meta{name}_rule_\meta{label1}\string|\meta{label2}_tl}}] +% A token list holding the relation between \meta{label1} and +% \meta{label2} in the \meta{name}. The \meta{labels} are lexically +% (reverse) sorted to ensure that two labels always point to the same +% token list. For global rules, the \meta{name} is |??|. % % \item[\cs{g_@@_\meta{name}_code_tl}] The code that is actually executed % when the hook is called in the document is stored in this token % list. It is constructed from the code chunks applying the % information. % -% \item[\cs{g_@@_\meta{name}_next_code_tl}] Finally there is extra code +% \item[\cs{g_@@_\meta{name}_reversed_tl}] Some hooks are +% \enquote{reversed}. This token list stores a |-| for such hook +% so that it can be identified. The |-| character is used because +% $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed +% ones. +% +% \item[\cs{g_@@_\meta{name}_code_next_tl}] Finally there is extra code % (normally empty) that is used on the next invocation of the hook % (and then deleted). This can be used to define some special -% behavior for a single occasion from within the document. +% behavior for a single occasion from within the document. This token +% list is called |code_next| rather than |next_code| because otherwise +% a hook called \meta{name}|_next| would have its code-token list +% named \cs[no-index]{g_@@_\meta{name}_code_next_tl}, which would +% clash with the next code-token list of a hook called \meta{name}. % % \end{description} % \end{macro} - - +% +% % % % \begin{macro}{\hook_new:n} @@ -1437,7 +1677,7 @@ % already exists we complain. % \begin{macrocode} \hook_if_exist:nTF {#1} - { \ErrorHookExists } + { \msg_error:nnn { hooks } { exists } {#1} } % \end{macrocode} % Otherwise we add the hook name to the list of all hooks and % allocate the necessary data structures for the new hook. @@ -1465,15 +1705,24 @@ \tl_new:c { g_@@_#1_reversed_tl } % \end{macrocode} % The above is all in L3 convention, but we also provide an -% interface to legacy \LaTeXe{} for use in the current kernel. This -% is done in a separate macro. -% \begin{macrocode} - \@@_provide_legacy_interface:n {#1} +% interface to legacy \LaTeXe{} hooks of the form \cs{@...hook}, +% e.g., \cs{@begindocumenthook}. +% there have been a few of them and they have been added to +% using \cs{g@addto@macro}. If there exists such a macro matching +% the name of the new hook, i.e., +% \verb+\@+\meta{hook-name}\texttt{hook} and it is not empty then +% we add its contents as a code chunk under the label \texttt{legacy}. +% \begin{quote} +% \textbf{Warning: this support will vanish in future releases!} +% \end{quote} +% +% \begin{macrocode} + \@@_include_legacy_code_chunk:n {#1} } } % \end{macrocode} % \end{macro} - +% % % % \begin{macro}{\@@_declare:n} @@ -1488,15 +1737,14 @@ \@@_if_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } - \tl_new:c { g_@@_#1_next_code_tl } - \prop_new:c { g_@@_#1_rules_prop } % only for debugging + \tl_new:c { g_@@_#1_code_next_tl } } } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\hook_new_reversed:n} % % Declare a new hook. The default ordering of code chunks is @@ -1504,11 +1752,16 @@ % \begin{macrocode} \cs_new_protected:Npn \hook_new_reversed:n #1 { \hook_new:n {#1} +% \end{macrocode} +% If the hook already exists the above will generate an error +% message, so the next line should be executed (but it is --- too +% bad). +% \begin{macrocode} \tl_gset:cn { g_@@_#1_reversed_tl } { - } } % \end{macrocode} % \end{macro} - +% % \begin{macro}{\hook_new_pair:nn} % A shorthand for declaring a normal and a (matching) reversed hook in one go. % \begin{macrocode} @@ -1517,23 +1770,21 @@ } % \end{macrocode} % \end{macro} - - -% \begin{macro}{\@@_provide_legacy_interface:n} +% +% +% \begin{macro}{\@@_include_legacy_code_chunk:n} % The \LaTeX{} legacy concept for hooks uses with hooks the % following naming scheme in the code: \cs{@...hook}. % -% We follow this convention and insert the hook code using this -% naming scheme in \LaTeXe{}. At least as long as this code is in a -% package, some such hooks are already filled with data when we move -% them over to the new scheme. We therefore insert already existing -% code under the label \texttt{legacy} into the hook management -% machinery and then replace the \cs{@...hook} with its counterpart -% which is \cs{g_@@_\#1_code_tl}.\footnote{This means one extra -% unnecessary expansion on each invocation in the document but -% keeps the \LaTeXe{} and the L3 coding side properly separated.} +% If this macro is not empty we add it under the label +% \texttt{legacy} to the current hook and then empty it globally. +% This way packages or classes directly manipulating commands such +% as \cs{@begindocumenthook} still get their hook data added. +% \begin{quote} +% \textbf{Warning: this support will vanish in future releases!} +% \end{quote} % \begin{macrocode} -\cs_new_protected:Npn \@@_provide_legacy_interface:n #1 +\cs_new_protected:Npn \@@_include_legacy_code_chunk:n #1 { % \end{macrocode} % If the \pkg{expl3} code is run with checking on then assigning or @@ -1542,32 +1793,34 @@ % debugging explicitly suspended. % \begin{macrocode} \debug_suspend: +% \end{macrocode} +% If the macro doesn't exist (which is the usual case) then nothing +% needs to be done. +% \begin{macrocode} \tl_if_exist:cT { @#1hook } % \end{macrocode} -% Of course if the hook exists but is still empty, there is no need -% to add anything under \texttt{legacy} or the current package name. +% Of course if the legacy hook exists but is empty, there is no need +% to add anything under \texttt{legacy} the legacy label. % \begin{macrocode} { \tl_if_empty:cF { @#1hook } { - \@@_gput_code:nxv {#1} - { \@@_parse_label_default:Vn \c_novalue_tl { legacy } } - { @#1hook } - } - } + \exp_args:Nnnv \@@_hook_gput_code_do:nnn {#1} + { legacy } { @#1hook } % \end{macrocode} -% We need a global definition in case the declaration is done -% inside a group (which happens below at the end of the file). -% This is another reason why need to suspend checking, otherwise -% \cs{tl_gset:co} would complain about \cs{@...hook} not starting -% with \cs{g_}. +% Once added to the hook, we need to clear it otherwise it might +% get added again later if the hook data gets updated. % \begin{macrocode} - \tl_gset:co{@#1hook}{\cs:w g_@@_#1_code_tl\cs_end:} + \tl_gclear:c { @#1hook } + } + } \debug_resume: } % \end{macrocode} % \end{macro} % +% +% % \subsection{Parsing a label} % % \begin{macro}[EXP]{\@@_parse_label_default:nn,\@@_parse_label_default:Vn} @@ -1647,10 +1900,10 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \begin{macro}{\hook_gput_code:nnn} % \begin{macro}{\@@_gput_code:nnn,\@@_gput_code:nxv,\@@_hook_gput_code_do:nnn} % @@ -1667,13 +1920,19 @@ \cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3 { % \end{macrocode} -% First we check if the hook exists. +% First check if the current \meta{hook}/\meta{label} pair was marked +% for removal, in which case \cs{@@_unmark_removal:nn} is used to +% remove that mark (once). This may happen when a package removes +% code from another package which was not yet loaded: the removal +% order is stored, and at this stage it is executed by not adding to +% the hook. % \begin{macrocode} \@@_if_marked_removal:nnTF {#1} {#2} { \@@_unmark_removal:nn {#1} {#2} } { % \end{macrocode} -% First we check if the hook exists. +% If no removal is queued, we are free to add. Start by checking if +% the hook exists. % \begin{macrocode} \hook_if_exist:nTF {#1} % \end{macrocode} @@ -1691,7 +1950,10 @@ \@@_update_hook_code:n {#1} } % \end{macrocode} -% +% +% If the hook does not exist, however, before giving up try to +% declare it as a generic hook, if its name matches one of the valid +% patterns. % \begin{macrocode} { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } } @@ -1699,20 +1961,21 @@ \cs_generate_variant:Nn \@@_gput_code:nnn { nxv } % \end{macrocode} % -% This macro will unconditionally add a chunk of code to the given hook. +% This macro will unconditionally add a chunk of code to the given hook. % \begin{macrocode} \cs_new_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 { -% However, first some debugging info if debugging is enabled: +% \end{macrocode} +% However, first some debugging info if debugging is enabled: % \begin{macrocode} \@@_debug:n{\iow_term:x{****~ Add~ to~ \hook_if_exist:nF {#1} { undeclared~ } hook~ #1~ (#2) \on@line\space <-~ \tl_to_str:n{#3}} } % \end{macrocode} -% Then try to get the code chunk labeled \verb=#2= from the hook. -% If there's code already there, then append \verb=#3= to that, -% otherwise just put \verb=#3=. +% Then try to get the code chunk labeled \verb=#2= from the hook. +% If there's code already there, then append \verb=#3= to that, +% otherwise just put \verb=#3=. % \begin{macrocode} \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl { @@ -1786,7 +2049,7 @@ \@@_if_file_hook:wTF #1 / / \s_@@_mark { \exp_args:Ne \@@_try_declaring_generic_hook_split:nNNnn - { \exp_args:Ne \@@_file_hook_normalise:n {#1} } + { \exp_args:Ne \@@_file_hook_normalize:n {#1} } } { \@@_try_declaring_generic_hook_split:nNNnn {#1} } } @@ -1867,16 +2130,16 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_file_hook_normalise:n} +% \begin{macro}[EXP]{\@@_file_hook_normalize:n} % \begin{macro}[EXP]{\@@_strip_double_slash:n,\@@_strip_double_slash:w} % When a file-specific hook is found, before being declared it is -% lightly normalized by \cs{@@_file_hook_normalise:n}. The current +% lightly normalized by \cs{@@_file_hook_normalize:n}. The current % implementation just replaces two consecutive slashes (|//|) by a % single one, to cope with simple cases where the user did something % like \verb|\def\input@path{{./mypath/}}|, in which case a hook would % have to be \verb|\AddToHook{file/after/./mypath//file.tex}|. % \begin{macrocode} -\cs_new:Npn \@@_file_hook_normalise:n #1 +\cs_new:Npn \@@_file_hook_normalize:n #1 { \@@_strip_double_slash:n {#1} } \cs_new:Npn \@@_strip_double_slash:n #1 { \@@_strip_double_slash:w #1 // \s_@@_mark } @@ -1889,13 +2152,9 @@ % \end{macrocode} % \end{macro} % \end{macro} - - - - - +% % \begin{macro}{\c_@@_generics_prop} -% Clist holding the generic names. We don't provide any user +% Property list holding the generic names. We don't provide any user % interface to this as this is meant to be static. % \begin{description} % \item[\texttt{env}] @@ -1920,17 +2179,7 @@ \prop_const_from_keyval:Nn \c_@@_generics_file_prop {before=,after=} % \end{macrocode} % \end{macro} - - -% \begin{macro}{\@@_update_hook_code:n} -% Before \verb=\begin{document}= this does nothing, in the body it -% reinitializes the hook code using the altered data. -% \begin{macrocode} -\cs_new_eq:NN \@@_update_hook_code:n \use_none:n -% \end{macrocode} -% \end{macro} - - +% % \begin{macro}{\hook_gremove_code:nn} % \begin{macro}{\@@_gremove_code:nn} % @@ -1958,10 +2207,7 @@ % \begin{macrocode} { \str_if_eq:nnTF {#2} {*} - { - \prop_gclear:c { g_@@_#1_code_prop } - \clist_gclear:c { g_@@_#1_labels_clist } % for debugging only - } + { \prop_gclear:c { g_@@_#1_code_prop } } { % \end{macrocode} % Check if the label being removed exists in the code pool. If it does, @@ -1979,6 +2225,12 @@ \hook_if_exist:nT {#1} { \@@_update_hook_code:n {#1} } } +% \end{macrocode} +% +% If the code pool for this hook doesn't exist it means that nothing +% tried to add to it before, so we just queue this removal order for +% later. +% \begin{macrocode} { \@@_mark_removal:nn {#1} {#2} } } % \end{macrocode} @@ -1986,26 +2238,18 @@ % \begin{macro}{\@@_gremove_code_do:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_gremove_code_do:nn #1 #2 - { - \prop_gremove:cn { g_@@_#1_code_prop } {#2} -% \end{macrocode} -% Removing the dropped label from \verb=\g_@@_#1_labels_clist= is -% rather tricky, because that clists holds the labels as strings -% (i.e., not ordinary text which is what we have in \verb=#2=). -% \begin{macrocode} - \exp_args:Nco \clist_gremove_all:Nn - { g_@@_#1_labels_clist } { \tl_to_str:n {#2} } % for debugging only - } + { \prop_gremove:cn { g_@@_#1_code_prop } {#2} } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} - - % % \begin{macro}{\@@_mark_removal:nn} % Marks \meta{label} (\verb=#2=) to be removed from \meta{hook} -% (\verb=#1=). +% (\verb=#1=). The number of removals should be fairly small, and +% \cs{tl_gremove_once:Nx} is fairly efficient even for longer token +% lists, so we use a single global token list, rather than one for +% each hook. % \begin{macrocode} \cs_new_protected:Npn \@@_mark_removal:nn #1 #2 { @@ -2044,29 +2288,24 @@ % % \begin{macro}[rEXP]{\@@_removal_tl:nn} % Builds a token list with \verb=#1= and \verb=#2= which can only be -% matched by \verb=#1= and \verb=#2=. +% matched by \verb=#1= and \verb=#2=. The |&|$_4$ anchors a removal, +% so that \verb=#1= can't be mistaken by \verb=#2= and vice versa, and +% the two |$|$_3$ delimit the two arguments % \begin{macrocode} \cs_new:Npn \@@_removal_tl:nn #1 #2 { & \tl_to_str:n {#2} $ \tl_to_str:n {#1} $ } % \end{macrocode} % \end{macro} - - - - -% % % % \begin{macro}{ -% \g_@@_??_rules_prop, % \g_@@_??_code_prop, % \g_@@_??_code_tl, % \g_@@_??_reversed_tl, % } % -% Default rules applying to all hooks are stored in this property -% list. Initially it simply used an empty ``label'' name (not two -% question marks). This was a bit unfortunate, because then +% Initially these variables simply used an empty ``label'' name (not +% two question marks). This was a bit unfortunate, because then % \texttt{l3doc} complains about \verb=__= in the middle of a % command name when trying to typeset the documentation. However % using a ``normal'' name such as \texttt{default} has the @@ -2079,7 +2318,6 @@ % \cs{g_@@_??_code_tl} isn't used, but it has to be defined to trick % the code into thinking that \verb=??= is actually a hook. % \begin{macrocode} -\prop_new:c {g_@@_??_rules_prop} \prop_new:c {g_@@_??_code_prop} \prop_new:c {g_@@_??_code_tl} % \end{macrocode} @@ -2093,53 +2331,6 @@ \tl_new:c {g_@@_??_reversed_tl} % \end{macrocode} % \end{macro} - - - -% \begin{macro}{\@@_debug_gset_rule:nnnn} -% -% \fmi{this needs cleanup and docu correction!} -% -% With -% \cs{@@_debug_gset_rule:nnnn}\Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} -% a relation is defined between the two code labels for the given -% \meta{hook}. The special hook \texttt{??} stands for \emph{any} -% hook describing a default rule. -% \begin{macrocode} -\cs_new_protected:Npn \@@_debug_gset_rule:nnnn #1#2#3#4 - { -% \end{macrocode} -% If so we drop any existing rules with the two labels (in case -% there are any). -% \begin{macrocode} - \prop_gremove:cn{g_@@_#1_rules_prop}{#2|#4} - \prop_gremove:cn{g_@@_#1_rules_prop}{#4|#2} -% \end{macrocode} -% Then we add the new one (normalizing the input a bit, e.g., we -% always use \texttt{before} and not \texttt{after} and -% instead reorder the labels): -% \begin{macrocode} - \str_case_e:nnF {#3} - { - {before} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{<} } - {after} { \prop_gput:cnn {g_@@_#1_rules_prop}{#4|#2}{<} } -% \end{macrocode} -% More special rule types \ldots -% \begin{macrocode} - {incompatible-error} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{xE} } - {incompatible-warning} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{xW} } - {removes} { \prop_gput:cnn {g_@@_#1_rules_prop}{#2|#4}{->} } -% \end{macrocode} -% Undo a setting: -% \begin{macrocode} - {unrelated}{ \prop_gremove:cn {g_@@_#1_rules_prop}{#2|#4} - \prop_gremove:cn {g_@@_#1_rules_prop}{#4|#2} } - } - { \ERRORunknownrule } - } -% \end{macrocode} -% \end{macro} -% % % \subsection{Setting rules for hooks code} % @@ -2188,9 +2379,9 @@ {#1} {#2} {#4} \@@_update_hook_code:n {#1} } - { \ERRORunknownrule } + { \msg_error:nnnnnn { hooks } { unknown-rule } + {#1} {#2} {#3} {#4} } \debug_resume: - \@@_debug_gset_rule:nnnn {#1} {#2} {#3} {#4} % for debugging } % \end{macrocode} % \end{macro} @@ -2200,10 +2391,10 @@ % \@@_rule_<_gset:nnn, \@@_rule_>_gset:nnn} % Then we add the new rule. We need to normalize the rules here to % allow for faster processing later. Given a pair of labels -% $l_A$ and $l_B$, the rule $l_A>l_B$ is the same as $l_B<l_A$\fmi{} -% said differently. But normalizing the -% forms of the rule to a single representation, say, $l_B<l_A$, then -% the time spent looking for the rules later is considerably reduced. +% $l_A$ and $l_B$, the rule $l_A>l_B$ is the same as $l_B<l_A$ +% only presented differently. But by normalizing the +% forms of the rule to a single representation, say, $l_B<l_A$, reduces +% the time spent looking for the rules later considerably. % % Here we do that normalization by using \cs[no-index]{(pdf)strcmp} to % lexically sort labels $l_A$ and $l_B$ to a fixed order. This order @@ -2232,11 +2423,11 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_rule_removes_gset:nnn} +% \begin{macro}{\@@_rule_voids_gset:nnn} % This rule removes (clears, actually) the code from label |#3| if % label |#2| is in the hook |#1|. % \begin{macrocode} -\cs_new_protected:Npn \@@_rule_removes_gset:nnn #1#2#3 +\cs_new_protected:Npn \@@_rule_voids_gset:nnn #1#2#3 { \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { -> } { <- } } @@ -2299,7 +2490,7 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_if_label_case:nnnnn} -% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNNn} +% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNn} % (once with \cs{str_if_eq:nn} and again with \cs{@@_label_ordered:nn}), % we use a three-way branching macro that will compare |#1| and |#2| % and expand to \cs{use_i:nnn} if they are equal, \cs{use_ii:nn} if @@ -2314,8 +2505,15 @@ } % \end{macrocode} % \end{macro} - - +% +% \begin{macro}{\@@_update_hook_code:n} +% Before \verb=\begin{document}= this does nothing, in the body it +% reinitializes the hook code using the altered data. +% \begin{macrocode} +\cs_new_eq:NN \@@_update_hook_code:n \use_none:n +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@@_initialize_all:} % Initialize all known hooks (at \verb=\begin{document}=), i.e., % update the fast execution token lists to hold the necessary code @@ -2349,7 +2547,6 @@ \exp_not:v {g_@@_##1_code_tl}~ } } } -% % \end{macrocode} % After all hooks are initialized we change the ``use'' to just % call the hook code and not initialize it (as it was done in the @@ -2360,9 +2557,9 @@ } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\@@_initialize_hook_code:n} % Initializing or reinitializing the fast execution hook code. In % the preamble this is selectively done in case a hook gets used @@ -2373,12 +2570,20 @@ \@@_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~ '#1' \on@line :^^J} } % \end{macrocode} -% This does the sorting and the updates. If there aren't any code +% This does the sorting and the updates. +% First thing we do is to check if a legacy hook macro exists and +% if so we add it to the hook under the label \texttt{legacy}. This +% might make the hook non-empty so we have to do this before +% the then following test. +% \begin{macrocode} + \@@_include_legacy_code_chunk:n {#1} +% \end{macrocode} +% If there aren't any code % chunks for the current hook, there is no point in even starting % the sorting routine so we make a quick test for that and in that % case just update \cs{g_@@_\meta{hook}_code_tl} to hold the next % code. If there are code chunks we call -% \cs{@@_initialize_single:NNNNn} and pass to it ready made csnames +% \cs{@@_initialize_single:NNNn} and pass to it ready made csnames % as they are needed several times inside. This way we save a bit % on processing time if we do that up front. % \begin{macrocode} @@ -2386,7 +2591,7 @@ { \prop_if_empty:cTF {g_@@_#1_code_prop} { \tl_gset:co {g_@@_#1_code_tl} - {\cs:w g_@@_#1_next_code_tl \cs_end: } } + {\cs:w g_@@_#1_code_next_tl \cs_end: } } { % \end{macrocode} % By default the algorithm sorts the code chunks and then saves the @@ -2403,38 +2608,39 @@ \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } % \end{macrocode} % -% When sorting, some relations (namely \verb|->| \verb|<-|) need to +% When sorting, some relations (namely \verb|voids|) need to % act destructively on the code property lists to remove code that -% shouldn't appear in the sorted hook token list. +% shouldn't appear in the sorted hook token list, so we temporarily +% save the old code property list so that it can be restored later. % \begin{macrocode} - \prop_gset_eq:Nc \g_@@_code_temp_prop { g_@@_#1_code_prop } - \@@_initialize_single:ccccn - { g_@@_#1_code_prop } { g_@@_#1_code_tl } - { g_@@_#1_next_code_tl } { g_@@_#1_labels_clist } - {#1} - \prop_gset_eq:cN { g_@@_#1_code_prop } \g_@@_code_temp_prop + \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } + \@@_initialize_single:cccn + { g_@@_#1_code_tl } { g_@@_#1_code_next_tl } + { g_@@_#1_labels_clist } {#1} % \end{macrocode} % For debug display we want to keep track of those hooks that % actually got code added to them, so we record that in plist. We % use a plist to ensure that we record each hook name only once, -% i.e., we are only interested in storing the keys and the value is arbitrary +% i.e., we are only interested in storing the keys and the value is +% arbitrary. % \begin{macrocode} - \@@_debug:n{ \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1}{} } + \@@_debug:n{ \exp_args:NNx \prop_gput:Nnn + \g_@@_used_prop {#1}{} } } } } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\g_@@_used_prop} % All hooks that receive code (for use in debugging display). % \begin{macrocode} \prop_new:N\g_@@_used_prop % \end{macrocode} % \end{macro} - - +% +% % % \begin{macro}[EXP]{\@@_tl_csname:n,\@@_seq_csname:n} % It is faster to pass a single token and expand it when necessary @@ -2446,7 +2652,7 @@ % \end{macrocode} % \end{macro} % - +% % % % \begin{macro}{\l_@@_labels_seq,\l_@@_labels_int,\l_@@_front_tl, @@ -2486,11 +2692,11 @@ % % \end{itemize} % \end{macro} - - -% \begin{macro}{\@@_initialize_single:NNNNn,\@@_initialize_single:ccccn} % -% \cs{@@_initialize_single:NNNNn} implements the sorting of the code +% +% \begin{macro}{\@@_initialize_single:NNNn,\@@_initialize_single:cccn} +% +% \cs{@@_initialize_single:NNNn} implements the sorting of the code % chunks for a hook and saves the result in the token list for fast % execution (\verb=#3=). The arguments are \meta{hook-code-plist}, % \meta{hook-code-tl}, \meta{hook-next-code-tl}, @@ -2506,7 +2712,7 @@ % the moment: a label can't be equal to the number 0! \fmi{Needs % checking for, just in case} % \begin{macrocode} -\cs_new_protected:Npn \@@_initialize_single:NNNNn #1#2#3#4#5 { +\cs_new_protected:Npn \@@_initialize_single:NNNn #1#2#3#4 { % \end{macrocode} % % \begin{macrocode} @@ -2520,7 +2726,7 @@ % % Store the name of the hook: % \begin{macrocode} - \tl_set:Nn \l_@@_cur_hook_tl {#5} + \tl_set:Nn \l_@@_cur_hook_tl {#4} % \end{macrocode} % % We loop over the property list holding the code and record all @@ -2530,20 +2736,18 @@ % to ensure that labels named |front|, |rear|, |labels|, or |return| % don't interact with our code. % \begin{macrocode} - \prop_map_inline:Nn #1 + \prop_map_inline:Nn \l_@@_work_prop { \int_incr:N \l_@@_labels_int \seq_put_right:Nn \l_@@_labels_seq {##1} - \tl_set:cn { \@@_tl_csname:n {##1} }{0} % the counter k for number of - % j before k rules - \seq_clear_new:c { \@@_seq_csname:n {##1} } % sequence of successors to k - % i.e., k before j rules (stores - % the names of the j's) + \tl_set:cn { \@@_tl_csname:n {##1} }{0} + \seq_clear_new:c { \@@_seq_csname:n {##1} } } % \end{macrocode} % Steps T2 and T3: Sort the relevant rules into the data structure\ldots % -% This loop constitutes a square matrix of the labels in |#1| in the +% This loop constitutes a square matrix of the labels in +% \cs{l_@@_work_prop} in the % vertical and the horizontal directions. However since the rule % $l_A\meta{rel}l_B$ is the same as $l_B\meta{rel}^{-1}l_A$ we can cut % the loop short at the diagonal of the matrix (\emph{i.e.}, when @@ -2554,29 +2758,29 @@ % \cs{@@_apply_label_pair:nnn}, which takes the properly-ordered pair % of labels as argument. % \begin{macrocode} - \prop_map_inline:Nn #1 + \prop_map_inline:Nn \l_@@_work_prop { - \prop_map_inline:Nn #1 + \prop_map_inline:Nn \l_@@_work_prop { \@@_if_label_case:nnnnn {##1} {####1} { \prop_map_break: } { \@@_apply_label_pair:nnn {##1} {####1} } { \@@_apply_label_pair:nnn {####1} {##1} } - {#5} + {#4} } } % \end{macrocode} % Take a breath and take a look at the data structures that have % been set up: % \begin{macrocode} - \@@_debug:n { \@@_debug_label_data:N #1 } + \@@_debug:n { \@@_debug_label_data:N \l_@@_work_prop } % \end{macrocode} % % % Step T4: % \begin{macrocode} \tl_set:Nn \l_@@_rear_tl { 0 } - \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } % really {l_@@_label_ \l_@@_rear_tl _tl} + \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } \seq_map_inline:Nn \l_@@_labels_seq { \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 @@ -2589,8 +2793,8 @@ % \end{macrocode} % % \begin{macrocode} - \tl_gclear:N #2 - \clist_gclear:N #4 + \tl_gclear:N #1 + \clist_gclear:N #3 % \end{macrocode} % % The whole loop combines steps T5--T7: @@ -2601,12 +2805,12 @@ % This part is step T5: % \begin{macrocode} \int_decr:N \l_@@_labels_int - \prop_get:NVN #1 \l_@@_front_tl \l_@@_return_tl - \@@_tl_gput:NV #2 \l_@@_return_tl + \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl + \@@_tl_gput:NV #1 \l_@@_return_tl % \end{macrocode} % % \begin{macrocode} - \@@_clist_gput:NV #4 \l_@@_front_tl + \@@_clist_gput:NV #3 \l_@@_front_tl \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } % \end{macrocode} % @@ -2617,8 +2821,11 @@ \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } } { \tl_set:cx { \@@_tl_csname:n {##1} } - { \int_eval:n { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } } - \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 + { \int_eval:n + { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } + } + \int_compare:nNnT + { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 { \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} \tl_set:Nn \l_@@_rear_tl {##1} @@ -2627,7 +2834,8 @@ % \end{macrocode} % and step T7: % \begin{macrocode} - \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { \l_@@_front_tl } } + \tl_set_eq:Nc \l_@@_front_tl + { \@@_tl_csname:n { \l_@@_front_tl } } % \end{macrocode} % % This is step T8: If we haven't moved the code for all labels @@ -2644,15 +2852,15 @@ % This is not really the information one needs in the error case % but will do for now \ldots \fmi{fix} % \begin{macrocode} - \@@_debug_label_data:N #1 + \@@_debug_label_data:N \l_@@_work_prop \iow_term:x{====================} } % \end{macrocode} -% After we have added all hook code to \verb=#2= we finish it off +% After we have added all hook code to \verb=#1= we finish it off % with adding extra code for a one time execution. That is stored -% in \verb=#3= but is normally empty. +% in \verb=#2= but is normally empty. % \begin{macrocode} - \tl_gput_right:Nn #2 {#3} + \tl_gput_right:Nn #1 {#2} % \end{macrocode} % % \begin{macrocode} @@ -2661,12 +2869,12 @@ % \end{macrocode} % % \begin{macrocode} -\cs_generate_variant:Nn \@@_initialize_single:NNNNn {cccc} +\cs_generate_variant:Nn \@@_initialize_single:NNNn {ccc} % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\@@_tl_gput:NV,\@@_clist_gput:NV} % These append either on the right (normal hook) or on the left % (reversed hook). This is setup up in @@ -2676,8 +2884,8 @@ \cs_new:Npn \@@_clist_gput:NV {\ERROR} % \end{macrocode} % \end{macro} - - +% +% % % \begin{macro}{\@@_apply_label_pair:nnn,\@@_label_if_exist_apply:nnnF} % @@ -2732,10 +2940,10 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \begin{macro}{\@@_apply_rule:nnn} % This is the code executed in steps T2 and T3 while looping through % the matrix This is part of step T3. We are about to apply the next @@ -2798,13 +3006,15 @@ % % \begin{macro}{\@@_apply_rule_->:nnn,\@@_apply_rule_<-:nnn} % If we see \texttt{\detokenize{->}} we have to drop code for label -% \verb=#3= and carry on. We could do a little better and trop +% \verb=#3= and carry on. We could do a little better and drop % everything for that label since it doesn't matter where we sort % in the empty code. However that would complicate the algorithm a -% lot with little gain. So we still unnecessarily try to sort it in -% and depending on the rules that might result in a loop that is -% otherwise resolved. If that turns out to be a real issue, we can -% improve the code. +% lot with little gain.\footnote{This also hase the advantage that +% the result of the sorting doesn't change which might otherwise +% (for unrelated chunks) if we aren't careful.} So we still +% unnecessarily try to sort it in and depending on the rules that +% might result in a loop that is otherwise resolved. If that turns +% out to be a real issue, we can improve the code. % % Here the code is removed from \cs{l_@@_cur_hook_tl} rather than % \verb=#3= because the latter may be \verb=??=, and the default @@ -2817,9 +3027,10 @@ { \@@_msg_pair_found:nnn {#1} {#2} {#3} \iow_term:x{--->~ Drop~ '#2'~ code~ from~ - \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ because~ of~ '#1' } + \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ + because~ of~ '#1' } } - \prop_gput:cnn { g_@@_ \l_@@_cur_hook_tl _code_prop } {#2} { } + \prop_put:Nnn \l_@@_work_prop {#2} { } } \cs_new_protected:cpn { @@_apply_rule_<-:nnn } #1#2#3 { @@ -2827,13 +3038,14 @@ { \@@_msg_pair_found:nnn {#1} {#2} {#3} \iow_term:x{--->~ Drop~ '#1'~ code~ from~ - \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ because~ of~ '#2' } + \iow_char:N \\ g_@@_ \l_@@_cur_hook_tl _code_prop ~ + because~ of~ '#2' } } - \prop_gput:cnn { g_@@_ \l_@@_cur_hook_tl _code_prop } {#1} { } + \prop_put:Nnn \l_@@_work_prop {#1} { } } % \end{macrocode} % \end{macro} - +% % \begin{macro}{ % \@@_apply_-rule_<:nnn, % \@@_apply_-rule_>:nnn, @@ -2851,27 +3063,28 @@ \cs_new_eq:cc { @@_apply_-rule_xW:nnn } { @@_apply_rule_xW:nnn } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_msg_pair_found:nnn} % A macro to avoid moving this many tokens around. % \begin{macrocode} \cs_new_protected:Npn \@@_msg_pair_found:nnn #1#2#3 { \iow_term:x{~ \str_if_eq:nnTF {#3} {??} {default} {~normal} ~ - rule~ \@@_label_pair:nn {#1} {#2}:~ - \use:c { g_@@_#3_rule_ \@@_label_pair:nn {#1} {#2} _tl } ~ found} + rule~ \@@_label_pair:nn {#1} {#2}:~ + \use:c { g_@@_#3_rule_ \@@_label_pair:nn {#1} {#2} _tl } ~ + found} } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_debug_label_data:N} % % \begin{macrocode} \cs_new_protected:Npn \@@_debug_label_data:N #1 { \iow_term:x{Code~ labels~ for~ sorting:} - \iow_term:x{~ \seq_use:Nnnn\l_@@_labels_seq {~and~}{,~}{~and~} } % fix name! + \iow_term:x{~ \seq_use:Nnnn\l_@@_labels_seq {~and~}{,~}{~and~} } \iow_term:x{^^J Data~ structure~ for~ label~ rules:} \prop_map_inline:Nn #1 { @@ -2883,9 +3096,9 @@ } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\hook_log:n} % This writes out information about the hook given in its argument % onto the terminal and the \texttt{.log} file. @@ -2897,6 +3110,7 @@ } \cs_new_protected:Npn \@@_log:n #1 { + \@@_preamble_hook:n {#1} \iow_term:x{^^JThe~ hook~ '#1':} % \end{macrocode} % @@ -2917,26 +3131,42 @@ % \begin{macrocode} \iow_term:x{~Extra~ code~ next~ invocation:} \iow_term:x{\@spaces - \tl_if_empty:cTF { g_@@_#1_next_code_tl } - {---} {->~ \str_use:c{g_@@_#1_next_code_tl} } } + \tl_if_empty:cTF { g_@@_#1_code_next_tl } + {---} +% \end{macrocode} +% If the token list is not empty we want to display it but without +% the first tokens (the code to clear itself) so we call a helper +% command to get rid of them. +% \begin{macrocode} + {->~ \exp_args:Nv + \@@_log_next_code:n {g_@@_#1_code_next_tl} } } % \end{macrocode} % -% \fmi{This is currently only displaying the local rules, but it -% should also show the matching global rules!} -% +% Loop through the rules in a hook and for every rule found, print it. +% If no rule is there, print |---|. The boolean \cs{l_@@_tmpa_bool} +% here indicates if the hook has no rules. % \begin{macrocode} - \iow_term:x{~Rules:} - \prop_if_empty:cTF {g_@@_#1_rules_prop} - { \iow_term:x{\@spaces ---} } - { \prop_map_inline:cn {g_@@_#1_rules_prop} - { \iow_term:x{\@spaces ##1~ with~ relation~ ##2} } + \iow_term:x { ~Rules: } + \bool_set_true:N \l_@@_tmpa_bool + \@@_list_rules:nn {#1} + { + \bool_set_false:N \l_@@_tmpa_bool + \iow_term:x + { + \@spaces ##2~ with~ + \str_if_eq:nnT {##3} {??} { default~ } + relation~ ##1 } } + \bool_if:NT \l_@@_tmpa_bool + { \iow_term:x { \@spaces --- } } % \end{macrocode} % % \begin{macrocode} - \hook_if_exist:nT {#1} + \bool_lazy_and:nnT + { \hook_if_exist_p:n {#1} } + { ! \hook_if_empty_p:n {#1} } { \iow_term:x { ~Execution~ order - \prop_if_empty:cTF {g_@@_#1_rules_prop} + \bool_if:NTF \l_@@_tmpa_bool { \@@_if_reversed:nT {#1} { ~ (after~ reversal) } } @@ -2944,30 +3174,97 @@ \@@_if_reversed:nT {#1} {reversal~ and~} applying~ rules) } - : + : } - \iow_term:x { \@spaces - \clist_if_empty:cTF{g_@@_#1_labels_clist} - {not~ set~ yet} - { \clist_use:cnnn {g_@@_#1_labels_clist} - { ,~ } { ,~ } { ,~ } } - } + \iow_term:x + { \@spaces \clist_use:cn {g_@@_#1_labels_clist} { ,~ } } } } { \iow_term:n { ~The~hook~is~empty. } } \iow_term:n { } } % \end{macrocode} -% +% +% To display the code for next invocation only (i.e., from +% \cs{AddToHookNext} we have to remove the first two tokens at the +% front which are \cs{tl_gclear:N} and the token list to clear. +% \begin{macrocode} +\cs_new:Npn \@@_log_next_code:n #1 { + \exp_args:No \tl_to_str:n {\use_none:nn #1} +} +% \end{macrocode} % \end{macro} - - - -% \subsection{Specifying code for next invocation} % +% \begin{macro}{\@@_list_rules:nn} +% \begin{macro}{\@@_list_one_rule:nnn,\@@_list_if_rule_exists:nnnF} +% This macro takes a \meta{hook} and an \meta{inline function} and +% loops through each pair of \meta{labels} in the \meta{hook}, and if +% there is a relation between this pair of \meta{labels}, the +% \meta{inline function} is executed with |#1|${}={}$\meta{relation}, +% |#2|${}={}$\meta{label_1}\verb=|=\meta{label_2}, +% and |#3|${}={}$\meta{hook} (the latter may be the argument |#1| to +% \cs{@@_list_rules:nn}, or |??| if it is a default rule). +% \begin{macrocode} +\cs_new_protected:Npn \@@_list_rules:nn #1 #2 + { + \cs_set_protected:Npn \@@_tmp:w ##1 ##2 ##3 {#2} + \prop_map_inline:cn { g_@@_#1_code_prop } + { + \prop_map_inline:cn { g_@@_#1_code_prop } + { + \@@_if_label_case:nnnnn {##1} {####1} + { \prop_map_break: } + { \@@_list_one_rule:nnn {##1} {####1} } + { \@@_list_one_rule:nnn {####1} {##1} } + {#1} + } + } + } +% \end{macrocode} % +% These two are quite similar to \cs{@@_apply_label_pair:nnn} and +% \cs{@@_label_if_exist_apply:nnnF}, respectively, but rather than +% applying the rule, they pass it to the \meta{inline function}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_list_one_rule:nnn #1#2#3 + { + \@@_list_if_rule_exists:nnnF {#1} {#2} {#3} { } + { \@@_list_if_rule_exists:nnnF {#1} {#2} { ?? } { } } + } +\cs_new_protected:Npn \@@_list_if_rule_exists:nnnF #1#2#3 + { + \if_cs_exist:w g_@@_ #3 _rule_ #1 | #2 _tl \cs_end: + \exp_args:Nv \@@_tmp:w + { g_@@_ #3 _rule_ #1 | #2 _tl } { #1 | #2 } {#3} + \fi: + } +% \end{macrocode} +% \end{macro} +% \end{macro} % +% \begin{macro}{\@@_debug_print_rules:n} +% A shorthand for debugging that prints similar to \cs{prop_show:N}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_debug_print_rules:n #1 + { + \iow_term:n { The~hook~#1~contains~the~rules: } + \cs_set_protected:Npn \@@_tmp:w ##1 + { + \@@_list_rules:nn {#1} + { + \iow_term:x + { + > ##1 {####2} ##1 => ##1 {####1} + \str_if_eq:nnT {####3} {??} { ~(default) } + } + } + } + \exp_args:No \@@_tmp:w { \use:nn { ~ } { ~ } } + } +% \end{macrocode} +% \end{macro} % +% \subsection{Specifying code for next invocation} % % \begin{macro}{\hook_gput_next_code:nn} % @@ -2984,10 +3281,29 @@ { \@@_gput_next_do:nn {#1} {#2} } { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } } -\cs_new_protected:Npn \@@_gput_next_do:nn #1 #2 +\cs_new_protected:Npn \@@_gput_next_do:nn #1 { - \tl_gput_right:cn { g_@@_#1_next_code_tl } - { #2 \tl_gclear:c { g_@@_#1_next_code_tl } } + \exp_args:Nc \@@_gput_next_do:Nnn + { g_@@_#1_code_next_tl } {#1} + } +% \end{macrocode} +% First check if the ``next code'' token list is empty: if so we need +% to add a \cs{tl_gclear:c} to clear it, so the code lasts for one +% usage only. The token list is cleared early so that nested usages +% don't get lost. \cs{tl_gclear:c} is used instead of +% \cs{tl_gclear:N} in case the hook is used in an expansion-only +% context, so the token list doesn't expand before \cs{tl_gclear:N}: +% that would make an infinite loop. Also in case the main code token +% list is empty, the hook code has to be updated to add the next +% execution token list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_next_do:Nnn #1 #2 + { + \tl_if_empty:cT { g_@@_#2_code_tl } + { \@@_update_hook_code:n {#2} } + \tl_if_empty:NT #1 + { \tl_gset:Nn #1 { \tl_gclear:c { g_@@_#2_code_next_tl } } } + \tl_gput_right:Nn #1 } % \end{macrocode} % \end{macro} @@ -3069,7 +3385,7 @@ \@@_if_file_hook:wTF #1 / / \s_@@_mark { \exp_args:Ne \@@_if_exist_use:n - { \exp_args:Ne \@@_file_hook_normalise:n {#1} } + { \exp_args:Ne \@@_file_hook_normalize:n {#1} } } { \@@_if_exist_use:n {#1} } % file/ generic hook (e.g. file/before) } @@ -3102,7 +3418,7 @@ } % \end{macrocode} % \end{macro} - +% % \subsection{Querying a hook} % % Simpler data types, like token lists, have three possible states; they @@ -3129,7 +3445,7 @@ % Test if a hook is empty (that is, no code was added to that hook). % A hook being empty means that \emph{both} its % \cs[no-index]{g_@@_\meta{hook}_code_prop} and its -% \cs[no-index]{g_@@_\meta{hook}_next_code_tl} are empty. +% \cs[no-index]{g_@@_\meta{hook}_code_next_tl} are empty. % \begin{macrocode} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } { @@ -3137,7 +3453,7 @@ { \bool_lazy_and:nnTF { \prop_if_empty_p:c { g_@@_#1_code_prop } } - { \tl_if_empty_p:c { g_@@_#1_next_code_tl } } + { \tl_if_empty_p:c { g_@@_#1_code_next_tl } } { \prg_return_true: } { \prg_return_false: } } @@ -3145,7 +3461,7 @@ } % \end{macrocode} % \end{macro} - +% % \begin{macro}[pTF]{\hook_if_exist:n} % A canonical way to test if a hook exists. A hook exists if the % token list that stores the sorted code for that hook, @@ -3163,7 +3479,7 @@ } % \end{macrocode} % \end{macro} - +% % \begin{macro}[pTF]{\@@_if_exist:n} % An internal check if the hook has already been declared with % \cs{@@_declare:n}. This means that the hook was already used somehow @@ -3192,8 +3508,8 @@ } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\g_@@_execute_immediately_clist} % List of hooks that from no on should not longer receive code. % \begin{macrocode} @@ -3208,21 +3524,57 @@ { Labels~`#1'~and~`#2'~are~incompatible \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~ - \int_compare:nNnT {#4} = { 1 } - { The~code~for~both~labels~will~be~dropped. } - } - { - LaTeX~found~two~incompatible~labels~in~the~same~hook.~ - This~indicates~an~incompatibility~between~packages. + \int_compare:nNnTF {#4} = { 1 } + { The~ code~ for~ both~ labels~ will~ be~ dropped. } + { You~ may~ see~ errors~ later. } } + { LaTeX~found~two~incompatible~labels~in~the~same~hook.~ + This~indicates~an~incompatibility~between~packages. } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { exists } + { Hook~`#1'~ has~ already~ been~ declared. } + { There~ already~ exists~ a~ hook~ declaration~ with~ this~ + name.\\ + Please~ use~ a~ different~ name~ for~ your~ hook.} +% \end{macrocode} +% +% \begin{macrocode} \msg_new:nnn { hooks } { empty-label } { Empty~code~label~\msg_line_context:.~Using~`#1'~instead. } % \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { unknown-rule } + { Unknown~ relationship~ `#3'~ + between~ labels~ `#2'~ and~ `#4'~ + \str_if_eq:nnF {#1} {??} { ~in~hook~`#1' }. ~ + Perhaps~ a~ missspelling? + } + { + The~ relation~ used~ not~ known~ to~ the~ system.~ Allowed~ values~ are~ + `before'~ or~ `<',~ + `after'~ or~ `>',~ + `incompatible-warning',~ + `incompatible-error',~ + `voids'~ or~ + `unrelated'. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { should-not-happen } + { + ERROR!~This~should~not~happen.~#1 \\ + Please~report~at~https://github.com/latex3/latex2e. + } +% \end{macrocode} % % \subsection{\LaTeXe{} package interface commands} % - - +% +% % \begin{macro}{\NewHook,\NewReversedHook,\NewMirroredHookPair} % Declaring new hooks \ldots % \begin{macrocode} @@ -3231,7 +3583,7 @@ \NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} } % \end{macrocode} % \end{macro} - +% % \begin{macro}{\AddToHook} % % \begin{macrocode} @@ -3243,7 +3595,7 @@ } % \end{macrocode} % \end{macro} - +% % \begin{macro}{\AddToHookNext} % % \begin{macrocode} @@ -3251,8 +3603,8 @@ { \hook_gput_next_code:nn {#1} {#2} } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\RemoveFromHook} % % \begin{macrocode} @@ -3275,32 +3627,15 @@ % default label for the top-level. Since the string \verb|top-level| % is hardcoded, here this item of the stack is empty. Also, since % we're in an input level, add \verb|lthooks| to the stack as well. -% This stack should never go empty, so we loop through \LaTeXe's -% file name stack, and add empty entries to \cs{g_@@_name_stack_seq} -% for each item in that stack. The last item is the \verb|top-level|, -% which also gets an empty entry. -% -% Also check for the case we're loading \texttt{lthooks} in the -% \LaTeXe{} kernel. In that case, \cs{@currname} isn't \verb|lthooks| -% and just the top-level is added to the stack as an empty entry. +% This stack should never go empty. An empty entry is added to the +% stack to account for the \verb|top-level|. The item is empty so +% that the hard-coded default is used, but a call to +% \cs{DeclareDefaultHookLabel} will change it if needed. % \begin{macrocode} -\str_if_eq:VnTF \@currname { lthooks } - { - \seq_gpush:Nn \g_@@_name_stack_seq { lthooks } - \cs_set_protected:Npn \@@_tmp:w #1 #2 #3 - { - \quark_if_recursion_tail_stop:n {#1} - \seq_gput_right:Nn \g_@@_name_stack_seq { } - \@@_tmp:w - } - \exp_after:wN \@@_tmp:w - \@currnamestack - \q_recursion_tail \q_recursion_tail - \q_recursion_tail \q_recursion_stop - } - { \seq_gpush:Nn \g_@@_name_stack_seq { } } +\seq_gpush:Nn \g_@@_name_stack_seq { } % \end{macrocode} % +% % Two commands keep track of the stack: when a file is input, % \cs{@@_curr_name_push:n} pushes an (empty by default) label to the % stack: @@ -3321,7 +3656,10 @@ \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl \seq_get:NNTF \g_@@_name_stack_seq \l_@@_return_tl { \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl } - { \ERROR_should_not_happen } + { + \msg_error:nnn { hooks } { should-not-happen } + { Tried~to~pop~from~an~empty~default~label~stack. } + } } % \end{macrocode} % @@ -3336,15 +3674,6 @@ \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl \@@_curr_name_push:n {#1} } -% \begin{macrocode} -% -% The push and pop macros are injected in \cs{@pushfilename} and -% \cs{@popfilename} so that they correctly keep track of the label.s -% \begin{macrocode} -% TODO! \pho{Properly integrate in the kernel} -\tl_gput_left:Nn \@pushfilename { \@@_curr_name_push:n { } } -\tl_gput_left:Nn \@popfilename { \@@_curr_name_pop: } -% TODO! \pho{Properly integrate in the kernel} % \end{macrocode} % \end{macro} % \end{macro} @@ -3352,48 +3681,42 @@ % % % -% \begin{macro}{\UseHook} +% \begin{macro}{\UseHook,\UseOneTimeHook} % Avoid the overhead of \pkg{xparse} and its protection that we % don't want here (since the hook should vanish without trace if empty)! % \begin{macrocode} -\newcommand \UseHook { \hook_use:n } +\newcommand \UseHook { \hook_use:n } +\newcommand \UseOneTimeHook { \hook_use_once:n } % \end{macrocode} % \end{macro} % -% \begin{macro}{\UseOneTimeHook} % -% \begin{macrocode} -\cs_new_protected:Npn \UseOneTimeHook { \hook_use_once:n } -% \end{macrocode} -% \end{macro} - - - +% % \begin{macro}{\ShowHook} % % \begin{macrocode} \cs_new_protected:Npn \ShowHook { \hook_log:n } % \end{macrocode} % \end{macro} - -% \begin{macro}{\DebugHookOn,\DebugHookOff} +% +% \begin{macro}{\DebugHooksOn,\DebugHooksOff} % % \begin{macrocode} -\cs_new_protected:Npn \DebugHookOn { \hook_debug_on: } -\cs_new_protected:Npn \DebugHookOff { \hook_debug_off: } +\cs_new_protected:Npn \DebugHooksOn { \hook_debug_on: } +\cs_new_protected:Npn \DebugHooksOff { \hook_debug_off: } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\DeclareHookRule} % % \begin{macrocode} \NewDocumentCommand \DeclareHookRule { m m m m } -{ \hook_gset_rule:nnnn {#1}{#2}{#3}{#4} } + { \hook_gset_rule:nnnn {#1}{#2}{#3}{#4} } % \end{macrocode} % \end{macro} - +% % \begin{macro}{\DeclareDefaultHookRule} % This declaration is only supported before \verb=\begin{document}=. % \begin{macrocode} @@ -3406,7 +3729,7 @@ % \begin{macro}{\ClearHookRule} % A special setup rule that removes an existing relation. % Basically {@@_rule_gclear:nnn} plus fixing the property list for debugging. -% \fmi{Need an L3 interface, or maybe it should get dropped} +% \fmi{Need an L3 interface, or maybe it should get dropped?} % \begin{macrocode} \NewDocumentCommand \ClearHookRule { m m m } { \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} } @@ -3414,512 +3737,102 @@ % \end{macro} % % -% \begin{macro}{\IfHookExistTF,\IfHookEmptyTF} +% \begin{macro}{\IfHookExistsTF,\IfHookEmptyTF} % \begin{macrocode} -\NewExpandableDocumentCommand \IfHookExistTF { m } +\NewExpandableDocumentCommand \IfHookExistsTF { m } { \hook_if_exist:nTF {#1} } \NewExpandableDocumentCommand \IfHookEmptyTF { m } { \hook_if_empty:nTF {#1} } % \end{macrocode} % \end{macro} - - - - -% \begin{macro}{\AtBeginDocument} -% -% \begin{macrocode} -\renewcommand\AtBeginDocument{\AddToHook{begindocument}} -% \end{macrocode} -% \end{macro} - -% \begin{macro}{\AtEndDocument} -% -% \begin{macrocode} -\renewcommand\AtEndDocument {\AddToHook{enddocument}} -%\renewcommand\AtEndDocument {\AddToHook{env/document/end}} % alternative impl -% \end{macrocode} -% -% \end{macro} - - - -% \subsection{Set up existing \LaTeXe{} hooks} -% -% As we are in a package calling \cs{NewHook} would label any -% already set up hook code under the package name, but we want it -% under the name \hook{top-level} so we pretend that \cs{@currname} -% is empty. -% \begin{macrocode} -\begingroup - \def\@currname{} -% \end{macrocode} -% -% \begin{macrocode} - \NewHook{begindocument} - \NewHook{enddocument} -% \end{macrocode} -% We need to initialize the mechanism at \verb=\begin{document}= -% but obviously before everything else, so we sneak\footnote{This -% needs to move to \cs{document} directly.} -% \cs{@@_initialize_all:} into the \LaTeXe{} hook name. -% -% We can't use \cs{tl_gput_left:Nn} because that complains about -% \cs{@begindocumenthook} not starting with \cs{g_} so we do this -% through the backdoor. -% \begin{macrocode} -% \tex_global:D\tl_put_left:Nn \@begindocumenthook -% {\@@_initialize_all:} -% \end{macrocode} -% There aren't many other hooks at the moment: -% \begin{macrocode} - \NewHook{rmfamily} - \NewHook{sffamily} - \NewHook{ttfamily} - \NewHook{defaultfamily} -% \end{macrocode} -% Not checked what this one does and whether it should be there (or -% is a real ``hook''. -% \begin{macrocode} - \NewHook{documentclass} -% \end{macrocode} -% -% \begin{macrocode} -\endgroup -% \end{macrocode} -% -% -% -% \section{Generic hooks for environments} -% -% -% \begin{macrocode} -\let\begin\relax % avoid redeclaration message -% \end{macrocode} -% -% \begin{macrocode} -\DeclareRobustCommand*\begin[1]{% - \UseHook{env/#1/before}% - \@ifundefined{#1}% - {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}% - {\def\reserved@a{\def\@currenvir{#1}% - \edef\@currenvline{\on@line}% - \@execute@begin@hook{#1}% - \csname #1\endcsname}}% - \@ignorefalse - \begingroup\@endpefalse\reserved@a} -% \end{macrocode} -% -% Before the \cs{document} code is executed we have to first undo -% the \cs{endgroup} as there should be none for this environment to -% avoid that changes on top-level unnecessarily go to \TeX's -% savestack, and we have to initialize all hooks in the hook system. -% So we need to test for this environment name. But once it has be -% found all this testing is no longer needed and so we redefine -% \cs{@execute@begin@hook} to simply use the hook -% \begin{macrocode} -\def\@execute@begin@hook #1{% - \expandafter\ifx\csname #1\endcsname\document - \endgroup - \gdef\@execute@begin@hook##1{\UseHook{env/##1/begin}}% - \@@_initialize_all: - \@execute@begin@hook{#1}% -% \end{macrocode} -% If this is an environment before \verb=\begin{document}= we just -% run the hook. -% \begin{macrocode} - \else - \UseHook{env/#1/begin}% - \fi -} -% \end{macrocode} -% -% \begin{macrocode} -\@namedef{end~}#1{% - \UseHook{env/#1/end}% - \csname end#1\endcsname\@checkend{#1}% - \expandafter\endgroup\if@endpe\@doendpe\fi - \UseHook{env/#1/after}% - \if@ignore\@ignorefalse\ignorespaces\fi}% -% \end{macrocode} -% Version that fixes tlb3722 but the change should perhaps be made in -% \pkg{tabularx} instead. -% \begin{macrocode} -\@namedef{end~}#1{% -\romannumeral -\IfHookEmptyTF{env/#1/end}% - {\expandafter\z@}% - {\z@\UseHook{env/#1/end}}% -\csname end#1\endcsname\@checkend{#1}% -\expandafter\endgroup\if@endpe\@doendpe\fi -\UseHook{env/#1/after}% -\if@ignore\@ignorefalse\ignorespaces\fi}% -% \end{macrocode} -% -% % -% We provide 4 high-level hook interfaces directly, the others only when -% etoolbox is loaded -% \begin{macrocode} -\newcommand\AtBeginEnvironment[1] {\AddToHook{env/#1/begin}} -\newcommand\AtEndEnvironment[1] {\AddToHook{env/#1/end}} -\newcommand\BeforeBeginEnvironment[1]{\AddToHook{env/#1/before}} -\newcommand\AfterEndEnvironment[1] {\AddToHook{env/#1/after}} -% \end{macrocode} -% -% -% -% -% -% -% -% -% -% -% -% \section{Generic hooks for file loads} % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % +% \subsection{Internal commands needed elsewhere} % +% Here we set up a few horrible (but consistent) \LaTeXe{} names to +% allow for internal commands to be used outside this module. We +% have to unset the \texttt{@\/@} since we want double ``at'' sign +% in place of double underscores. % -% -% -% -% \section{Hooks in \cs{begin} document} -% -% Can't have \texttt{@{}@} notation here as this is \LaTeXe{} code -% \ldots{} and makes for puzzling errors if the double \texttt{@} -% signs get substituted. % \begin{macrocode} %<@@=> -\ExplSyntaxOff -% \end{macrocode} -% -% The \hook{begindocument} hook was already set up earlier, here is now -% the additional one (which was originally from the \pkg{etoolbox} -% package under the name \texttt{afterpreamble}. -% \begin{macrocode} -\NewHook{begindocument/end} % \end{macrocode} % -% - -% \begin{macro}{\document} +% \begin{macro}{\@expl@@@initialize@all@@, +% \@expl@@@hook@curr@name@push@@n, +% \@expl@@@hook@curr@name@pop@@} % % \begin{macrocode} -\def\document{% +\cs_new_eq:NN \@expl@@@initialize@all@@ + \__hook_initialize_all: % \end{macrocode} -% We do cancel the grouping as part of the \cs{begin} handling -% (this is now done inside \cs{begin} instead) so that the -% \hook{env/\meta{env}/begin} hook is not hidden inside \cs{begingroup} -% \texttt{...} \cs{endgroup}. -% \begin{macrocode} -% \endgroup -% \end{macrocode} -% -% \begin{macrocode} - \@kernel@after@env@document@begin -% \end{macrocode} -% -% Added hook to load \textsf{l3backend} code: -% \begin{macrocode} - \@expl@sys@load@backend@@ - \ifx\@unusedoptionlist\@empty\else - \@latex@warning@no@line{Unused global option(s):^^J% - \@spaces[\@unusedoptionlist]}% - \fi - \@colht\textheight - \@colroom\textheight \vsize\textheight - \columnwidth\textwidth - \@clubpenalty\clubpenalty - \if@twocolumn - \advance\columnwidth -\columnsep - \divide\columnwidth\tw@ \hsize\columnwidth \@firstcolumntrue - \fi - \hsize\columnwidth \linewidth\hsize - \begingroup\@floatplacement\@dblfloatplacement - \makeatletter\let\@writefile\@gobbletwo - \global \let \@multiplelabels \relax - \@input{\jobname.aux}% - \endgroup - \if@filesw - \immediate\openout\@mainaux\jobname.aux - \immediate\write\@mainaux{\relax}% - \fi - \process@table - \let\glb@currsize\@empty % Force math initialization. - \normalsize - \everypar{}% - \ifx\normalsfcodes\@empty - \ifnum\sfcode`\.=\@m - \let\normalsfcodes\frenchspacing - \else - \let\normalsfcodes\nonfrenchspacing - \fi - \fi - \ifx\document@default@language\m@ne - \chardef\document@default@language\language - \fi - \@noskipsecfalse - \let \@refundefined \relax -% \end{macrocode} -% -% \begin{macrocode} -% \let\AtBeginDocument\@firstofone -% \@begindocumenthook - \UseOneTimeHook{begindocument}% - \@kernel@after@begindocument -% \end{macrocode} -% -% \begin{macrocode} - \ifdim\topskip<1sp\global\topskip 1sp\relax\fi - \global\@maxdepth\maxdepth - \global\let\@begindocumenthook\@undefined - \ifx\@listfiles\@undefined - \global\let\@filelist\relax - \global\let\@addtofilelist\@gobble - \fi - \gdef\do##1{\global\let ##1\@notprerr}% - \@preamblecmds - \global\let \@nodocument \relax - \global\let\do\noexpand -% \end{macrocode} -% -% \begin{macrocode} - \UseOneTimeHook{begindocument/end}% - \ignorespaces} -% \end{macrocode} -% -% \begin{macrocode} -\let\@kernel@after@begindocument\@empty -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@kernel@after@env@document@begin,\@kernel@hook@begindocument} -% -% \begin{macrocode} -\edef \@kernel@after@env@document@begin{% - \let\expandafter\noexpand\csname - g__hook_env/document/begin_code_tl\endcsname - \noexpand\@empty} -% \end{macrocode} -% \begin{macrocode} -\let\@kernel@hook@begindocument\@empty -% \end{macrocode} -% -% \end{macro} % -% -% \section{Hooks in \cs{enddocument}} -% -% -% -% The \hook{enddocument} hook was already set up earlier, here are now -% the additional ones: % \begin{macrocode} -\NewHook{enddocument/afterlastpage} -\NewHook{enddocument/afteraux} -\NewHook{enddocument/info} -\NewHook{enddocument/end} +\cs_new_eq:NN \@expl@@@hook@curr@name@push@@n + \__hook_curr_name_push:n % \end{macrocode} - - - -% \begin{macro}{\enddocument} -% -% -% \begin{macrocode} -\def\enddocument{% - \UseHook{enddocument}% - \@kernel@after@enddocument - \@checkend{document}% - \clearpage - \UseHook{enddocument/afterlastpage}% - \@kernel@after@enddocument@afterlastpage - \begingroup - \if@filesw - \immediate\closeout\@mainaux - \let\@setckpt\@gobbletwo - \let\@newl@bel\@testdef - \@tempswafalse - \makeatletter \@@input\jobname.aux - \fi - \UseHook{enddocument/afteraux}% -% \end{macrocode} -% Next hook is expect to contain only code for writing info -% messages on the terminal. -% \begin{macrocode} - \UseHook{enddocument/info}% - \endgroup - \UseHook{enddocument/end}% - \deadcycles\z@\@@end} -% \end{macrocode} -% The two kernel hooks above are used by the shipout code. -% \begin{macrocode} -\let\@kernel@after@enddocument\@empty -\let\@kernel@after@enddocument@afterlastpage\@empty -% \end{macrocode} -% \end{macro} -% % -% -% \begin{macro}{\@enddocument@kernel@warnings} -% -% \begin{macrocode} -\def\@enddocument@kernel@warnings{% - \ifdim \font@submax >\fontsubfuzz\relax - \@font@warning{Size substitutions with differences\MessageBreak - up to \font@submax\space have occurred.\@gobbletwo}% - \fi - \@defaultsubs - \@refundefined - \if@filesw - \ifx \@multiplelabels \relax - \if@tempswa - \@latex@warning@no@line{Label(s) may have changed. - Rerun to get cross-references right}% - \fi - \else - \@multiplelabels - \fi - \fi -} -% \end{macrocode} -% % \begin{macrocode} -\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} -\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} -\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} +\cs_new_eq:NN \@expl@@@hook@curr@name@pop@@ + \__hook_curr_name_pop: % \end{macrocode} % \end{macro} % -% -% \subsection{Adjusting at \pkg{atveryend} interfaces} -% -% With the new hook management all of \pkg{atveryend} is taken care -% of. -% -% We therefore prevent the package from loading: -% \begin{macrocode} -\expandafter\let\csname ver@atveryend.sty\endcsname\fmtversion -% \end{macrocode} -% -% -% Here are new definitions for its interfaces now pointing to the -% hooks in \cs{enddocument} -% \begin{macrocode} -\newcommand\AfterLastShipout {\AddToHook{enddocument/afterlastpage}} -\newcommand\AtVeryEndDocument {\AddToHook{enddocument/afteraux}} -% \end{macrocode} -% Next one is a bit of a fake, but the result should normally be as -% expected. If not one needs to add a rule to sort the code chunks -% in \hook{enddocument/info}. -% \begin{macrocode} -\newcommand\AtEndAfterFileList{\AddToHook{enddocument/info}} -% \end{macrocode} -% -% \begin{macrocode} -\newcommand\AtVeryVeryEnd {\AddToHook{enddocument/end}} -% \end{macrocode} - -% \begin{macro}{\BeforeClearDocument} -% This one is the only one we don't implement or rather don't have -% a dedicated hook in the code. -% \begin{macrocode} -\ExplSyntaxOn -\newcommand\BeforeClearDocument[1] - { \AtEndDocument{#1} - \@DEPRECATED{BeforeClearDocument \tl_to_str:n{#1}} - } -\cs_new:Npn\@DEPRECATED #1 - {\iow_term:x{======~DEPRECATED~USAGE~#1~==========}} -% \end{macrocode} % % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -%</2ekernel> -% \end{macrocode} - % -% \section{A package version of the code for testing} % - -% \begin{macrocode} -%<*package> -% \end{macrocode} - - - -% \begin{macrocode} -\RequirePackage{xparse} -\ProvidesExplPackage{lthooks}{\lthooksdate}{\lthooksversion} - {Hook management interface for LaTeX2e} +% Rolling back here doesn't undefine the interface commands as they +% may be used in packages without rollback functionality. So we +% just make them do nothing which may or may not work depending on +% the code usage. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\NewHook}{The hook management}% +%<latexrelease> +%<latexrelease>\def \NewHook#1{} +%<latexrelease>\def \NewReversedHook#1{} +%<latexrelease>\def \NewMirroredHookPair#1#2{} +%<latexrelease> +%<latexrelease>\long\def \AddToHook#1#2{} +%<latexrelease> +%<latexrelease>\def \AddToHookNext#1{\@gobble@AddToHook@args} +%<latexrelease>\providecommand\@gobble@AddToHook@args[2][]{} +%<latexrelease> +%<latexrelease>\def\RemoveFromHook#1{\@gobble@RemoveFromHook@arg} +%<latexrelease>\providecommand\@gobble@RemoveFromHook@arg[1][]{} +%<latexrelease> +%<latexrelease>\def \UseHook #1{} +%<latexrelease>\def \UseOneTimeHook #1{} +%<latexrelease>\def \ShowHook #1{} +%<latexrelease>\let \DebugHooksOn \@empty +%<latexrelease>\let \DebugHooksOff\@empty +%<latexrelease> +%<latexrelease>\def \DeclareHookRul#1#2#3#4{} +%<latexrelease>\def \DeclareDefaultHookRule #1#2#3{} +%<latexrelease>\def \ClearHookRule#1#2#3{} +% \end{macrocode} +% If the hook management is not provided we make the test for existence +% false and the test for empty true in the hope that this is most +% of the time reasonable. If not a package would need to guard +% against running in an old kernel. +% \begin{macrocode} +%<latexrelease>\def \IfHookExistTF #1#2#3{#3} +%<latexrelease>\def \IfHookEmptyTF #1#2#3{#2} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % % -% \subsection{Core hook management code (kernel part)} -% -% This should run in older formats so we can't use -% \cs{IfFormatAtLeastTF} right now. -% \begin{macrocode} -\@ifl@t@r\fmtversion{2020/10/01} - {} - {\input{lthooks.ltx} - \input{ltshipout.ltx} - \input{ltfilehook.ltx} - } -% \end{macrocode} -% -% \subsection{Package options} -% -% For now we offer a simple debug option which turns on a lot of -% strange \cs{typeout} messages, nothing fancy. -% \begin{macrocode} -\ExplSyntaxOn -% \end{macrocode} -% -% \begin{macrocode} -\hook_debug_off: -\DeclareOption { debug } { \hook_debug_on: - \shipout_debug_on: } -% \end{macrocode} -% -% -% For now we offer a simple debug option which turns on a lot of -% strange \cs{typeout} messages, nothing fancy. -% \begin{macrocode} -\shipout_debug_off: -\DeclareOption { debug-shipout } { \shipout_debug_on: } -% \end{macrocode} -% -% \begin{macrocode} -\ProcessOptions -% \end{macrocode} -% -% -% \subsection{Temporarily patching package until changed} -% -% -% -% \pkg{filehook} support until that package is patched: -% \begin{macrocode} -\RequirePackage{filehook-ltx} -% \end{macrocode} -% -% -% -% \begin{macrocode} -%</package> -% \end{macrocode} -% -% -% % \Finale % - - +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.ins b/Master/texmf-dist/source/latex-dev/base/lthooks.ins deleted file mode 100644 index 4218fb8b259..00000000000 --- a/Master/texmf-dist/source/latex-dev/base/lthooks.ins +++ /dev/null @@ -1,76 +0,0 @@ -%% -%% This file will generate fast loadable files and documentation -%% driver files from the dtx file(s) in this package when run through -%% LaTeX or TeX. -%% -%% Copyright 2020 Frank Mittelbach -%% -%% -%% This file is part of the lthooks Bundle for LaTeX. -%% ------------------------------------------------------- -%% -%% It may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3c -%% of this license or (at your option) any later version. -%% The latest version of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.3c or later is part of all distributions of LaTeX -%% version 2008 or later. -%% -%% In particular, NO PERMISSION is granted to modify the contents of this -%% file since it contains the legal notices that are placed in the files -%% it generates. -%% -%% -%% -%% --------------- start of docstrip commands ------------------ -%% -\input docstrip - -\keepsilent - -\preamble - -This is a generated file. - -Copyright 2020 Frank Mittelbach - -This file was generated from file(s) of the LaTeX `lthooks Bundle'. --------------------------------------------------------------------------- - -It may be distributed and/or modified under the -conditions of the LaTeX Project Public License, either version 1.3c -of this license or (at your option) any later version. -The latest version of this license is in - http://www.latex-project.org/lppl.txt -and version 1.3c or later is part of all distributions of LaTeX -version 2005/12/01 or later. - -This file may only be distributed together with a copy of the LaTeX -`lthooks Bundle'. You may however distribute the `lthooks Bundle' -without such generated files. - -The newest sources can be found below - - https://github.com/FrankMittelbach/fmitex/ - -where one can also log issues in case there are any. - - -\endpreamble - - -\generate{\file{lthooks.ltx}{\from{lthooks.dtx}{2ekernel}}} -\generate{\file{ltshipout.ltx}{\from{ltshipout.dtx}{2ekernel}}} -\generate{\file{ltfilehook.ltx}{\from{ltfilehook.dtx}{2ekernel}}} - - -\generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}} - -\generate{\file{lthooks.sty}{\from{lthooks.dtx}{package}}} - -\generate{\file{filehook-ltx.sty}{\from{ltfilehook.dtx}{filehook-draft}}} - -\generate{\file{srclfile-ltx.sty}{\from{ltfilehook.dtx}{scrlfile-draft}}} - -\endbatchfile diff --git a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx index 2e692a993b9..ec1031cc290 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx @@ -28,7 +28,7 @@ \ProvidesFile{ltluatex.dtx} %</driver> %<*tex> -[2020/06/10 v1.1n +[2020/08/10 v1.1r %</tex> %<plain> LuaTeX support for plain TeX (core) %<*tex> @@ -459,7 +459,7 @@ % \end{macrocode} % luatex/xetex also allow more math fam. % \begin{macrocode} -\edef \et@xmaxfam {\ifx\Umathchar\@undefined\sixt@@n\else\@cclvi\fi} +\edef \et@xmaxfam {\ifx\Umathcode\@undefined\sixt@@n\else\@cclvi\fi} % \end{macrocode} % % \begin{macrocode} @@ -550,18 +550,19 @@ % % \begin{macro}{\newattribute} % \changes{v1.0a}{2015/09/24}{Macro added} +% \changes{v1.1q}{2020/08/02}{Move reset to $0$ inside conditional} % As is generally the case for the Lua\TeX{} registers we start here % from~$1$. Notably, some code assumes that |\attribute0| is never used so % this is important in this case. % \begin{macrocode} \ifx\e@alloc@attribute@count\@undefined \countdef\e@alloc@attribute@count=258 + \e@alloc@attribute@count=\z@ \fi \def\newattribute#1{% \e@alloc\attribute\attributedef \e@alloc@attribute@count\m@ne\e@alloc@top#1% } -\e@alloc@attribute@count=\z@ % \end{macrocode} % \end{macro} % @@ -586,13 +587,13 @@ % \begin{macrocode} \ifx\e@alloc@ccodetable@count\@undefined \countdef\e@alloc@ccodetable@count=259 + \e@alloc@ccodetable@count=\z@ \fi \def\newcatcodetable#1{% \e@alloc\catcodetable\chardef \e@alloc@ccodetable@count\m@ne{"8000}#1% \initcatcodetable\allocationnumber } -\e@alloc@ccodetable@count=\z@ % \end{macrocode} % \end{macro} % @@ -699,18 +700,19 @@ % % \begin{macro}{\newluafunction} % \changes{v1.0a}{2015/09/24}{Macro added} +% \changes{v1.1q}{2020/08/02}{Move reset to $0$ inside conditional} % Much the same story for allocating Lua\TeX{} functions except here they are % just numbers so they are allocated in the same way as boxes. % Lua indexes from~$1$ so once again slot~$0$ is skipped. % \begin{macrocode} \ifx\e@alloc@luafunction@count\@undefined \countdef\e@alloc@luafunction@count=260 + \e@alloc@luafunction@count=\z@ \fi \def\newluafunction{% \e@alloc\luafunction\e@alloc@chardef \e@alloc@luafunction@count\m@ne\e@alloc@top } -\e@alloc@luafunction@count=\z@ % \end{macrocode} % \end{macro} % @@ -718,17 +720,18 @@ % % \begin{macro}{\newwhatsit} % \changes{v1.0a}{2015/09/24}{Macro added} +% \changes{v1.1q}{2020/08/02}{Move reset to $0$ inside conditional} % These are only settable from Lua but for consistency are definable % here. % \begin{macrocode} \ifx\e@alloc@whatsit@count\@undefined \countdef\e@alloc@whatsit@count=261 + \e@alloc@whatsit@count=\z@ \fi \def\newwhatsit#1{% \e@alloc\whatsit\e@alloc@chardef \e@alloc@whatsit@count\m@ne\e@alloc@top#1% } -\e@alloc@whatsit@count=\z@ % \end{macrocode} % \end{macro} % @@ -736,17 +739,18 @@ % % \begin{macro}{\newluabytecode} % \changes{v1.0a}{2015/09/24}{Macro added} +% \changes{v1.1q}{2020/08/02}{Move reset to $0$ inside conditional} % These are only settable from Lua but for consistency are definable % here. % \begin{macrocode} \ifx\e@alloc@bytecode@count\@undefined \countdef\e@alloc@bytecode@count=262 + \e@alloc@bytecode@count=\z@ \fi \def\newluabytecode#1{% \e@alloc\luabytecode\e@alloc@chardef \e@alloc@bytecode@count\m@ne\e@alloc@top#1% } -\e@alloc@bytecode@count=\z@ % \end{macrocode} % \end{macro} % @@ -754,12 +758,14 @@ % \begin{macro}{\newluachunkname} % \changes{v1.0a}{2015/09/24}{Macro added} +% \changes{v1.1q}{2020/08/02}{Move reset to $0$ inside conditional} % As for bytecode registers, but in addition we need to add a string % to the \verb|lua.name| table to use in stack tracing. We use the % name of the command passed to the allocator, with no backslash. % \begin{macrocode} \ifx\e@alloc@luachunk@count\@undefined \countdef\e@alloc@luachunk@count=263 + \e@alloc@luachunk@count=\z@ \fi \def\newluachunkname#1{% \e@alloc\luachunk\e@alloc@chardef @@ -767,19 +773,31 @@ {\escapechar\m@ne \directlua{lua.name[\the\allocationnumber]="\string#1"}}% } -\e@alloc@luachunk@count=\z@ % \end{macrocode} % \end{macro} % % \subsection{Lua loader} +% \changes{v1.1r}{2020/08/10}{Load ltluatex Lua module during format building} +% +% Lua code loaded in the format often has to to be loaded again at the +% beginning of every job, so we define a helper whch allows us to avoid +% duplicated code: +% +% \begin{macrocode} +\def\now@and@everyjob#1{% + \everyjob\expandafter{\the\everyjob + #1% + }% + #1% +} +% \end{macrocode} % % Load the Lua code at the start of every job. % For the conversion of \TeX{} into numbers at the Lua side we need some % known registers: for convenience we use a set of systematic names, which % means using a group around the Lua loader. % \begin{macrocode} -%<2ekernel>\everyjob\expandafter{% -%<2ekernel> \the\everyjob +%<2ekernel>\now@and@everyjob{% \begingroup \attributedef\attributezero=0 % \chardef \charzero =0 % @@ -1322,6 +1340,7 @@ local callbacktypes = callbacktypes or { % \changes{v1.1k}{2019/10/02}{process\_rule is \texttt{exclusive}} % \changes{v1.1k}{2019/10/02}{mlist\_to\_hlist is \texttt{exclusive}} % \changes{v1.1l}{2020/02/02}{post\_linebreak\_filter is \texttt{reverselist}} +% \changes{v1.1p}{2020/08/01}{new\_graf is \texttt{exclusive}} % \begin{macrocode} contribute_filter = simple, buildpage_filter = simple, @@ -1343,7 +1362,7 @@ local callbacktypes = callbacktypes or { pre_mlist_to_hlist_filter = list, mlist_to_hlist = exclusive, post_mlist_to_hlist_filter = reverselist, - new_graf = simple, + new_graf = exclusive, % \end{macrocode} % Section 8.5: information reporting callbacks. % \changes{v1.0m}{2016/02/11}{show\_warning\_message added} diff --git a/Master/texmf-dist/source/latex-dev/base/ltmath.dtx b/Master/texmf-dist/source/latex-dev/base/ltmath.dtx index c4963cf0c62..36b8bb7ec46 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltmath.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltmath.dtx @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2020/04/21 v1.2f LaTeX Kernel (Math Setup)] + [2020/07/27 v1.2g LaTeX Kernel (Math Setup)] % \iffalse %</driver> % @@ -407,15 +407,17 @@ % \begin{macro}{\cases} % \changes{LaTeX2.09}{1991/08/14} % {(RmS) inserted extra braces around entry for NFSS} +% \changes{v1.2g}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\cases[1]{\left\{\,\vcenter{\normalbaselines\m@th +\DeclareRobustCommand*\cases[1]{\left\{\,\vcenter{\normalbaselines\m@th \ialign{$##\hfil$&\quad{##}\hfil\crcr#1\crcr}}\right.} % \end{macrocode} % \end{macro} % % \begin{macro}{\matrix} +% \changes{v1.2g}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\matrix[1]{\null\,\vcenter{\normalbaselines\m@th +\DeclareRobustCommand*\matrix[1]{\null\,\vcenter{\normalbaselines\m@th \ialign{\hfil$##$\hfil&&\quad\hfil$##$\hfil\crcr \mathstrut\crcr\noalign{\kern-\baselineskip} #1\crcr\mathstrut\crcr\noalign{\kern-\baselineskip}}}\,} @@ -423,8 +425,9 @@ % \end{macro} % % \begin{macro}{\pmatrix} +% \changes{v1.2g}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\pmatrix[1]{\left(\matrix{#1}\right)} +\DeclareRobustCommand*\pmatrix[1]{\left(\matrix{#1}\right)} % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx index c48384b8bdc..0c115d3be1b 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2020/05/31 v1.1u LaTeX Kernel (Misc. Environments)] + [2020/08/21 v1.1v LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -73,6 +73,7 @@ % \cs{@noligs}.} % \changes{v1.1g}{1998/08/17}{(RmS) Minor documentation fixes.} % \changes{v1.1p}{2019/08/27}{Make various commands robust} +% \changes{v1.1v}{2020/08/21}{Integration of new hook management interface} % % \section{Miscellaneous Environments} % This section implements the basic environment mechanism, and also @@ -191,6 +192,10 @@ % {Added warning in case of undefined references.}% % \changes{v0.9e}{1993/12/09}{Hook added} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\enddocument}{Use Hooks}% \def\enddocument{% % \end{macrocode} % The |\end{document}| hook is executed first. If necessary it can @@ -209,10 +214,15 @@ % \changes{v1.1i}{2000/05/19} % {Reset \cs{AtEndDocument} for latex/3060} % \begin{macrocode} - \let\AtEndDocument\@firstofone - \@enddocumenthook + \UseOneTimeHook{enddocument}% + \@kernel@after@enddocument +% \end{macrocode} +% +% \begin{macrocode} \@checkend{document}% \clearpage + \UseOneTimeHook{enddocument/afterlastpage}% + \@kernel@after@enddocument@afterlastpage \begingroup \if@filesw \immediate\closeout\@mainaux @@ -235,11 +245,52 @@ \@tempswafalse \makeatletter \@@input\jobname.aux \fi + \UseHook{enddocument/afteraux}% % \end{macrocode} -% \changes{v1.0w}{1994/11/30} -% {(DPC) Use \cs{@dofilelist}} +% Next hook is expect to contain only code for writing info +% messages on the terminal. +% \begin{macrocode} + \UseOneTimeHook{enddocument/info}% + \endgroup + \UseOneTimeHook{enddocument/end}% + \deadcycles\z@\@@end} +% \end{macrocode} +% +% The public hooks used in \cs{enddocument}: +% \begin{macrocode} +\NewHook{enddocument} +\NewHook{enddocument/afterlastpage} +\NewHook{enddocument/afteraux} +\NewHook{enddocument/info} +\NewHook{enddocument/end} +% \end{macrocode} +% +% This is one of the few places where we already add data and rules +% to a hook already in the kernel. +% \changes{v1.0w}{1994/11/30}{(DPC) Use \cs{@dofilelist}} +% \begin{macrocode} +\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} +\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} +% \end{macrocode} +% \end{macro} +% \end{environment} +% +% +% \begin{macro}{\@kernel@after@enddocument, +% \@kernel@after@enddocument@afterlastpage} +% +% The two kernel hooks above are used by the shipout code. +% \begin{macrocode} +\let\@kernel@after@enddocument\@empty +\let\@kernel@after@enddocument@afterlastpage\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@enddocument@kernel@warnings} +% % \begin{macrocode} - \@dofilelist +\def\@enddocument@kernel@warnings{% % \end{macrocode} % First we check for font size substitution bigger than % |\fontsubfuzz|. The |\relax| is necessary because this is a macro @@ -247,29 +298,29 @@ % \changes{v1.0w}{1994/11/30} % {(DPC) Do warnings even for \cs{nofiles}} % \begin{macrocode} - \ifdim \font@submax >\fontsubfuzz\relax + \ifdim \font@submax >\fontsubfuzz\relax % \end{macrocode} % In case you wonder about the |\@gobbletwo| inside the message % below, this is a horrible hack to remove the tokens |\on@line.| % that are added by |\@font@warning| at the end. % \changes{v1.1j}{2000/07/11}{Fix typo in warning} % \begin{macrocode} - \@font@warning{Size substitutions with differences\MessageBreak - up to \font@submax\space have occurred.\@gobbletwo}% - \fi + \@font@warning{Size substitutions with differences\MessageBreak + up to \font@submax\space have occurred.\@gobbletwo}% + \fi % \end{macrocode} % The macro |\@defaultsubs| is initially |\relax| but gets redefined % to produce % a warning if there have been some default font substitutions. % \changes{v1.0z}{1995/07/13}{Use \cs{@defaultsubs} instead of switch} % \begin{macrocode} - \@defaultsubs + \@defaultsubs % \end{macrocode} % The macro |\@refundefined| is initially |\relax| but gets redefined % to produce a warning if there are undefined refs. % \changes{v1.1b}{1995/10/24}{Use \cs{@refundefined} instead of switch} % \begin{macrocode} - \@refundefined + \@refundefined % \end{macrocode} % If a label is defined more than once, |\@tempswa| will always be % true and thus produce a ``Label(s) may \ldots'' warning. But @@ -281,21 +332,77 @@ % \changes{v1.1b}{1995/10/24}{Changed logic for producing % warning messages and removed switch} % \begin{macrocode} - \if@filesw - \ifx \@multiplelabels \relax - \if@tempswa - \@latex@warning@no@line{Label(s) may have changed. - Rerun to get cross-references right}% - \fi - \else - \@multiplelabels + \if@filesw + \ifx \@multiplelabels \relax + \if@tempswa + \@latex@warning@no@line{Label(s) may have changed. + Rerun to get cross-references right}% \fi + \else + \@multiplelabels \fi - \endgroup - \deadcycles\z@\@@end} + \ifx \@extra@page@added \relax + \@latex@warning@no@line{Temporary extra page added at the end. + Rerun to get it removed}% + \fi +% \end{macrocode} +% We could think of adding a warning that nothing can be corrected +% while \cs{nofiles} is in force. In the past the warnings related +% to the \texttt{aux} file are simply suppressed in this case. +% \begin{macrocode} + \fi +} % \end{macrocode} % \end{macro} -% \end{environment} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\enddocument}{Use Hooks}% +%<latexrelease> +%<latexrelease>\def\enddocument{% +%<latexrelease> \let\AtEndDocument\@firstofone +%<latexrelease> \@enddocumenthook +%<latexrelease> \@checkend{document}% +%<latexrelease> \clearpage +%<latexrelease> \begingroup +%<latexrelease> \if@filesw +%<latexrelease> \immediate\closeout\@mainaux +%<latexrelease> \let\@setckpt\@gobbletwo +%<latexrelease> \let\@newl@bel\@testdef +%<latexrelease> \@tempswafalse +%<latexrelease> \makeatletter \@@input\jobname.aux +%<latexrelease> \fi +%<latexrelease> \@dofilelist +%<latexrelease> \ifdim \font@submax >\fontsubfuzz\relax +%<latexrelease> \@font@warning{Size substitutions with differences\MessageBreak +%<latexrelease> up to \font@submax\space have occurred.\@gobbletwo}% +%<latexrelease> \fi +%<latexrelease> \@defaultsubs +%<latexrelease> \@refundefined +%<latexrelease> \if@filesw +%<latexrelease> \ifx \@multiplelabels \relax +%<latexrelease> \if@tempswa +%<latexrelease> \@latex@warning@no@line{Label(s) may have changed. +%<latexrelease> Rerun to get cross-references right}% +%<latexrelease> \fi +%<latexrelease> \else +%<latexrelease> \@multiplelabels +%<latexrelease> \fi +%<latexrelease> \fi +%<latexrelease> \endgroup +%<latexrelease> \deadcycles\z@\@@end} +%<latexrelease> +%<latexrelease>\let\@kernel@after@enddocument\@undefined +%<latexrelease>\let\@kernel@after@enddocument@afterlastpage\@undefined +%<latexrelease>\let\@enddocument@kernel@warnings\@undefined +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% % % \begin{macro}{\@testdef} % \begin{macrocode} @@ -525,17 +632,107 @@ % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\begin}{Making \begin/\end robust}% -\DeclareRobustCommand\begin[1]{% +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\begin}{Use hook system}% +\DeclareRobustCommand*\begin[1]{% + \UseHook{env/#1/before}% \@ifundefined{#1}% {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% {\def\reserved@a{\def\@currenvir{#1}% - \edef\@currenvline{\on@line}% - \csname #1\endcsname}}% + \edef\@currenvline{\on@line}% + \@execute@begin@hook{#1}% + \csname #1\endcsname}}% \@ignorefalse \begingroup\@endpefalse\reserved@a} % \end{macrocode} +% +% Before the \cs{document} code is executed we have to first undo +% the \cs{endgroup} as there should be none for this environment to +% avoid that changes on top-level unnecessarily go to \TeX's +% savestack, and we have to initialize all hooks in the hook system. +% So we need to test for this environment name. But once it has be +% found all this testing is no longer needed and so we redefine +% \cs{@execute@begin@hook} to simply use the hook. +% \begin{macrocode} +\def\@execute@begin@hook #1{% + \expandafter\ifx\csname #1\endcsname\document + \endgroup + \gdef\@execute@begin@hook##1{\UseHook{env/##1/begin}}% + \@expl@@@initialize@all@@ + \fi +% \end{macrocode} +% If this is an environment before \verb=\begin{document}= we just +% run the hook so this can be outside the test. +% \begin{macrocode} + \UseHook{env/#1/begin}% +} +% \end{macrocode} +% +% The top level definition for \cs{end}. for an explanation see +% below (this is the same as the 2019 version where it was +% introduced, but for rollback we have to repeat it). +% \begin{macrocode} +\edef\end + {\unexpanded{% + \romannumeral + \ifx\protect\@typeset@protect + \expandafter %1 + \expandafter %2 + \expandafter %1 + \expandafter %3 expands the \csname inside \end<space> + \expandafter %1 + \expandafter %2 expands \end<space> + \expandafter %1 expands the \else + \z@ + \else + \expandafter\z@\expandafter\protect + \fi + }% + \expandafter\noexpand\csname end \endcsname + } +% \end{macrocode} +% Version that adds hooks (so different from the 2019 version). It +% fixes tlb3722 but the change should perhaps be made in +% \texttt{tabularx} instead. +% \begin{macrocode} +\@namedef{end }#1{% + \romannumeral + \IfHookEmptyTF{env/#1/end}% + {\expandafter\z@}% + {\z@\UseHook{env/#1/end}}% + \csname end#1\endcsname\@checkend{#1}% + \expandafter\endgroup\if@endpe\@doendpe\fi + \UseHook{env/#1/after}% + \if@ignore\@ignorefalse\ignorespaces\fi +} +% \end{macrocode} +% Version without the fix for tlb3722 for the record: +% \begin{macrocode} +%\@namedef{end }#1{% +% \UseHook{env/#1/end}% +% \csname end#1\endcsname\@checkend{#1}% +% \expandafter\endgroup\if@endpe\@doendpe\fi +% \UseHook{env/#1/after}% +% \if@ignore\@ignorefalse\ignorespaces\fi}% +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2019/10/01}% +%<latexrelease> {\begin}{Making \begin/\end robust}% +%<latexrelease>\DeclareRobustCommand\begin[1]{% +%<latexrelease> \@ifundefined{#1}% +%<latexrelease> {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% +%<latexrelease> {\def\reserved@a{\def\@currenvir{#1}% +%<latexrelease> \edef\@currenvline{\on@line}% +%<latexrelease> \csname #1\endcsname}}% +%<latexrelease> \@ignorefalse +%<latexrelease> \begingroup\@endpefalse\reserved@a} +% \end{macrocode} % A version that doesn't start out with \cs{relax} when in % typesetting mode would be the following, but since \cs{begin} % issues a \cs{begingroup} it wouldn't help much with respect to @@ -608,41 +805,50 @@ % \changes{v1.1p}{2019/08/27}{Make command robust} % % \begin{macrocode} -\edef\end - {\unexpanded{% - \romannumeral - \ifx\protect\@typeset@protect - \expandafter %1 - \expandafter %2 - \expandafter %1 - \expandafter %3 expands the \csname inside \end<space> - \expandafter %1 - \expandafter %2 expands \end<space> - \expandafter %1 expands the \else - \z@ - \else - \expandafter\z@\expandafter\protect - \fi - }% - \expandafter\noexpand\csname end \endcsname - } +%<latexrelease>\edef\end +%<latexrelease> {\unexpanded{% +%<latexrelease> \romannumeral +%<latexrelease> \ifx\protect\@typeset@protect +%<latexrelease> \expandafter %1 +%<latexrelease> \expandafter %2 +%<latexrelease> \expandafter %1 +%<latexrelease> \expandafter %3 expands the \csname inside \end<space> +%<latexrelease> \expandafter %1 +%<latexrelease> \expandafter %2 expands \end<space> +%<latexrelease> \expandafter %1 expands the \else +%<latexrelease> \z@ +%<latexrelease> \else +%<latexrelease> \expandafter\z@\expandafter\protect +%<latexrelease> \fi +%<latexrelease> }% +%<latexrelease> \expandafter\noexpand\csname end \endcsname +%<latexrelease> } % \end{macrocode} % And here is the original definition of \cs{end} the way it was in % \LaTeX{} for several decades now hidden in \verb*=\end =. % \begin{macrocode} -\@namedef{end }#1{% - \csname end#1\endcsname\@checkend{#1}% - \expandafter\endgroup\if@endpe\@doendpe\fi - \if@ignore\@ignorefalse\ignorespaces\fi} -%</2ekernel|latexrelease> +%<latexrelease>\@namedef{end }#1{% +%<latexrelease> \csname end#1\endcsname\@checkend{#1}% +%<latexrelease> \expandafter\endgroup\if@endpe\@doendpe\fi +%<latexrelease> \if@ignore\@ignorefalse\ignorespaces\fi} %<latexrelease>\EndIncludeInRelease % \end{macrocode} % An here the rollback in case that is ever needed. % \begin{macrocode} %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\begin}{Making \begin/\end robust}% -%<latexrelease>\kernel@make@fragile\begin -%<latexrelease>\kernel@make@fragile\end +%<latexrelease>\def\begin#1{% +%<latexrelease> \@ifundefined{#1}% +%<latexrelease> {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% +%<latexrelease> {\def\reserved@a{\def\@currenvir{#1}% +%<latexrelease> \edef\@currenvline{\on@line}% +%<latexrelease> \csname #1\endcsname}}% +%<latexrelease> \@ignorefalse +%<latexrelease> \begingroup\@endpefalse\reserved@a} +%<latexrelease>\def\end#1{% +%<latexrelease> \csname end#1\endcsname\@checkend{#1}% +%<latexrelease> \expandafter\endgroup\if@endpe\@doendpe\fi +%<latexrelease> \if@ignore\@ignorefalse\ignorespaces\fi} %<latexrelease> %<latexrelease>\EndIncludeInRelease %<*2ekernel> @@ -674,6 +880,47 @@ % \end{macro} % % +% +% \begin{macro}{\AtBeginEnvironment,\AtEndEnvironment, +% \BeforeBeginEnvironment,\AfterEndEnvironment} +% +% We provide 4 high-level hook interfaces directly, the others only when +% etoolbox is loaded +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\AtBeginEnvironment}{Hooks for environments}% +% \end{macrocode} +% +% \begin{macrocode} +\newcommand\AtBeginEnvironment[2][.] {\AddToHook{env/#2/begin}[#1]} +\newcommand\AtEndEnvironment[2][.] {\AddToHook{env/#2/end}[#1]} +\newcommand\BeforeBeginEnvironment[2][.]{\AddToHook{env/#2/before}[#1]} +\newcommand\AfterEndEnvironment[2][.] {\AddToHook{env/#2/after}[#1]} +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\AtBeginEnvironment}{Hooks for environments}% +%<latexrelease> +%<latexrelease>\let\AtBeginEnvironment\@undefined +%<latexrelease>\let\AtEndEnvironment\@undefined +%<latexrelease>\let\BeforeBeginEnvironment\@undefined +%<latexrelease>\let\AfterEndEnvironment\@undefined +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% % \subsection{Center, Flushright, Flushleft} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx index 59c20f37700..c6bfc149b7c 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx @@ -37,14 +37,14 @@ %<TS1>\ProvidesFile{ts1enc.def}[2001/06/05 v3.0e (jk/car/fm) %<TU>\ProvidesFile{tuenc.def} %<package>\ProvidesPackage{fontenc} -%<OT1|T1|OMS|OML|OT4|TU|package> [2020/04/22 v2.0p +%<OT1|T1|OMS|OML|OT4|TU|package> [2020/08/10 v2.0s %<OT1|T1|OMS|OML|OT4|TS1|TU> Standard LaTeX file] %<package> Standard LaTeX package] % %<*driver> % \fi \ProvidesFile{ltoutenc.dtx} - [2021/07/04 v2.0q LaTeX Kernel (font encodings)] + [2020/08/10 v2.0s LaTeX Kernel (font encodings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutenc.dtx} @@ -1082,8 +1082,9 @@ % deficiencies, see pr/3160. % \task{?}{Improve this and document its problems, see pr/3160} % \changes{v1.9z}{2000/01/30}{Macro reimplemented (pr/3160)} +% \changes{v2.0r}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\UseTextAccent[3]{% +\DeclareRobustCommand*\UseTextAccent[3]{% \hmode@start@before@group {% % \end{macrocode} @@ -1098,8 +1099,9 @@ % \end{macrocode} % % \changes{v1.9z}{2000/01/30}{Macro reimplemented (pr/3160)} +% \changes{v2.0r}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\UseTextSymbol[2]{% +\DeclareRobustCommand*\UseTextSymbol[2]{% \hmode@start@before@group {% \def\@wrong@font@char{\MessageBreak @@ -2899,12 +2901,6 @@ \else \newluafunction\@remove@tlig@@@@ % \end{macrocode} -% We are in the format and Lua functions can not be dumped, so we have to repeat -% the code during |\everyjob|. Therefore we first define a helper to both execute -% some code and same it for |\everyjob|: -% \begin{macrocode} - \def\now@and@everyjob#1{\toksapp\everyjob{#1}#1} -% \end{macrocode} % Now we can define the function. Mostly we just have to insert a protected glyph % node, which is a glyph node with subtype 256. But we have to keep track of the % current mode to avoid inserting the glyph into a vlist. diff --git a/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx index c3b27baf42d..35d049b9590 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltoutput.dtx} - [2019/08/27 v1.4e LaTeX Kernel (Output Routine)] + [2020/08/21 v1.4f LaTeX Kernel (Output Routine)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutput.dtx} @@ -791,12 +791,17 @@ % % The stuff in the box should not add any typeset material to the % page when it is unboxed. +% +% This interface is no longer used. Instead a new one is inside +% \texttt{ltshipout.dtx}. We only keep the box in case some old +% code refers to it directly (or we do some rollback). +% \changes{v1.4f}{2020/08/21}{Integration of new hook management interface} % \begin{macrocode} \newbox\@begindvibox -\DeclareRobustCommand \AtBeginDvi [1]{% - \global \setbox \@begindvibox - \vbox{\unvbox \@begindvibox #1}% -} +%\DeclareRobustCommand \AtBeginDvi [1]{% +% \global \setbox \@begindvibox +% \vbox{\unvbox \@begindvibox #1}% +%} % \end{macrocode} % \end{macro} % \end{macro} diff --git a/Master/texmf-dist/source/latex-dev/base/ltpage.dtx b/Master/texmf-dist/source/latex-dev/base/ltpage.dtx index f926f330605..8c7aac0a7b8 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltpage.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltpage.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltpage.dtx} - [2019/08/27 v1.0l LaTeX Kernel (page style setup)] + [2020/07/27 v1.0m LaTeX Kernel (page style setup)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpage.dtx} @@ -201,8 +201,9 @@ % expansion, CAR} % \changes{v1.0j}{2000/05/26}{Reimplementation to fix expansion % error (pr/3203).} +% \changes{v1.0m}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\markboth[2]{% +\DeclareRobustCommand*\markboth[2]{% \begingroup \let\label\relax \let\index\relax \let\glossary\relax \unrestored@protected@xdef\@themark {{#1}{#2}}% @@ -212,8 +213,9 @@ \if@nobreak\ifvmode\nobreak\fi\fi} % \end{macrocode} % +% \changes{v1.0m}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\markright[1]{% +\DeclareRobustCommand*\markright[1]{% \begingroup \let\label\relax \let\index\relax \let\glossary\relax % \end{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx b/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx index bdac744e831..5bef40375cd 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltpictur.dtx} - [2020/05/12 v1.1o LaTeX Kernel (Picture Mode)] + [2020/08/14 v1.2a LaTeX Kernel (Picture Mode)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpictur.dtx} @@ -191,6 +191,45 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\@defaultunitsset} +% \changes{v1.2a}{2020/08/15}{Macro added} +% Set a length register, |#1|, +% accepting number or an etex length expression, |#2|, +% with default unit, |#3|. +% +% The register name in |#1| can be prefixed by |\advance| so that +% the register is incremented by the supplied value. +% +% |\@defaultunitsset{\advance\@vxx}{\textwidth-15pt}\unitlength| +% +% |#3| can be a literal unit such as |cm| or a length register such +% as |\unitlength|. +% +% This is used in all |picture| commands that take picture coordinates. +% So |\put(2,2)| as previously but now |\put(\textwidth-5cm,0.4\texteight)| +% Note that you can only use expressions with lengths, |\put(1+2,0)| is not +% supported. +% +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@defaultunitsset}{default units}% +\def\@defaultunitsset#1#2#3{% + \@defaultunits#1\dimexpr#2#3\relax\relax\@nnil} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@defaultunitsset}{default units}% +%<latexrelease>\let\@defaultunitsset\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% % \begin{environment}{picture} % \begin{macro}{\picture} % \changes{v0.1c}{1994/04/28}{(DPC) Ignore spaces before (} @@ -208,12 +247,34 @@ % % \begin{macro}{\@picture} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@picture}{default units}% \def\@picture(#1,#2)(#3,#4){% - \@picht#2\unitlength - \setbox\@picbox\hb@xt@#1\unitlength\bgroup - \hskip -#3\unitlength - \lower #4\unitlength\hbox\bgroup + \@defaultunitsset\@picht{#2}\unitlength + \@defaultunitsset\@tempdimc{#1}\unitlength + \setbox\@picbox\hb@xt@\@tempdimc\bgroup + \@defaultunitsset\@tempdimc{#3}\unitlength + \hskip -\@tempdimc + \@defaultunitsset\@tempdimc{#4}\unitlength + \lower\@tempdimc\hbox\bgroup \ignorespaces} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@picture}{default units}% +%<latexrelease>\def\@picture(#1,#2)(#3,#4){% +%<latexrelease> \@picht#2\unitlength +%<latexrelease> \setbox\@picbox\hb@xt@#1\unitlength\bgroup +%<latexrelease> \hskip -#3\unitlength +%<latexrelease> \lower #4\unitlength\hbox\bgroup +%<latexrelease> \ignorespaces} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -237,10 +298,34 @@ % changed 20 Jul 87). % % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\put}{default units}% +%<latexrelease>\expandafter\let\csname put \endcsname\@undefind \long\def\put(#1,#2)#3{% - \@killglue\raise#2\unitlength - \hb@xt@\z@{\kern#1\unitlength #3\hss}% + \@killglue + \@defaultunitsset\@tempdimc{#2}\unitlength + \raise\@tempdimc + \hb@xt@\z@{% + \@defaultunitsset\@tempdimc{#1}\unitlength + \kern\@tempdimc + #3\hss}% \ignorespaces} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\put}{default units}% +%<latexrelease>\expandafter\let\csname put \endcsname\@undefind +%<latexrelease>\long\def\put(#1,#2)#3{% +%<latexrelease> \@killglue\raise#2\unitlength +%<latexrelease> \hb@xt@\z@{\kern#1\unitlength #3\hss}% +%<latexrelease> \ignorespaces} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % % @@ -248,23 +333,63 @@ % \changes{v0.1c}{1994/04/28}{(DPC) Ignore spaces between )(} % |#3| had better be a |(|. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\multiput}{default units}% +%<latexrelease>\expandafter\let\csname multiput \endcsname\@undefind \def\multiput(#1,#2)#3{% - \@xdim #1\unitlength - \@ydim #2\unitlength + \@defaultunitsset\@xdim{#1}\unitlength + \@defaultunitsset\@ydim{#2}\unitlength \@multiput(} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\multiput}{default units}% +%<latexrelease>\expandafter\let\csname multiput \endcsname\@undefind +%<latexrelease>\def\multiput(#1,#2)#3{% +%<latexrelease> \@xdim #1\unitlength +%<latexrelease> \@ydim #2\unitlength +%<latexrelease> \@multiput(} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % -% \begin{macro}{\multiput} +% \begin{macro}{\@multiput} % \changes{v0.1c}{1994/04/28}{(DPC) Macro added} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@multiput}{default units}% \long\def\@multiput(#1,#2)#3#4{% \@killglue\@multicnt #3\relax \@whilenum \@multicnt >\z@\do {\raise\@ydim\hb@xt@\z@{\kern\@xdim #4\hss}% \advance\@multicnt\m@ne - \advance\@xdim#1\unitlength\advance\@ydim#2\unitlength}% + \@defaultunitsset{\advance\@xdim}{#1}\unitlength + \@defaultunitsset{\advance\@ydim}{#2}\unitlength}% \ignorespaces} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@multiput}{default units}% +%<latexrelease>\long\def\@multiput(#1,#2)#3#4{% +%<latexrelease> \@killglue\@multicnt #3\relax +%<latexrelease> \@whilenum \@multicnt >\z@\do +%<latexrelease> {\raise\@ydim\hb@xt@\z@{\kern\@xdim #4\hss}% +%<latexrelease> \advance\@multicnt\m@ne +%<latexrelease> \advance\@xdim#1\unitlength\advance\@ydim#2\unitlength}% +%<latexrelease> \ignorespaces} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -289,8 +414,9 @@ % % \begin{macro}{\linethickness} % \changes{v1.1n}{2020/02/14}{Suppress spaces following the declaration (gh/274)} +% \changes{v1.1p}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\linethickness[1] +\DeclareRobustCommand*\linethickness[1] {\@wholewidth #1\relax \@halfwidth .5\@wholewidth \ignorespaces} % \end{macrocode} % \end{macro} @@ -531,13 +657,35 @@ % % \begin{macro}{\line} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\line}{default units}% +%<latexrelease>\expandafter\let\csname line \endcsname\@undefind \def\line(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax - \@linelen #3\unitlength + \@defaultunitsset\@linelen{#3}\unitlength \ifdim\@linelen<\z@\@badlinearg\else \ifnum\@xarg =\z@ \@vline \else \ifnum\@yarg =\z@ \@hline \else \@sline\fi \fi \fi} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\line}{default units}% +%<latexrelease>\expandafter\let\csname line \endcsname\@undefind +%<latexrelease>\def\line(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax +%<latexrelease> \@linelen #3\unitlength +%<latexrelease> \ifdim\@linelen<\z@\@badlinearg\else +%<latexrelease> \ifnum\@xarg =\z@ \@vline +%<latexrelease> \else \ifnum\@yarg =\z@ \@hline \else \@sline\fi +%<latexrelease> \fi +%<latexrelease> \fi} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -621,16 +769,41 @@ % % \begin{macro}{\vector} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\vector}{default units}% +%<latexrelease>\expandafter\let\csname vector \endcsname\@undefind \def\vector(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax \@tempcnta \ifnum\@xarg<\z@ -\@xarg\else\@xarg\fi \ifnum\@tempcnta<5\relax - \@linelen #3\unitlength + \@defaultunitsset\@linelen{#3}\unitlength \ifdim\@linelen<\z@\@badlinearg\else \ifnum\@xarg =\z@ \@vvector \else \ifnum\@yarg =\z@ \@hvector \else \@svector\fi \fi \fi \else\@badlinearg\fi} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\vector}{default units}% +%<latexrelease>\expandafter\let\csname vector \endcsname\@undefind +%<latexrelease>\def\vector(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax +%<latexrelease> \@tempcnta \ifnum\@xarg<\z@ -\@xarg\else\@xarg\fi +%<latexrelease> \ifnum\@tempcnta<5\relax +%<latexrelease> \@linelen #3\unitlength +%<latexrelease> \ifdim\@linelen<\z@\@badlinearg\else +%<latexrelease> \ifnum\@xarg =\z@ \@vvector +%<latexrelease> \else \ifnum\@yarg =\z@ \@hvector \else \@svector\fi +%<latexrelease> \fi +%<latexrelease> \fi +%<latexrelease> \else\@badlinearg\fi} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -824,11 +997,17 @@ % % \begin{macro}{\dashbox} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\dashbox}{default units}% +%<latexrelease>\expandafter\let\csname dashbox \endcsname\@undefind \def\dashbox#1(#2,#3){\leavevmode\hb@xt@\z@{\baselineskip \z@skip \lineskip \z@skip -\@dashdim #2\unitlength +\@defaultunitsset\@dashdim{#2}\unitlength \@dashcnt \@dashdim \advance\@dashcnt 200 -\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +\@defaultunitsset\@dashdim{#1}\unitlength +\divide\@dashcnt \@dashdim \ifodd\@dashcnt\@dashdim \z@ \advance\@dashcnt \@ne \divide\@dashcnt \tw@ \else \divide\@dashdim \tw@ \divide\@dashcnt \tw@ @@ -840,15 +1019,19 @@ \put(#2,#3){\hskip-\@dashdim\box\@dashbox}% \multiply\@dashdim \thr@@ \fi -\setbox\@dashbox \hbox{\vrule \@height \@halfwidth \@depth \@halfwidth -\@width #1\unitlength\hskip #1\unitlength}\@tempcnta\z@ +\setbox\@dashbox \hbox{% + \@defaultunitsset\@tempdimc{#1}\unitlength + \vrule \@height \@halfwidth \@depth \@halfwidth \@width \@tempdimc + \hskip\@tempdimc}% +\@tempcnta\z@ \put(0,0){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt \do{\copy\@dashbox\advance\@tempcnta \@ne }}\@tempcnta\z@ \put(0,#3){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt \do{\copy\@dashbox\advance\@tempcnta \@ne }}% -\@dashdim #3\unitlength +\@defaultunitsset\@dashdim{#3}\unitlength \@dashcnt \@dashdim \advance\@dashcnt 200 -\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +\@defaultunitsset\@dashdim{#1}\unitlength +\divide\@dashcnt \@dashdim \ifodd\@dashcnt \@dashdim \z@ \advance\@dashcnt \@ne \divide\@dashcnt \tw@ \else @@ -862,14 +1045,79 @@ \put(#2,#3){\lower\@dashdim\copy\@dashbox}% \multiply\@dashdim \thr@@ \fi -\setbox\@dashbox\hbox{\vrule \@width \@wholewidth -\@height #1\unitlength}\@tempcnta\z@ +\@defaultunitsset\@tempdimb{#1}\unitlength +\setbox\@dashbox\hbox{% + \vrule \@width \@wholewidth \@height\@tempdimb}% +\@tempcnta\z@ \put(0,0){\hskip -\@halfwidth \vbox{\@whilenum \@tempcnta <\@dashcnt -\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta \@ne }% +\do{\vskip\@tempdimb\copy\@dashbox\advance\@tempcnta \@ne }% \vskip\@dashdim}}\@tempcnta\z@ \put(#2,0){\hskip -\@halfwidth \vbox{\@whilenum \@tempcnta<\@dashcnt -\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta \@ne }% +\do{\vskip\@tempdimb\copy\@dashbox\advance\@tempcnta \@ne }% \vskip\@dashdim}}}\@makepicbox(#2,#3)} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\dashbox}{default units}% +%<latexrelease>\expandafter\let\csname dashbox \endcsname\@undefind +%<latexrelease>\def\dashbox#1(#2,#3){% +%<latexrelease>\leavevmode\hb@xt@\z@{\baselineskip \z@skip +%<latexrelease>\lineskip \z@skip +%<latexrelease>\@dashdim #2\unitlength +%<latexrelease>\@dashcnt \@dashdim \advance\@dashcnt 200 +%<latexrelease>\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +%<latexrelease>\ifodd\@dashcnt\@dashdim \z@ +%<latexrelease>\advance\@dashcnt \@ne \divide\@dashcnt \tw@ +%<latexrelease>\else \divide\@dashdim \tw@ \divide\@dashcnt \tw@ +%<latexrelease>\advance\@dashcnt \m@ne +%<latexrelease>\setbox\@dashbox \hbox{% +%<latexrelease> \vrule \@height \@halfwidth \@depth \@halfwidth +%<latexrelease> \@width \@dashdim}\put(0,0){\copy\@dashbox}% +%<latexrelease>\put(0,#3){\copy\@dashbox}% +%<latexrelease>\put(#2,0){\hskip-\@dashdim\copy\@dashbox}% +%<latexrelease>\put(#2,#3){\hskip-\@dashdim\box\@dashbox}% +%<latexrelease>\multiply\@dashdim \thr@@ +%<latexrelease>\fi +%<latexrelease>\setbox\@dashbox \hbox{% +%<latexrelease> \vrule \@height \@halfwidth \@depth \@halfwidth +%<latexrelease> \@width #1\unitlength\hskip #1\unitlength}\@tempcnta\z@ +%<latexrelease>\put(0,0){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt +%<latexrelease>\do{\copy\@dashbox\advance\@tempcnta \@ne }}\@tempcnta\z@ +%<latexrelease>\put(0,#3){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt +%<latexrelease>\do{\copy\@dashbox\advance\@tempcnta \@ne }}% +%<latexrelease>\@dashdim #3\unitlength +%<latexrelease>\@dashcnt \@dashdim \advance\@dashcnt 200 +%<latexrelease>\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +%<latexrelease>\ifodd\@dashcnt \@dashdim \z@ +%<latexrelease>\advance\@dashcnt \@ne \divide\@dashcnt \tw@ +%<latexrelease>\else +%<latexrelease>\divide\@dashdim \tw@ \divide\@dashcnt \tw@ +%<latexrelease>\advance\@dashcnt \m@ne +%<latexrelease>\setbox\@dashbox\hbox{\hskip -\@halfwidth +%<latexrelease>\vrule \@width \@wholewidth +%<latexrelease>\@height \@dashdim}\put(0,0){\copy\@dashbox}% +%<latexrelease>\put(#2,0){\copy\@dashbox}% +%<latexrelease>\put(0,#3){\lower\@dashdim\copy\@dashbox}% +%<latexrelease>\put(#2,#3){\lower\@dashdim\copy\@dashbox}% +%<latexrelease>\multiply\@dashdim \thr@@ +%<latexrelease>\fi +%<latexrelease>\setbox\@dashbox\hbox{\vrule \@width \@wholewidth +%<latexrelease>\@height #1\unitlength}\@tempcnta\z@ +%<latexrelease>\put(0,0){% +%<latexrelease> \hskip -\@halfwidth \vbox{\@whilenum \@tempcnta <\@dashcnt +%<latexrelease> \do{\vskip #1\unitlength\copy\@dashbox +%<latexrelease> \advance\@tempcnta\@ne }% +%<latexrelease> \vskip\@dashdim}}\@tempcnta\z@ +%<latexrelease>\put(#2,0){% +%<latexrelease> \hskip -\@halfwidth \vbox{\@whilenum \@tempcnta<\@dashcnt +%<latexrelease> \do{\vskip #1\unitlength\copy\@dashbox +%<latexrelease> \advance\@tempcnta \@ne }% +%<latexrelease> \vskip\@dashdim}}}\@makepicbox(#2,#3)} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1164,12 +1412,26 @@ % \begin{macrocode} \newif\if@ovvline \@ovvlinetrue \newif\if@ovhline \@ovhlinetrue +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@ovhlinetrue}% +%<latexrelease> {Avoid almost zero length leaders}% +%<latexrelease>\let\if@ovvline\@undefined +%<latexrelease>\let\if@ovhline\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\@oval} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@oval}{default units}% \def\@oval(#1,#2)[#3]{\begingroup\boxmaxdepth \maxdimen \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue % \end{macrocode} @@ -1178,9 +1440,10 @@ \@ovvlinefalse \@ovhlinefalse % \end{macrocode} % \begin{macrocode} - \@tfor\reserved@a :=#3\do{\csname @ov\reserved@a false\endcsname}% - \@ovxx #1\unitlength - \@ovyy #2\unitlength + \@tfor\reserved@a :=#3\do{% + \csname @ov\reserved@a false\endcsname}% + \@defaultunitsset\@ovxx{#1}\unitlength + \@defaultunitsset\@ovyy{#2}\unitlength % \end{macrocode} % \changes{v1.1l}{2016/03/29}{add setting of line tests} % \begin{macrocode} @@ -1208,11 +1471,79 @@ \advance\@ovdy\@ovro \ht\@tempboxa\z@ \dp\@tempboxa\z@ \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}% \endgroup} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2016/03/31}% +%<latexrelease> {\@oval}{default units}% +%<latexrelease>\def\@oval(#1,#2)[#3]{\begingroup\boxmaxdepth \maxdimen +%<latexrelease> \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue +%<latexrelease> \@ovvlinefalse \@ovhlinefalse +%<latexrelease> \@tfor\reserved@a :=#3\do{% +%<latexrelease> \csname @ov\reserved@a false\endcsname}% +%<latexrelease> \@ovxx #1\unitlength +%<latexrelease> \@ovyy #2\unitlength +%<latexrelease> \@tempdimb \ifdim \@ovyy >\@ovxx \@ovxx \@ovvlinetrue +%<latexrelease> \else \@ovyy \ifdim \@ovyy =\@ovxx \else \@ovhlinetrue +%<latexrelease> \fi\fi +%<latexrelease> \advance \@tempdimb -2\p@ +%<latexrelease> \@getcirc \@tempdimb +%<latexrelease> \@ovro \ht\@tempboxa \@ovri \dp\@tempboxa +%<latexrelease> \@ovdx\@ovxx \advance\@ovdx -\@tempdima \divide\@ovdx \tw@ +%<latexrelease> \@ovdy\@ovyy \advance\@ovdy -\@tempdima \divide\@ovdy \tw@ +%<latexrelease> \ifdim \@ovdx >\z@ \@ovhlinetrue \fi +%<latexrelease> \ifdim \@ovdy >\z@ \@ovvlinetrue \fi +%<latexrelease> \@circlefnt \setbox\@tempboxa +%<latexrelease> \hbox{\if@ovr \@ovvert32\kern -\@tempdima \fi +%<latexrelease> \if@ovl +%<latexrelease> \kern \@ovxx \@ovvert01\kern -\@tempdima \kern -\@ovxx +%<latexrelease> \fi +%<latexrelease> \if@ovt \@ovhorz \kern -\@ovxx \fi +%<latexrelease> \if@ovb \raise \@ovyy \@ovhorz \fi}\advance\@ovdx\@ovro +%<latexrelease> \advance\@ovdy\@ovro \ht\@tempboxa\z@ \dp\@tempboxa\z@ +%<latexrelease> \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}% +%<latexrelease> \endgroup} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@oval}{default units}% +%<latexrelease>\def\@oval(#1,#2)[#3]{\begingroup\boxmaxdepth \maxdimen +%<latexrelease> \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue +%<latexrelease> \@tfor\reserved@a :=#3\do +%<latexrelease> {\csname @ov\reserved@a false\endcsname}% +%<latexrelease> \@ovxx #1\unitlength +%<latexrelease> \@ovyy #2\unitlength +%<latexrelease> \@tempdimb \ifdim \@ovyy >\@ovxx \@ovxx\else \@ovyy \fi +%<latexrelease> \advance \@tempdimb -2\p@ +%<latexrelease> \@getcirc \@tempdimb +%<latexrelease> \@ovro \ht\@tempboxa \@ovri \dp\@tempboxa +%<latexrelease> \@ovdx\@ovxx \advance\@ovdx -\@tempdima \divide\@ovdx \tw@ +%<latexrelease> \@ovdy\@ovyy \advance\@ovdy -\@tempdima \divide\@ovdy \tw@ +%<latexrelease> \@circlefnt \setbox\@tempboxa +%<latexrelease> \hbox{\if@ovr \@ovvert32\kern -\@tempdima \fi +%<latexrelease> \if@ovl +%<latexrelease> \kern \@ovxx \@ovvert01\kern -\@tempdima \kern -\@ovxx +%<latexrelease> \fi +%<latexrelease> \if@ovt \@ovhorz \kern -\@ovxx \fi +%<latexrelease> \if@ovb \raise \@ovyy \@ovhorz \fi}\advance\@ovdx\@ovro +%<latexrelease> \advance\@ovdy\@ovro \ht\@tempboxa\z@ \dp\@tempboxa\z@ +%<latexrelease> \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}% +%<latexrelease> \endgroup} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % % \begin{macro}{\@ovvert} % \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2016/03/31}% +%<latexrelease> {\@ovvert}{Avoid almost zero length leaders}% +%<*2ekernel|latexrelease> \def\@ovvert#1#2{\vbox to\@ovyy{% \if@ovb \@tempcntb \@tempcnta \advance \@tempcntb #1\relax \kern -\@ovro \hbox{\char \@tempcntb}\nointerlineskip @@ -1228,11 +1559,32 @@ \if@ovt \@tempcntb \@tempcnta \advance \@tempcntb #2\relax \hbox{\char \@tempcntb}% \else \kern \@ovdy \kern \@ovro \fi}} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@ovvert}{Avoid almost zero length leaders}% +%<latexrelease>\def\@ovvert#1#2{\vbox to\@ovyy{% +%<latexrelease> \if@ovb \@tempcntb \@tempcnta \advance \@tempcntb #1\relax +%<latexrelease> \kern -\@ovro \hbox{\char \@tempcntb}\nointerlineskip +%<latexrelease> \else \kern \@ovri \kern \@ovdy \fi +%<latexrelease> \leaders\vrule \@width \@wholewidth\vfil \nointerlineskip +%<latexrelease> \if@ovt \@tempcntb \@tempcnta \advance \@tempcntb #2\relax +%<latexrelease> \hbox{\char \@tempcntb}% +%<latexrelease> \else \kern \@ovdy \kern \@ovro \fi}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % % \begin{macro}{\@ovhorz} % \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2016/03/31}% +%<latexrelease> {\@ovhorz}{Avoid almost zero length leaders}% +%<*2ekernel|latexrelease> \def\@ovhorz{\hb@xt@\@ovxx{\kern \@ovro \if@ovr \else \kern \@ovdx \fi % \end{macrocode} @@ -1241,51 +1593,18 @@ % \begin{macrocode} \if@ovhline \leaders \hrule \@height \@wholewidth \fi % \end{macrocode} +% % \begin{macrocode} \hfil \if@ovl \else \kern \@ovdx \fi \kern \@ovri}} +%</2ekernel|latexrelease> % \end{macrocode} -% \end{macro} -% +% % \begin{macrocode} -%</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\@ovhlinetrue}% -%<latexrelease> {Avoid almost zero length leaders}% -%<latexrelease>\let\if@ovvline\@undefined -%<latexrelease>\let\if@ovhline\@undefined -%<latexrelease>\def\@oval(#1,#2)[#3]{\begingroup\boxmaxdepth \maxdimen -%<latexrelease> \@ovttrue \@ovbtrue \@ovltrue \@ovrtrue -%<latexrelease> \@tfor\reserved@a :=#3\do -%<latexrelease> {\csname @ov\reserved@a false\endcsname}% -%<latexrelease> \@ovxx #1\unitlength -%<latexrelease> \@ovyy #2\unitlength -%<latexrelease> \@tempdimb \ifdim \@ovyy >\@ovxx \@ovxx\else \@ovyy \fi -%<latexrelease> \advance \@tempdimb -2\p@ -%<latexrelease> \@getcirc \@tempdimb -%<latexrelease> \@ovro \ht\@tempboxa \@ovri \dp\@tempboxa -%<latexrelease> \@ovdx\@ovxx \advance\@ovdx -\@tempdima \divide\@ovdx \tw@ -%<latexrelease> \@ovdy\@ovyy \advance\@ovdy -\@tempdima \divide\@ovdy \tw@ -%<latexrelease> \@circlefnt \setbox\@tempboxa -%<latexrelease> \hbox{\if@ovr \@ovvert32\kern -\@tempdima \fi -%<latexrelease> \if@ovl -%<latexrelease> \kern \@ovxx \@ovvert01\kern -\@tempdima \kern -\@ovxx -%<latexrelease> \fi -%<latexrelease> \if@ovt \@ovhorz \kern -\@ovxx \fi -%<latexrelease> \if@ovb \raise \@ovyy \@ovhorz \fi}\advance\@ovdx\@ovro -%<latexrelease> \advance\@ovdy\@ovro \ht\@tempboxa\z@ \dp\@tempboxa\z@ -%<latexrelease> \@put{-\@ovdx}{-\@ovdy}{\box\@tempboxa}% -%<latexrelease> \endgroup} -%<latexrelease>\def\@ovvert#1#2{\vbox to\@ovyy{% -%<latexrelease> \if@ovb \@tempcntb \@tempcnta \advance \@tempcntb #1\relax -%<latexrelease> \kern -\@ovro \hbox{\char \@tempcntb}\nointerlineskip -%<latexrelease> \else \kern \@ovri \kern \@ovdy \fi -%<latexrelease> \leaders\vrule \@width \@wholewidth\vfil \nointerlineskip -%<latexrelease> \if@ovt \@tempcntb \@tempcnta \advance \@tempcntb #2\relax -%<latexrelease> \hbox{\char \@tempcntb}% -%<latexrelease> \else \kern \@ovdy \kern \@ovro \fi}} +%<latexrelease> {\@ovhorz}{Avoid almost zero length leaders}% %<latexrelease>\def\@ovhorz{\hb@xt@\@ovxx{\kern \@ovro %<latexrelease> \if@ovr \else \kern \@ovdx \fi %<latexrelease> \leaders \hrule \@height \@wholewidth \hfil @@ -1294,6 +1613,7 @@ %<latexrelease>\EndIncludeInRelease %<*2ekernel> % \end{macrocode} +% \end{macro} % % \begin{macro}{\circle} % \changes{LaTeX2.09}{1993/08/05} @@ -1305,8 +1625,13 @@ % % \begin{macro}{\@circle} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@circle}{default units}% \def\@circle#1{% - \begingroup \boxmaxdepth \maxdimen \@tempdimb #1\unitlength + \begingroup \boxmaxdepth \maxdimen + \@defaultunitsset\@tempdimb{#1}\unitlength \ifdim \@tempdimb >15.5\p@ \@getcirc\@tempdimb \@ovro\ht\@tempboxa \setbox\@tempboxa\hbox{\@circlefnt @@ -1317,13 +1642,52 @@ \box\@tempboxa}\ht\@tempboxa\z@ \dp\@tempboxa\z@ \@put{-\@ovro}{-\@ovro}{\box\@tempboxa}% \else \@circ\@tempdimb{96}\fi\endgroup} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@circle}{default units}% +%<latexrelease>\def\@circle#1{% +%<latexrelease> \begingroup \boxmaxdepth \maxdimen \@tempdimb #1\unitlength +%<latexrelease> \ifdim \@tempdimb >15.5\p@ \@getcirc\@tempdimb +%<latexrelease> \@ovro\ht\@tempboxa +%<latexrelease> \setbox\@tempboxa\hbox{\@circlefnt +%<latexrelease> \advance\@tempcnta\tw@ \char \@tempcnta +%<latexrelease> \advance\@tempcnta\m@ne \char \@tempcnta +%<latexrelease> \kern -2\@tempdima +%<latexrelease> \advance\@tempcnta\tw@ +%<latexrelease> \raise \@tempdima \hbox{\char\@tempcnta}% +%<latexrelease> \raise \@tempdima +%<latexrelease> \box\@tempboxa}\ht\@tempboxa\z@ \dp\@tempboxa\z@ +%<latexrelease> \@put{-\@ovro}{-\@ovro}{\box\@tempboxa}% +%<latexrelease> \else \@circ\@tempdimb{96}\fi\endgroup} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % % \begin{macro}{\@dot} % Internal form of |\circle*|. % \begin{macrocode} -\def\@dot#1{\@tempdimb #1\unitlength \@circ\@tempdimb{112}} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@dot}{default units}% +\def\@dot#1{% + \@defaultunitsset\@tempdimb{#1}\unitlength + \@circ\@tempdimb{112}} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@dot}{default units}% +%<latexrelease>\def\@dot#1{\@tempdimb #1\unitlength \@circ\@tempdimb{112}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1503,35 +1867,45 @@ % % \begin{macro}{\@bezier} % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\@bezier}{default units}% \def\@bezier#1(#2,#3)(#4,#5)(#6,#7){% \ifnum #1=\z@ - \@ovxx #4\unitlength - \advance\@ovxx -#2\unitlength + \@defaultunitsset\@ovxx{#4}\unitlength + \@defaultunitsset{\advance\@ovxx}{-#2}\unitlength \ifdim \@ovxx<\z@ \@ovxx -\@ovxx \fi - \@ovdx #6\unitlength - \advance\@ovdx -#4\unitlength + \@defaultunitsset\@ovdx{#6}\unitlength + \@defaultunitsset{\advance\@ovdx}{-#4}\unitlength \ifdim \@ovdx<\z@ \@ovdx -\@ovdx \fi \ifdim \@ovxx<\@ovdx \@ovxx \@ovdx \fi - \@ovyy #5\unitlength - \advance\@ovyy -#3\unitlength + \@defaultunitsset\@ovyy{#5}\unitlength + \@defaultunitsset{\advance\@ovyy}{-#3}\unitlength \ifdim \@ovyy<\z@ \@ovyy -\@ovyy \fi - \@ovdy #7\unitlength - \advance\@ovdy -#5\unitlength + \@defaultunitsset\@ovdy{#7}\unitlength + \@defaultunitsset{\advance\@ovdy}{-#5}\unitlength \ifdim \@ovdy<\z@ \@ovdy -\@ovdy \fi \ifdim \@ovyy<\@ovdy \@ovyy \@ovdy \fi \@multicnt \ifdim \@ovxx>\@ovyy \@ovxx \else \@ovyy \fi \@ovxx .5\@halfwidth \divide\@multicnt\@ovxx - \ifnum \qbeziermax<\@multicnt \@multicnt\qbeziermax\relax \fi + \ifnum \qbeziermax<\@multicnt + \@multicnt\qbeziermax\relax + \fi \else \@multicnt#1\relax \fi \@tempcnta\@multicnt \advance\@tempcnta\@ne - \@ovdx #4\unitlength \advance\@ovdx -#2\unitlength + \@defaultunitsset\@ovdx{#4}\unitlength + \@defaultunitsset{\advance\@ovdx}{-#2}\unitlength \multiply\@ovdx \tw@ - \@ovxx #6\unitlength \advance\@ovxx -#2\unitlength + \@defaultunitsset\@ovxx{#6}\unitlength + \@defaultunitsset{\advance\@ovxx}{-#2}\unitlength \advance\@ovxx -\@ovdx \divide\@ovxx\@multicnt - \@ovdy #5\unitlength \advance\@ovdy -#3\unitlength + \@defaultunitsset\@ovdy{#5}\unitlength + \@defaultunitsset{\advance\@ovdy}{-#3}\unitlength \multiply\@ovdy \tw@ - \@ovyy #7\unitlength \advance\@ovyy -#3\unitlength + \@defaultunitsset\@ovyy{#7}\unitlength + \@defaultunitsset{\advance\@ovyy}{-#3}\unitlength \advance\@ovyy -\@ovdy \divide\@ovyy\@multicnt % \end{macrocode} % @@ -1557,6 +1931,67 @@ \hb@xt@\z@{\kern\@xdim \unhcopy\@tempboxa\hss}% \advance\count@\@ne}}} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@bezier}{default units}% +%<latexrelease>\def\@bezier#1(#2,#3)(#4,#5)(#6,#7){% +%<latexrelease> \ifnum #1=\z@ +%<latexrelease> \@ovxx #4\unitlength +%<latexrelease> \advance\@ovxx -#2\unitlength +%<latexrelease> \ifdim \@ovxx<\z@ \@ovxx -\@ovxx \fi +%<latexrelease> \@ovdx #6\unitlength +%<latexrelease> \advance\@ovdx -#4\unitlength +%<latexrelease> \ifdim \@ovdx<\z@ \@ovdx -\@ovdx \fi +%<latexrelease> \ifdim \@ovxx<\@ovdx \@ovxx \@ovdx \fi +%<latexrelease> \@ovyy #5\unitlength +%<latexrelease> \advance\@ovyy -#3\unitlength +%<latexrelease> \ifdim \@ovyy<\z@ \@ovyy -\@ovyy \fi +%<latexrelease> \@ovdy #7\unitlength +%<latexrelease> \advance\@ovdy -#5\unitlength +%<latexrelease> \ifdim \@ovdy<\z@ \@ovdy -\@ovdy \fi +%<latexrelease> \ifdim \@ovyy<\@ovdy \@ovyy \@ovdy \fi +%<latexrelease> \@multicnt +%<latexrelease> \ifdim \@ovxx>\@ovyy \@ovxx \else \@ovyy \fi +%<latexrelease> \@ovxx .5\@halfwidth \divide\@multicnt\@ovxx +%<latexrelease> \ifnum +%<latexrelease> \qbeziermax<\@multicnt \@multicnt\qbeziermax\relax +%<latexrelease> \fi +%<latexrelease> \else \@multicnt#1\relax \fi +%<latexrelease> \@tempcnta\@multicnt \advance\@tempcnta\@ne +%<latexrelease> \@ovdx #4\unitlength \advance\@ovdx -#2\unitlength +%<latexrelease> \multiply\@ovdx \tw@ +%<latexrelease> \@ovxx #6\unitlength \advance\@ovxx -#2\unitlength +%<latexrelease> \advance\@ovxx -\@ovdx \divide\@ovxx\@multicnt +%<latexrelease> \@ovdy #5\unitlength \advance\@ovdy -#3\unitlength +%<latexrelease> \multiply\@ovdy \tw@ +%<latexrelease> \@ovyy #7\unitlength \advance\@ovyy -#3\unitlength +%<latexrelease> \advance\@ovyy -\@ovdy \divide\@ovyy\@multicnt +%<latexrelease> \setbox\@tempboxa\hbox{% +%<latexrelease> \hskip -\@halfwidth +%<latexrelease> \vrule \@height\@halfwidth +%<latexrelease> \@depth \@halfwidth +%<latexrelease> \@width \@wholewidth}% +%<latexrelease> \put(#2,#3){% +%<latexrelease> \count@\z@ +%<latexrelease> \@whilenum{\count@<\@tempcnta}\do +%<latexrelease> {\@xdim\count@\@ovxx +%<latexrelease> \advance\@xdim\@ovdx +%<latexrelease> \divide\@xdim\@multicnt +%<latexrelease> \multiply\@xdim\count@ +%<latexrelease> \@ydim\count@\@ovyy +%<latexrelease> \advance\@ydim\@ovdy +%<latexrelease> \divide\@ydim\@multicnt +%<latexrelease> \multiply\@ydim\count@ +%<latexrelease> \raise \@ydim +%<latexrelease> \hb@xt@\z@{\kern\@xdim +%<latexrelease> \unhcopy\@tempboxa\hss}% +%<latexrelease> \advance\count@\@ne}}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} diff --git a/Master/texmf-dist/source/latex-dev/base/ltplain.dtx b/Master/texmf-dist/source/latex-dev/base/ltplain.dtx index 06602780664..7949b836d46 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltplain.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltplain.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2017/04/10 v2.3c LaTeX Kernel (Plain TeX)] + [2020/08/20 v2.3d LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -691,12 +691,32 @@ % \end{macro} % % \begin{macro}{\alloc@} +% \changes{v2.3d}{2020/08/20} +% {Define \cs{alloc@} in terms of \cs{e@alloc}} +% Since |\e@alloc| was added in 2015, |\@alloc| has not been used, +% but was left as some legacy code calls it. However the original +% defnition gives spurious errors once the ``classic'' registers +% run out, so it is now defined to call |\e@alloc| internally. % \begin{macrocode} -\def\alloc@#1#2#3#4#5{\global\advance\count1#1\@ne - \ch@ck#1#4#2% - \allocationnumber\count1#1% - \global#3#5\allocationnumber - \wlog{\string#5=\string#2\the\allocationnumber}} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01} +%<latexrelease> {\alloc@}{emulate alloc@}% +\def\alloc@#1#2#3#4{\e@alloc#2#3{\count1#1}#4\float@count} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\alloc@}{emulate alloc@}% +%<latexrelease>\def\alloc@#1#2#3#4#5{\global\advance\count1#1\@ne +%<latexrelease> \ch@ck#1#4#2% +%<latexrelease> \allocationnumber\count1#1% +%<latexrelease> \global#3#5\allocationnumber +%<latexrelease> \wlog{\string#5=\string#2\the\allocationnumber}} +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex-dev/base/ltsect.dtx b/Master/texmf-dist/source/latex-dev/base/ltsect.dtx index 9ccd042fb4e..359b445f453 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltsect.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltsect.dtx @@ -31,7 +31,7 @@ %%% From File: ltsect.dtx %<*driver> % \fi -\ProvidesFile{ltsect.dtx}[2019/08/27 v1.1d LaTeX Kernel (Sectioning)] +\ProvidesFile{ltsect.dtx}[2020/07/27 v1.1e LaTeX Kernel (Sectioning)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltsect.dtx} @@ -137,20 +137,22 @@ % % \begin{macro}{\author} % \changes{LaTeX2e}{1993/12/11}{Added default} +% \changes{v1.1e}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % % |\author| for use in |\maketitle|. If not given |\maketitle| will % produce a warning message. % % \begin{macrocode} -\DeclareRobustCommand\author[1]{\gdef\@author{#1}} +\DeclareRobustCommand*\author[1]{\gdef\@author{#1}} % \end{macrocode} % \end{macro} % % \begin{macro}{\date} % |\date| for use in |\maketitle|. If not given |\maketitle| will % produce |\today| as the default. +% \changes{v1.1e}{2020/07/27}{Don't make the command \cs{long} (gh/354)} % \begin{macrocode} -\DeclareRobustCommand\date[1]{\gdef\@date{#1}} +\DeclareRobustCommand*\date[1]{\gdef\@date{#1}} % \end{macrocode} % \end{macro} % @@ -776,20 +778,33 @@ % \cs{addcontentsline}. ASAJ.} % \changes{v1.1c}{2018/09/26}{Sometimes mask the endline char when % writing to files (github/73)} +% \changes{v1.1e}{2020/10/01}{add a fourth argument for better +% hyperref compability} % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\addcontentsline}{fourth argument}% +\def\addcontentsline#1#2#3{% +% \end{macrocode} +% We add an empty brace pair at the end of \cs{contentsline} +% so that the number of argument is identical in documents +% with and without hyperref. +% \begin{macrocode} + \addtocontents{#1}{\protect\contentsline{#2}{#3}{\thepage}{}% + \protected@file@percent}} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2018/12/01}% %<latexrelease> {\addcontentsline}{Mask line endings}% -\def\addcontentsline#1#2#3{% - \addtocontents{#1}{\protect\contentsline{#2}{#3}{\thepage}% +%<latexrelease> \def\addcontentsline#1#2#3{% +%<latexrelease> \addtocontents{#1}{\protect\contentsline{#2}{#3}{\thepage}% % \end{macrocode} % We add \cs{protected@file@percent} at the end which is turned inside % \cs{@writefile} into a percent character to mask the newline after % the closing argument brace. % \begin{macrocode} - \protected@file@percent}} -%</2ekernel|latexrelease> +%<latexrelease> \protected@file@percent}} %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% %<latexrelease> {\addcontentsline}{Mask line endings}% diff --git a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx index 8d6150b5930..650c46866e4 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx @@ -1,24 +1,38 @@ % \iffalse meta-comment -% +%% %% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +%% % -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file +% This file is part of the LaTeX base system. +% ------------------------------------------- % +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in % https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". % +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. % -% The development version of the bundle can be found below +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi % -% https://github.com/FrankMittelbach/... +% \iffalse % -% for those people who are interested or want to report an issue. +%%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v0.9a} -\providecommand\ltshipoutdate{2020/07/15} +\providecommand\ltshipoutversion{v1.0a} +\providecommand\ltshipoutdate{2020/08/31} % \end{macrocode} % %<*driver> @@ -53,7 +67,8 @@ % % \long\def\fmi#1{\begin{quote}\itshape Todo: #1\end{quote}} % -% \newcommand\hook[1]{\texttt{#1}} +% \providecommand\hook[1]{\texttt{#1}} +% \providecommand\pkg[1]{\texttt{#1}} % % % \title{The \texttt{ltshipout} package\thanks{This package has version @@ -94,13 +109,13 @@ % manipulated through a set of hooks after which it is shipped out % for real. % \end{function} - +% % \begin{variable}{\ShipoutBox,\l_shipout_box} % This box register is called \cs{ShipoutBox} (alternatively available via the % L3 name \cs{l_shipout_box}). % \end{variable} % - +% % \begin{variable}{\l_shipout_box_ht_dim, % \l_shipout_box_dp_dim,\l_shipout_box_wd_dim, % \l_shipout_box_ht_plus_dp_dim} @@ -136,7 +151,7 @@ % \item[\hook{shipout/background}] % % This hook adds a picture environment into the background of -% the page (with the \texttt{(0,0)} coordinate in the top-left +% the page with the \texttt{(0,0)} coordinate in the top-left % corner using a \cs{unitlength} of \texttt{1pt}. % % It should therefore only receive \cs{put} commands or other @@ -144,10 +159,6 @@ % vertical coordinate values would normally be % negative. % -% \fmi{Again, mainly \pkg{atbegshi} compatibility. Not -% sure it is best to have to always use negative -% coordinates.} -% % Technically this is implemented by adding a zero-sized % \cs{hbox} as the very first item into the \cs{ShipoutBox} % containing that \texttt{picture} environment. Thus the rest of @@ -157,7 +168,7 @@ % \item[\hook{shipout/foreground}] % % This hook adds a picture environment into the foreground of -% the page (with the \texttt{(0,0)} coordinate in the top-left +% the page with the \texttt{(0,0)} coordinate in the top-left % corner using a \cs{unitlength} of \texttt{1pt}. % % Technically this is implemented by adding a zero-sized @@ -171,29 +182,30 @@ % \item[\hook{shipout/firstpage}] % % The material from this hook is executed only once at the very -% beginning of the first output page. It should only contain -% \cs{special} commands needed to direct post processors -% handling the \texttt{.dvi} or \texttt{.pdf} output.\fmi{not -% sure it has to be that restrictive.} +% beginning of the first output page that is shipped out (i.e., +% not discarded at the last minute). It should only contain +% \cs{special} or similar commands needed to direct post processors +% handling the \texttt{.dvi} or \texttt{.pdf} output.\footnotemark % -% In \LaTeXe{} that was already existing but implemented as a box -% register \cs{@begindvibox}. -% \fmi{drop or at least mark the obsolete code in latex.ltx} +% ^^A \fmi{not sure it has to be that restrictive.} % % % \item[\hook{shipout/lastpage}] % % The corresponding hook to add \cs{special}s at the very end of -% the output file. It is only entered on the very last page. +% the output file. It is only executed on the very last page --- +% or rather on the page that \LaTeX{} believes is the last one. % -% It may not be possible for \LaTeX{} to correctly determine which page is -% the last one without several reruns. If this happens and the -% hook is non-empty then \LaTeX{} will add an extra page to -% place the material and also request a rerun to get the correct -% placement sorted out. +% It may not be possible for \LaTeX{} to correctly determine +% which page is the last one without several reruns. If this +% happens and the hook is non-empty then \LaTeX{} will add an +% extra page to place the material and also request a rerun to +% get the correct placement sorted out. % % \end{description} -% \end{variable} +% \end{variable}\footnotetext{In +% \LaTeXe{} that was already existing, but implemented using a box +% register with the name \cs{@begindvibox}.} % % As mentioned above the hook \hook{shipout/before} is executed % first and can manipulate the prepared shipout box stored in @@ -280,7 +292,7 @@ % routine). More precisely, it is incremented only after it is % clear that a page will be shipped out, i.e., after the % \hook{shipout/before} hook (because that might discard the page)! - +% % Just like with the \texttt{page} counter its value is % only accurate within the output routine. In the body of the % document it may be off by one as the output routine is called @@ -314,22 +326,33 @@ % reliable inside the output routine! % \end{variable} % - +% \begin{variable}{\PreviousTotalPages} +% \begin{syntax} +% \cs{thetotalpages}/\cs{PreviousTotalPages} +% \end{syntax} +% Command that expands to the number of total pages from the +% previous run. If there was no previous run or if usedin the +% preamble it expands to +% \texttt{0}. Note that this is a command to a counter, so in order +% to display the number in, say, Roman numerals you have to assign +% its value to a counter and then use \cs{Roman} on that counter. +% \end{variable} +% % % \subsection{Debugging shipout code} % -% \begin{function}{\DebugShipoutOn,\DebugShipoutOff, +% \begin{function}{\DebugShipoutsOn,\DebugShipoutsOff, % \shipout_debug_on:,\shipout_debug_off:} % \begin{syntax} -% \cs{DebugShipoutOn} +% \cs{DebugShipoutsOn} % \end{syntax} % Turn the debugging of shipout code on or off. This displays % changes made to the shipout data structures. \fmi{This needs -% some rationalizing and will probably not stay this way.} +% some rationalizing and may not stay this way.} % \end{function} % % - +% % % \section{Emulating commands from other packages} % @@ -381,8 +404,8 @@ % just adding it to the hook should be sufficient. % \end{function} % - - +% +% % \begin{function}{\AtBeginShipoutBox} % This is the name of the shipout box as \pkg{atbegshi} knows it. % \end{function} @@ -406,13 +429,12 @@ % The \pkg{atbegshi} names for \cs{AtBeginDvi} and \cs{DiscardShipoutBox}. % \end{function} % - - - +% +% +% % \subsection{Emulating \pkg{everyshi}} % - - +% % \begin{function}{\EveryShipout} % \begin{syntax} % \cs{EveryShipout}\Arg{code} $\equiv$ \cs{AddToHook}\texttt{\{shipout/before\}}\Arg{code} @@ -425,15 +447,15 @@ % \end{syntax} % \end{function} % - - +% +% % \subsection{Emulating \pkg{atenddvi}} % % The \pkg{atenddvi} package implemented only a single command: % \cs{AtEndDvi} and that is now available out of the box. - - - +% +% +% % \subsection{Emulating \pkg{everypage}} % % This page takes over the original \cs{@begindvi} hook and replaces @@ -448,8 +470,20 @@ % % \section{The Implementation} % \begin{macrocode} -%<*2ekernel> %<@@=shipout> +% \end{macrocode} +% +% At the moment the whole module rolls back in one go, but if we +% make any modifications in later releases this will then need +% splitting. +% \begin{macrocode} +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\shipout}{Hook mangement (shipout)}% +% \end{macrocode} +% +% +% \begin{macrocode} \ExplSyntaxOn % \end{macrocode} % @@ -489,24 +523,10 @@ % \end{macro} % \end{macro} % - -% \begin{macro}{shipout/before, -% shipout/foreground,shipout/background, -% shipout/firstpage, -% shipout/lastpage} -% Declaring all hooks for the shipout code. -% \begin{macrocode} -\hook_new:n{shipout/before} -\hook_new:n{shipout/foreground} -\hook_new:n{shipout/background} -\hook_new:n{shipout/firstpage} -\hook_new:n{shipout/lastpage} -% \end{macrocode} -% \end{macro} - - - - +% +% +% +% % \begin{macro}{\ShipoutBox,\l_shipout_box} % The box filled with the page to be shipped out (both L3 and % \LaTeXe{} name). @@ -518,10 +538,10 @@ \cs_set_eq:NN \ShipoutBox \l_shipout_box % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \begin{macro}{\@@_execute:} % This is going to the be the code run by \cs{shipout}. The code % follows closely the ideas from \pkg{atbegshi}, so not @@ -535,25 +555,25 @@ } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\shipout} % Overloading the \cs{shipout} primitive: % \begin{macrocode} \cs_gset_eq:NN \shipout \@@_execute: % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\l_@@_group_level_tl} % Helper token list to record the group level at which % \cs{@@_execute:} is encountered. \begin{macrocode} \tl_new:N \l_@@_group_level_tl % \end{macrocode} % \end{macro} - +% - +% % \begin{macro}{\@@_execute_test_level:} % If the group level has changed then we are still constructing % \cs{l_shipout_box} and to continue we need to wait until the @@ -567,8 +587,8 @@ } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_execute_cont:} % When we have reached this point the shipout box has been % processed and is available in \cs{l_shipout_box} and ready for @@ -589,8 +609,10 @@ % Otherwise we assume that we will ship something and prepare for % final adjustments (in particular setting the state of % \cs{protect} while we are running the hook code). +% We also save the current \cs{protect} state to restore it later. % \begin{macrocode} \bool_gset_false:N \g_@@_discard_bool + \cs_set_eq:NN \@@_saved_protect: \protect \set@typeset@protect % \end{macrocode} % We also store the current shipout box dimension in registers, so that @@ -675,13 +697,13 @@ % % \begin{macrocode} \@@_get_box_size:N \l_shipout_box - \@kernel@before@shipout@foreground \hook_if_empty:nF {shipout/foreground} { \@@_add_foreground_picture:n { \hook_use:n {shipout/foreground} } } \hook_if_empty:nF {shipout/background} { \@@_add_background_picture:n - { \hook_use:n {shipout/background} } } + { \@kernel@before@shipout@background + \hook_use:n {shipout/background} } } % \end{macrocode} % We then run \cs{@@_execute_firstpage_hook:} that adds % the content of the hook \hook{shipout/firstpage} to the @@ -713,22 +735,52 @@ \tex_shipout:D \box_use:N \l_shipout_box } } +% \end{macrocode} +% Restore the value of \cs{protect} in case \cs{shipout} is called +% outside of the output routine (where it is automatically restored +% because of the implicit group). +% \begin{macrocode} + \cs_set_eq:NN \protect \@@_saved_protect: } } % \end{macrocode} % \end{macro} - - - -% \begin{macro}{\@kernel@after@shipout@lastpage,\@kernel@before@shipout@foreground} -% +% +% +% \begin{macro}{\@@_saved_protect:} +% Remeber the current \cs{protect} state. +% \begin{macrocode} +\cs_new_eq:NN \@@_saved_protect: \protect +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{shipout/before, +% shipout/foreground,shipout/background, +% shipout/firstpage, +% shipout/lastpage} +% Declaring all hooks for the shipout code. +% \begin{macrocode} +\hook_new:n{shipout/before} +\hook_new:n{shipout/foreground} +\hook_new:n{shipout/background} +\hook_new:n{shipout/firstpage} +\hook_new:n{shipout/lastpage} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@kernel@after@shipout@lastpage, +% \@kernel@before@shipout@background} +% And here are the internal kernel hooks going before or after the +% public ones where needed. % \begin{macrocode} \let\@kernel@after@shipout@lastpage\@empty -\let\@kernel@before@shipout@foreground\@empty +\let\@kernel@before@shipout@background\@empty % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_execute_firstpage_hook: } % This command adds any specials into a box and adds that to the % very beginning of the first box shipped out. After that we @@ -750,15 +802,15 @@ % \begin{macrocode} \cs_gset_eq:NN \@@_execute_firstpage_hook: \prg_do_nothing: \cs_gset:Npn \@@_add_firstpage_material:Nn ##1 ##2 { - \PackageWarning{ltshipout}{ + \@latex@warning{ First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak \string##1 } } } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\g_@@_lastpage_handled_bool} % A boolean to signal if we have already handled the % \hook{shipout/lastpage} hook. @@ -766,9 +818,9 @@ \bool_new:N \g_@@_lastpage_handled_bool % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\@@_add_firstpage_material:Nn} % This command adds material to the % \hook{shipout/firstpage} hook. It is used in @@ -782,13 +834,13 @@ } % \end{macrocode} % \end{macro} - - - - - - - +% +% +% +% +% +% +% % \begin{macro}{\@@_get_box_size:N} % Store the box dimensions in dimen registers. % \fmi{This could/should perhaps be generalized to set height depth and @@ -803,7 +855,7 @@ } % \end{macrocode} % \end{macro} - +% % \begin{macro}{\l_shipout_box_ht_dim, % \l_shipout_box_dp_dim,\l_shipout_box_wd_dim, % \l_shipout_box_ht_plus_dp_dim} @@ -815,20 +867,20 @@ \dim_new:N \l_shipout_box_ht_plus_dp_dim % \end{macrocode} % \end{macro} - - - - - +% +% +% +% +% % \begin{macro}{\g_@@_discard_bool} % Indicate whether or not the current page box should be discarded % \begin{macrocode} \bool_new:N \g_@@_discard_bool % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\l_@@_tmp_box,\l_@@_saved_badness_tl} % We need a box for the background and foreground material and a % token register to remember badness settings as we disable them @@ -838,8 +890,8 @@ \tl_new:N \l_@@_saved_badness_tl % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_add_background_box:n} % In standard \LaTeX{} the shipout box is always a \cs{vbox} but % here we are allow for other usage as well, in case some package @@ -930,10 +982,10 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \begin{macro}{\@@_add_foreground_box:n} % Foreground boxes are done in the same way, only the order and % placement of boxes has to be done differently. @@ -993,17 +1045,21 @@ } % \end{macrocode} % \end{macro} - - - - -% \begin{macro}{\c_@@_horigin_tl,\c_@@_vorigin_tl} +% +% +% +% +% \begin{macro}{\@@_init_page_origins:,\c_@@_horigin_tl,\c_@@_vorigin_tl} % Two constants holding the offset of the top-left with respect to % the media box. % % Setting the constants this way is courtesy of Bruno. +% +% We delay setting the constants to the last possible place as +% there might be updates in the preamble or even in the +% \hook{begindocument} hook that affects their setup. % \begin{macrocode} -\tl_gput_right:Nn \@kernel@after@begindocument { +\cs_new:Npn \@@_init_page_origins: { \tl_const:Nx \c_@@_horigin_tl { \cs_if_exist_use:NTF \pdfvariable { horigin } @@ -1014,11 +1070,17 @@ \cs_if_exist_use:NTF \pdfvariable { vorigin } { \cs_if_exist_use:NF \pdfvorigin { 1in } } } +% \end{macrocode} +% After the constants have been set there is no need to execute +% this command again, in fact it would raise an error, so we +% redefine it to do nothing. +% \begin{macrocode} + \cs_gset_eq:NN \@@_init_page_origins: \prg_do_nothing: } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_picture_overlay:n} % Put the argument into a \texttt{picture} environment that doesn't take up % any size and uses \texttt{1pt} for \cs{unitlength}. @@ -1026,6 +1088,14 @@ % not it is not.} % \begin{macrocode} \cs_new:Npn \@@_picture_overlay:n #1 { +% \end{macrocode} +% The very first time this is executed we have ot initializes (and +% freeze) the origins. +% \begin{macrocode} + \@@_init_page_origins: +% \end{macrocode} +% +% \begin{macrocode} \kern -\c_@@_horigin_tl \scan_stop: \vbox_to_zero:n { \kern -\c_@@_vorigin_tl \scan_stop: @@ -1040,20 +1110,21 @@ } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\@@_add_background_picture:n} % Put a \texttt{picture} env in the background of the shipout box % with its reference point in the top-left corner. +% % \begin{macrocode} \cs_new:Npn \@@_add_background_picture:n #1 { \@@_add_background_box:n { \@@_picture_overlay:n {#1} } } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\@@_add_foreground_picture:n} % % Put a \texttt{picture} env in the foreground of the shipout box @@ -1064,8 +1135,8 @@ } % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\shipout_discard:} % Request that the next shipout box should be discarded. At the % moment this is just setting a boolean, but we may want to augment @@ -1078,18 +1149,18 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \subsection{Handling the end of job hook} - +% % At the moment this is partly solved by using the existing hooks. % But rather than putting the code into these hooks it should be % moved to the right place directly as we shouldn't prefill hooks % with material unless it needs to interact with other code. % - +% % % \begin{macro}{\g_shipout_readonly_int,\ReadonlyShipoutCounter} % We count every shipout activity that makes a page (but not those @@ -1103,7 +1174,7 @@ \cs_new_eq:NN \ReadonlyShipoutCounter \g_shipout_readonly_int % \end{macrocode} % \end{macro} - +% % \begin{macro}{\g_shipout_totalpages_int,\c@totalpages} % We count every shipout attempt (even those that are discarded) in % tis counter. It is not used in the code but may get used in user @@ -1120,15 +1191,15 @@ % \end{macrocode} % \end{macro} % - - - +% +% +% % \begin{macro}{\@abspage@last} % In \cs{@abspage@last} record the number of pages from the last % run. This is written to the \texttt{.aux} and this way made % available to the next run. In case there is no \texttt{.aux} file % or the statement is missing from it we initialize it with the -% largest possible number in \TeX{}. We use this a s the default +% largest possible number in \TeX{}. We use this as the default % because then we are inserting the \hook{shipout/lastpage} on % the last page (or after the last page but not on page 1 for a % multipage document. @@ -1136,8 +1207,8 @@ \xdef\@abspage@last{\number\maxdimen} % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\enddocument} % % Instead of using the hooks \hook{enddocument} and @@ -1188,7 +1259,7 @@ { % \end{macrocode} % This ends up in the \texttt{.aux} so we use \LaTeXe{} names here. -% \fmi{this needs an interface for \cs{nofiles} in expl3, doesn't at the moment!} +% \fmi{This needs an interface for \cs{nofiles} in expl3, doesn't at the moment!} % \begin{macrocode} \if@filesw \iow_now:Nx \@auxout { @@ -1202,32 +1273,47 @@ % run but helps to keep pdf viewers happy. % \begin{macrocode} \bool_if:NF \g_@@_lastpage_handled_bool - { \tex_shipout:D\vbox to\textheight{ - \hbox{\UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage } + { +% \end{macrocode} +% However, making this extra page in case the hook is actually +% empty would be forcing a rerun without any reason, so we check +% that condition and also check if +% \cs{@kernel@after@shipout@lastpage} contains any code. If both +% are empty we omit the page generation. +% \begin{macrocode} + \bool_lazy_and:nnF + { \hook_if_empty_p:n {shipout/lastpage} } + { \tl_if_empty_p:N \@kernel@after@shipout@lastpage } + { + \tex_shipout:D\vbox to\textheight + { + \hbox:n { \UseHook{shipout/lastpage} + \@kernel@after@shipout@lastpage } % \end{macrocode} % This extra page could be totally empty except for the hook % content, but to help the user understanding why it is there we % put some text into it. % \begin{macrocode} - \@@_excuse_extra_page: - \null - } + \@@_excuse_extra_page: + \null + } % \end{macrocode} -% At this point we should also signal to \LaTeX{} that a rerun is +% At this point we also signal to \LaTeX{}'s endgame that a rerun is % necessary so that an appropriate message can be shown on the -% terminal. -% -% \fmi{integrate warning ``Rerun \ldots'' } +% terminal. We do this by simply defining a command used as a flag and +% tested \cs{enddocument}. % \begin{macrocode} - } - } + \cs_gset_eq:NN \@extra@page@added \relax + } + } + } } % \end{macrocode} % \end{macro} % \end{macro} - - - +% +% +% % \begin{macro}{\@@_excuse_extra_page:} % Say mea culpa \ldots % \begin{macrocode} @@ -1248,178 +1334,401 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% \begin{macro}{\PreviousTotalPages,\@kernel@before@begindocument} +% In the preamble before the \texttt{aux} file was read +% \cs{PreviousTotalPages} is always zero. +% \begin{macrocode} +\def\PreviousTotalPages{0} +% \end{macrocode} +% In the \texttt{aux} file there should be an update for +% \cs{@abspage@last} recording the number of pages from the +% previous run. If not that macro holds the value of +% \cs{maxdimen}. So we test for it and update +% \cs{PreviousTotalPages} if there was a real value. This should +% happen just before the \hook{begindocument} hook is executed so +% that the value can be used inside that hook. +% \begin{macrocode} +\g@addto@macro\@kernel@before@begindocument + {\ifnum\@abspage@last<\maxdimen + \xdef\PreviousTotalPages{\@abspage@last}\fi} +% \end{macrocode} +% \end{macro} +% +% % \section{Legacy \LaTeXe{} interfaces} - - - +% +% +% % \begin{macro}{\DiscardShipoutBox} % Request that the next shipout box is to be discarded. % \begin{macrocode} \cs_new_eq:NN \DiscardShipoutBox \shipout_discard: % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\AtBeginDvi} % % \begin{macrocode} -\renewcommand \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} +\DeclareRobustCommand \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} % \end{macrocode} % \end{macro} - - -% \begin{macro}{\DebugShipoutOn,\DebugShipoutOff} +% +% +% \begin{macro}{\DebugShipoutsOn,\DebugShipoutsOff} % % \begin{macrocode} -\cs_new_eq:NN \DebugShipoutOn \shipout_debug_on: -\cs_new_eq:NN \DebugShipoutOff \shipout_debug_off: +\cs_new_eq:NN \DebugShipoutsOn \shipout_debug_on: +\cs_new_eq:NN \DebugShipoutsOff \shipout_debug_off: % \end{macrocode} % \end{macro} - - - - - +% +% +% \section{Internal commands needed elsewhere} +% +% These internal commands use double and triple \texttt{@} signs so +% we need to stop getting them translated to the module name. +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macro}{\@expl@@@shipout@add@firstpage@material@@Nn, +% \@expl@@@shipout@add@background@box@@n, +% \@expl@@@shipout@add@foreground@box@@n, +% \@expl@@@shipout@add@background@picture@@n, +% \@expl@@@shipout@add@foreground@picture@@n} +% Some internals needed elsewhere. +% +% \begin{macrocode} +\cs_set_eq:NN \@expl@@@shipout@add@firstpage@material@@Nn + \__shipout_add_firstpage_material:Nn +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_eq:NN \@expl@@@shipout@add@background@box@@n + \__shipout_add_background_box:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_eq:NN \@expl@@@shipout@add@foreground@box@@n + \__shipout_add_foreground_box:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_eq:NN \@expl@@@shipout@add@background@picture@@n + \__shipout_add_background_picture:n +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_eq:NN \@expl@@@shipout@add@foreground@picture@@n + \__shipout_add_foreground_picture:n +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +\ExplSyntaxOff +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% +% Rolling back here doesn't undefine the interface commands as they +% may be used in packages without rollback functionality. So we +% just make them do nothing which may or may not work depending on +% the code usage. +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\shipout}{The hook management (shipout)}% +%<latexrelease>\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname +%<latexrelease> +%<latexrelease>\let \ShipoutBox\@undefined +%<latexrelease>\let \ReadonlyShipoutCounter \@undefined +%<latexrelease>\let \c@totalpages \@undefined +%<latexrelease>\let \thetotalpages \@undefined +%<latexrelease> +%<latexrelease>\let \DiscardShipoutBox \@undefined +%<latexrelease>\let \DebugShipoutsOn \@undefined +%<latexrelease>\let \DebugShipoutsOff \@undefined +%<latexrelease> +%<latexrelease>\DeclareRobustCommand \AtBeginDvi [1]{% +%<latexrelease> \global \setbox \@begindvibox +%<latexrelease> \vbox{\unvbox \@begindvibox #1}% +%<latexrelease>} +%<latexrelease> +%<latexrelease>\let \AtBeginShipout \@undefined +%<latexrelease>\let \AtBeginShipoutNext \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutFirst \@undefined +%<latexrelease> +%<latexrelease>\let \ShipoutBoxHeight \@undefined +%<latexrelease>\let \ShipoutBoxDepth \@undefined +%<latexrelease>\let \ShipoutBoxWidth \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutDiscard \@undefined +%<latexrelease> +%<latexrelease>\let \AtBeginShipoutAddToBox \@undefined +%<latexrelease>\let \AtBeginShipoutAddToBoxForeground \@undefined +%<latexrelease>\let \AtBeginShipoutUpperLeft \@undefined +%<latexrelease>\let \AtBeginShipoutUpperLeftForeground \@undefined +%<latexrelease> +%<latexrelease> +% \end{macrocode} +% We do not undo a substitution when rolling back. As the file +% support gets undone the underlying data is no longer used (and +% sufficiently obscure that should not interfer with existing +% commands) and properly removing it would mean we need to make the +% \cs{unclare@...} and its support macros available in all earlier +% kernel releases which is pointless (and actually worse). +% \begin{macrocode} +%\undeclare@file@substitution{everyshi.sty}{everyshi-ltx.sty} +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease> +%<latexrelease>\let \AtEndDvi \@undefined +% \end{macrocode} +% We do not reenable a disabled package load when rolling back. As the file +% support gets undone the underlying data is no longer checked (and +% sufficiently obscure that it should not interfer with existing +% commands) and properly removing it would mean we need to make the +% \cs{reenable@package@load} command available in all earlier +% kernel releases which is pointless (and actually worse). +% \begin{macrocode} +%\reenable@package@load{atenddvi} +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease> +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% +% +% % \section{Package emulation for compatibility} - - +% +% +% \subsection{Package \pkg{atenddvi} emulation} +% +% +% \begin{macro}{\AtEndDvi} +% This package has only one public command to simulating it is easy +% and actually sensible to provide as part of the kernel. +% \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2020/10/01}% +%<latexrelease> {\AtEndDvi}{atenddvi emulation}% +\ExplSyntaxOn +\cs_new:Npn \AtEndDvi {\AddToHook{shipout/lastpage}} +\ExplSyntaxOff +% \end{macrocode} +% As the package is integrate we prevent loading (no need to roll that back): +% \begin{macrocode} +\disable@package@load{atenddvi} + {\PackageWarning{atenddvi} + {Functionality of this package is already\MessageBreak + provided by LaTeX.\MessageBreak\MessageBreak + It is there no longer necessary to load it\MessageBreak + and you can safely remove it.\MessageBreak + Found on}} +% \end{macrocode} +% +% \begin{macrocode} +%</2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\AtEndDvi}{atenddvi emulation}% +%<latexrelease>\let \AtEndDvi \@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +%</2ekernel> +% \end{macrocode} +% +% % \subsection{Package \pkg{atbegshi} emulation} - +% +% +% +% +% +% \begin{macrocode} +%<*atbegshi-ltx> +\ProvidesPackage{atbegshi} + [2020/08/17 v1.0a + Emulation of the original atbegshi package^^Jwith kernel methods] +% \end{macrocode} +% +% % \begin{macro}{\AtBeginShipoutBox} % \begin{macrocode} -\cs_new_eq:NN \AtBeginShipoutBox \ShipoutBox +\let \AtBeginShipoutBox \ShipoutBox % \end{macrocode} % \end{macro} - - - +% +% % \begin{macro}{\AtBeginShipoutInit} % Compatibility only, we aren't delaying \ldots % \begin{macrocode} -\cs_set_eq:NN\AtBeginShipoutInit\@empty +\let \AtBeginShipoutInit \@empty % \end{macrocode} % \end{macro} - - - +% +% % \begin{macro}{\AtBeginShipout,\AtBeginShipoutNext} % Filling hooks % \begin{macrocode} -\newcommand\AtBeginShipout {\AddToHook{shipout/before}} -\newcommand\AtBeginShipoutNext {\AddToHookNext{shipout/before}} +\def \AtBeginShipout {\AddToHook{shipout/before}} +\def \AtBeginShipoutNext {\AddToHookNext{shipout/before}} % \end{macrocode} % \end{macro} - - - +% +% % \begin{macro}{\AtBeginShipoutFirst} % Slightly more complex as we need to know the name of the command under which the % \hook{shipout/firstpage} hook is filled. % \begin{macrocode} -\newcommand\AtBeginShipoutFirst{\@@_add_firstpage_material:Nn \AtBeginShipoutFirst} +\def \AtBeginShipoutFirst + {\@expl@@@shipout@add@firstpage@material@@Nn \AtBeginShipoutFirst} % \end{macrocode} % \end{macro} - - - -% This is somewhat different from the original where -% \cs{ShipoutBoxHeight} etc.\ only holds the \verb=\the\ht<box>= value. This -% may has some implications in some use cases and if that is a problem -% then it might need changing. -% -% \begin{macrocode} -\cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim } -\cs_new:Npn \ShipoutBoxDepth { \dim_use:N \l_shipout_box_dp_dim } -\cs_new:Npn \ShipoutBoxWidth { \dim_use:N \l_shipout_box_wd_dim } -% \end{macrocode} - - +% +% % \begin{macro}{\AtBeginShipoutDiscard} % Just a different name. % \begin{macrocode} -\cs_new_eq:NN \AtBeginShipoutDiscard \DiscardShipoutBox +\let \AtBeginShipoutDiscard \DiscardShipoutBox % \end{macrocode} % \end{macro} - - +% +% % \begin{macro}{\AtBeginShipoutAddToBox,\AtBeginShipoutAddToBoxForeground, % \AtBeginShipoutUpperLeft,\AtBeginShipoutUpperLeftForeground} % We don't expose them. % \begin{macrocode} -\cs_new_eq:NN \AtBeginShipoutAddToBox \@@_add_background_box:n -\cs_new_eq:NN \AtBeginShipoutAddToBoxForeground \@@_add_foreground_box:n +\let \AtBeginShipoutAddToBox + \@expl@@@shipout@add@background@box@@n +\let \AtBeginShipoutAddToBoxForeground + \@expl@@@shipout@add@foreground@box@@n % \end{macrocode} % % \begin{macrocode} -\cs_new_eq:NN\AtBeginShipoutUpperLeft \@@_add_background_picture:n -\cs_new_eq:NN\AtBeginShipoutUpperLeftForeground \@@_add_foreground_picture:n +\let \AtBeginShipoutUpperLeft + \@expl@@@shipout@add@background@picture@@n +\let \AtBeginShipoutUpperLeftForeground + \@expl@@@shipout@add@foreground@picture@@n % \end{macrocode} % \end{macro} - % % -% We prevent the package \pkg{atbegshi} from loading: +% +% \begin{macro}{\ShipoutBoxHeight,\ShipoutBoxWidth,\ShipoutoBoxDepth} +% This is somewhat different from the original in \pkg{atbegshi} +% where \cs{ShipoutBoxHeight} etc.\ only holds the +% \verb=\the\ht<box>= value. This may has some implications in some +% use cases and if that is a problem then it might need changing. % \begin{macrocode} -\expandafter\cs_set_eq:NN\csname ver@atbegshi.sty\endcsname\fmtversion +\ExplSyntaxOn +\cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim } +\cs_new:Npn \ShipoutBoxDepth { \dim_use:N \l_shipout_box_dp_dim } +\cs_new:Npn \ShipoutBoxWidth { \dim_use:N \l_shipout_box_wd_dim } +\ExplSyntaxOff % \end{macrocode} -% \pkg{hyperref} code (and \pkg{ltxcmds}) doesn't understand 2020-10-01 -% and thinks it is before 1994, so for now \ldots +% \end{macro} +% +% % \begin{macrocode} -\@namedef {ver@atbegshi.sty}{2020/10/01} +%</atbegshi-ltx> % \end{macrocode} - - - -% \subsection{Package \pkg{everyshi} emulation} % -% \begin{macro}{\EveryShipout,\AtNextShipout} -% This package has only two public commands to simulating it is easy: +% If the package is requested we substitute the one above: % \begin{macrocode} -\cs_new_eq:NN\EveryShipout\AtBeginShipout -\cs_new_eq:NN\AtNextShipout\AtBeginShipoutNext +%<*2ekernel> +\declare@file@substitution{atbegshi.sty}{atbegshi-ltx.sty} +%</2ekernel> % \end{macrocode} -% \end{macro} +% +% +% +% +% +% +% \subsection{Package \pkg{everyshi} emulation} % % \begin{macrocode} -\expandafter\cs_set_eq:NN\csname ver@everyshi.sty\endcsname\fmtversion -\@namedef {ver@everyshi.sty}{2020/10/01} +%<*everyshi-ltx> % \end{macrocode} - - - -% \subsection{Package \pkg{atenddvi} emulation} % -% \begin{macro}{\AtEndDvi} -% This package has only one public command to simulating it is easy: % \begin{macrocode} -\cs_new:Npn \AtEndDvi {\AddToHook{shipout/lastpage}} +\ProvidesPackage{everyshi} + [2020/08/17 v1.0a + Emulation of the original everyshi package^^Jwith kernel methods] +% \end{macrocode} +% +% \begin{macro}{\EveryShipout,\AtNextShipout} +% This package has only two public commands so simulating it is easy: +% \begin{macrocode} +\def \EveryShipout {\AddToHook{shipout/before}} +\def \AtNextShipout {\AddToHookNext{shipout/before}} % \end{macrocode} % \end{macro} % +% \begin{macrocode} +% This is one difference between \pkg{everyshi} and the kernel +% implementation, the latter does not directly use box 255. +% +% For usage by ordinary users this makes no difference but of a +% package use complicated code together with \pkg{everyshi} and +% directly manipulates box 255 then this package needs updating. +% In most cases the updates are simple because the kernel offers +% hooks that makes such complicated code unnecessary. % +% We therefore add a little file into the adjusted package % \begin{macrocode} -\expandafter\cs_set_eq:NN\csname ver@atenddvi.sty\endcsname\fmtversion -\@namedef {ver@atenddvi.sty}{2020/10/01} +%% +%% In normal circumstances the above emulation is sufficient and in +%% all known packages (we know of) that use everyshi it either works or +%% the packages have been adjusted. +%% +%% Code that directly manipulates box 255, however, might fail. +%% If that is the case look at the shipout hooks offered now as +%% they are normally sufficienct to avoid such minpulations (or +%% replace box 255 with \ShipoutBox in the code. +%% +%</everyshi-ltx> % \end{macrocode} - - - - +% +% +% If the package is requested we substitute the one above: % \begin{macrocode} -\ExplSyntaxOff +%<*2ekernel> +\declare@file@substitution{everyshi.sty}{everyshi-ltx.sty} %</2ekernel> % \end{macrocode} - +% +% +% Rather important :-) +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% % \Finale % - - +% +% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - diff --git a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx index ff6c9ef2445..f02a9cdc471 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx @@ -115,7 +115,7 @@ {2020-10-01} %</2ekernel|latexrelease> %<*2ekernel> -\def\patch@level{-7} +\def\patch@level{-8} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx b/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx index 3b82ccd7597..696af32ab15 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx @@ -30,7 +30,7 @@ % %<class>\NeedsTeXFormat{LaTeX2e} %<class>\ProvidesClass{ltxdoc} -%<class> [2020/05/17 v2.0z Standard LaTeX documentation class] +%<class> [2020/08/21 v2.1a Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -54,6 +54,7 @@ % % \changes{v2.0i}{1994/04/29}{Update the documentation.} % \changes{v2.0s}{1998/08/17}{(RmS) Documentation fixes.} +% \changes{v2.1a}{2020/08/21}{Integration of new hook management interface} % % \section{Documentation of the \LaTeX\ sources} % @@ -422,6 +423,8 @@ \def\partname{File} % \end{macrocode} % +% +% % \changes{v2.0z}{2020/05/17}{Support spaces \emph{within} filenames % (gh/218)} % \begin{macrocode} @@ -435,7 +438,8 @@ \ifnum\@auxout=\@partaux \@latexerr{\string\include\space cannot be nested}\@eha \else - \set@curr@file@trim@spaces{#1}% + \set@curr@file{#1}% + \edef\@curr@file{\@strip@tex@ext\@curr@file}% \expandafter\@docinclude\expandafter{\@curr@file} \fi} \def\@docinclude#1 {\clearpage @@ -445,6 +449,7 @@ \if@tempswa \let\@auxout\@partaux \if@filesw \immediate\openout\@partaux "#1.aux" \immediate\write\@partaux{\relax}\fi +\@filehook@set@CurrentFile % \end{macrocode} % We need to save (and later restore) various index-related % commands which might be changed by the included file. diff --git a/Master/texmf-dist/source/latex-dev/base/ltxref.dtx b/Master/texmf-dist/source/latex-dev/base/ltxref.dtx index 98187571499..56ae09c1650 100644 --- a/Master/texmf-dist/source/latex-dev/base/ltxref.dtx +++ b/Master/texmf-dist/source/latex-dev/base/ltxref.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltxref.dtx} - [2020/05/07 v1.1n LaTeX Kernel (Cross Referencing)] + [2020/08/23 v1.1o LaTeX Kernel (Cross Referencing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltxref.dtx} @@ -318,7 +318,9 @@ % \begin{macro}{\refstepcounter} % Step the counter and allow for labels to point to its current value. % \changes{v1.1n}{2020/05/05}{record the counter name in \cs{@currentcounter}} +% \changes{v1.1o}{2020/08/23}{add default definition of \cs{@currentcounter}} % \begin{macrocode} +\def\@currentcounter{} \def\refstepcounter#1{\stepcounter{#1}% \edef\@currentcounter{#1}% \protected@edef\@currentlabel @@ -385,6 +387,7 @@ %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2019/10/01}% %<latexrelease> {\refstepcounter}{Add \labelformat and \Ref}% +%<latexrelease>\let\@currentcounter\@undefined %<latexrelease>\def\refstepcounter#1{\stepcounter{#1}% %<latexrelease> \protected@edef\@currentlabel %<latexrelease> {\csname p@#1\expandafter\endcsname\csname the#1\endcsname}% diff --git a/Master/texmf-dist/source/latex-dev/base/unpack.ins b/Master/texmf-dist/source/latex-dev/base/unpack.ins index ed8cb572c7d..3264a401d9e 100644 --- a/Master/texmf-dist/source/latex-dev/base/unpack.ins +++ b/Master/texmf-dist/source/latex-dev/base/unpack.ins @@ -123,8 +123,6 @@ \batchinput{latexrelease.ins} -\batchinput{lthooks.ins} - \Msg{} \Msg{*********************************************} \Msg{*} diff --git a/Master/texmf-dist/source/latex-dev/tools/varioref.dtx b/Master/texmf-dist/source/latex-dev/tools/varioref.dtx index 06af00bc282..2bba60465e0 100644 --- a/Master/texmf-dist/source/latex-dev/tools/varioref.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/varioref.dtx @@ -40,7 +40,7 @@ %<package>\DeclareCurrentRelease{}{2019-10-01} %<package> %<package>\ProvidesPackage{varioref} -%<package> [2020/07/20 v1.6d package for extended references (FMi)] +%<package> [2020/08/11 v1.6e package for extended references (FMi)] % \fi % %% @@ -70,7 +70,7 @@ % \PackageWarning{inputenc}{Unicode character \expandafter % \UTFviii@splitcsname\string##1\relax % \MessageBreak -% not set up for use with LaTeX}^^A +% not set up for use with LaTeX -- ignored}^^A % \raisebox{.8pt}{\fboxsep1pt\kern.1pt\fbox{$\cdot$}\kern.1pt}^^A % }} % \makeatother @@ -230,11 +230,6 @@ % The optional argument the command may take is the text to use in case % both labels are placed on the current page. % -% In some languages (currently only for Japanese) the generated text -% has to typeset the page range first and the reference range -% afterwards. To accomodate for this \cs{vrefrangeformat} has been -% added to allow to alter this on a per language basis. -% % % \DescribeMacro\vpagerefrange This command is similar to |\vpageref| % but takes two mandatory arguments which are two labels denoting a @@ -395,6 +390,8 @@ %\end{verbatim} % textual references can be suppressed. % +% +% % \section{Multi-lingual usage} % % The package works well together with the babel system if it is @@ -480,6 +477,19 @@ % describes the range of figures, tables, or whatever the labels refer % to, the default for English is ``|\ref{#1} to~\ref{#2}|''. % +% +% \NewIn{2020} +% \DescribeMacro\vrefformat +% \DescribeMacro\Vrefformat +% \DescribeMacro\vrefrangeformat +% \DescribeMacro\fullrefformat +% In some languages (currently only for Japanese) the generated text +% has to typeset in different word order to most other (Western) languages. +% To accomodate for this \cs{vrefformat}, etc.\ has been +% added to allow to alter this on a per language basis. +% There should be normally no need to alter the setup. For details see +% the code section. +% % \subsection{\ldots\ if Babel is used} % % \begin{itshape} If babel is being used then the above commands need to be @@ -561,6 +571,7 @@ % |\fullref| is also provided. This command can be used whenever you % know for sure that label and reference can't fall onto nearby pages. % +% % \StopEventually{\PrintIndex\PrintChanges} % % @@ -713,6 +724,9 @@ \def\reftextfaraway#1{op bladsy~\pageref{#1}}% \def\reftextpagerange#1#2{op bladsye~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} tot~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -729,6 +743,9 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -750,6 +767,9 @@ \def\reftextfaraway#1{بالصفحة رقم~\pageref{#1}}% \def\reftextpagerange#1#2{بالصفحات~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} حتى~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -783,6 +803,9 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -801,6 +824,9 @@ \def\reftextfaraway#1{~\pageref{#1}. orrialdean}% \def\reftextpagerange#1#2{~\pageref{#1}--\pageref{#2} orrialdeetan}% \def\reftextlabelrange#1#2{\ref{#1}.etik \ref{#2}.eraino}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -826,6 +852,9 @@ \def\reftextfaraway#1{pada muka surat~\pageref{#1}}% \def\reftextpagerange#1#2{pada muka surat~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -849,6 +878,9 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -871,6 +903,9 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -906,6 +941,9 @@ \cyrs\cyrt\cyrr\cyra\cyrn\cyri\cyrc\cyri ~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \cyrd\cyro~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -925,6 +963,9 @@ \def\reftextpagerange#1#2{a les p\`agines~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -942,6 +983,9 @@ \def\reftextfaraway#1{na stranici~\pageref{#1}}% \def\reftextpagerange#1#2{na stranicama~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} do~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -960,6 +1004,9 @@ \def\reftextfaraway#1{na stran\v{e}~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}\--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v{z}~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -983,6 +1030,9 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1023,6 +1073,9 @@ % \begin{macrocode} \def\reftextpagerange#1#2{op pagina's~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1041,6 +1094,9 @@ \def\reftextfaraway#1{on page~\pageref{#1}}% \def\reftextpagerange#1#2{on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} to~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1062,6 +1118,9 @@ \def\reftextfaraway#1{en pa\^go~\pageref{#1}}% \def\reftextpagerange#1#2{en pa\^goj~\pageref{#1} \^gis \pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \^gis~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1086,6 +1145,9 @@ % Can't combine numbers with the necessary suffix well. % \begin{macrocode} \def\reftextlabelrange#1#2{\ref{#1}--\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1106,6 +1168,9 @@ \def\reftextfaraway#1{page~\pageref{#1}}% \def\reftextpagerange#1#2{pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} \`a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1128,6 +1193,9 @@ \def\reftextpagerange#1#2{% nas p\'axinas~\pageref{#1}-\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1163,6 +1231,9 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1181,6 +1252,9 @@ \def\reftextfaraway#1{auf Seite~\pageref{#1}}% \def\reftextpagerange#1#2{auf den Seiten~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} bis~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1201,6 +1275,9 @@ \def\reftextpagerange#1#2{stis sel'ides\nobreakspace \pageref{#1}---\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} ws\nobreakspace\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1222,6 +1299,9 @@ \def\reftextfaraway#1{\'{a} s\'{i}{\dh}u~\pageref{#1}}% \def\reftextpagerange#1#2{\'{a} s\'{i}{\dh}um~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1247,29 +1327,41 @@ \def\reftextfaraway#1{a pagina~\pageref{#1}}% \def\reftextpagerange#1#2{nelle pagine~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{da~\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} -% Defaults for Japanese. It needs a special \cs{vrefrangeformat} +% Defaults for Japanese. It needs a special \cs{vrefformat}, +% \cs{Vrefformat}, \cs{fullrefformat} and \cs{vrefrangeformat} % for gramatical reasons. As our standard documentation % workflow uses pdf\TeX{} the Japanese letters can't be displayed % easily, so you will see missing glyphs below. To see the real % letters you have to look at the source or package file. % \changes{v1.6d}{2020/07/20}{Option japanese added (gh/352)} +% \changes{v1.6e}{2020/07/25}{Option japanese changed (gh/352)} % \begin{allowtofu} % \begin{macrocode} \DeclareOption{japanese} {\vref@addto\extrasjapanese{% - \def\reftextfaceafter {\reftextvario{見開き}{次}頁}% - \def\reftextfacebefore{\reftextvario{見開き}{前}頁}% - \def\reftextafter {\reftextvario{直後の}{次}頁}% - \def\reftextbefore {\reftextvario{直前の}{前}頁}% - \def\reftextcurrent {\reftextvario{この}{現}頁}% - \def\reftextfaraway#1{\pageref{#1}頁}% - \def\reftextpagerange#1#2{\pageref{#1}頁から\pageref{#2}頁}% + \def\reftextfaceafter {\reftextvario{見開き}{次}ページ}% + \def\reftextfacebefore{\reftextvario{見開き}{前}ページ}% + \def\reftextafter {\reftextvario{直後の}{次}ページ}% + \def\reftextbefore {\reftextvario{直前の}{前}ページ}% + \def\reftextcurrent {\reftextvario{この}{現}ページ}% + \def\reftextfaraway#1{\pageref{#1}ページ}% + \def\reftextpagerange#1#2{\pageref{#1}から\pageref{#2}ページ}% \def\reftextlabelrange#1#2{\ref{#1}から\ref{#2}}% - \def\vrefrangeformat#1#2#3{\vpagerefrange[{#1}]{#2}{#3}の% - \reftextlabelrange{#2}{#3}}% +% \end{macrocode} +% Note that the parentheses beow are not normal ones but full width +% ones U+FF08 and U+FF09! +% \begin{macrocode} + \def\vrefformat#1#2{\ref{#2}(\vpageref[#1]{#2})}% + \def\Vrefformat#1#2{\Ref{#2}(\vpageref[#1]{#2})}% + \def\fullrefformat#1{\ref{#1}(\reftextfaraway{#1})}% + \def\vrefrangeformat#1#2#3{\reftextlabelrange{#2}{#3}% + (\vpagerefrange[{#1}]{#2}{#3})}% }} % \end{macrocode} % \end{allowtofu} @@ -1317,6 +1409,9 @@ on pages~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\vref@stringwarning\reflabelpagerange \ref{#1} to~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }% % \end{macrocode} @@ -1358,6 +1453,9 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{nynorsk} @@ -1370,6 +1468,9 @@ \def\reftextfaraway#1{p\aa{} side~\pageref{#1}}% \def\reftextpagerange#1#2{p\aa{} side~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} til~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1398,6 +1499,9 @@ \def\reftextfaraway#1{na stronie~\pageref{#1}}% \def\reftextpagerange#1#2{na stronach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1419,6 +1523,9 @@ \def\reftextfaraway#1{na p\'agina~\pageref{#1}}% \def\reftextpagerange#1#2{nas p\'aginas~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1439,6 +1546,9 @@ \def\reftextfaraway#1{pe pagina~\pageref{#1}}% \def\reftextpagerange#1#2{pe paginile~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} la~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1473,6 +1583,9 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyrr\cyra\cyrn \cyri\cyrc\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrs~\ref{#1}\ \cyrp\cyro~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1494,6 +1607,9 @@ \def\reftextfaraway#1{na strane~\pageref{#1}}% \def\reftextpagerange#1#2{na stran\'ach~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a\v z~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1511,6 +1627,9 @@ \def\reftextfaraway#1{na strani~\pageref{#1}}% \def\reftextpagerange#1#2{na straneh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{od~\ref{#1} do~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1532,6 +1651,9 @@ \def\reftextpagerange#1#2{en las p\'aginas~\pageref{#1}% -\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} a~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1555,6 +1677,9 @@ \def\reftextpagerange#1#2{p\aa\ sidorna~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\ref{#1} till~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} \DeclareOption{turkish} @@ -1597,6 +1722,9 @@ \def\reftextpagerange#1#2{\cyrn\cyra\ \cyrs\cyrt\cyro\cyrr\cyrii \cyrn\cyrk\cyra\cyrh~\pageref{#1}--\pageref{#2}}% \def\reftextlabelrange#1#2{\cyrz~\ref{#1}\ \cyrd\cyro~\ref{#2}}% + \let\vrefformat\vrefdefaultformat + \let\Vrefformat\Vrefdefaultformat + \let\fullrefformat\fullrefdefaultformat \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} @@ -1651,7 +1779,6 @@ % \pkg{babel} package). % \begin{macrocode} \ExecuteOptions{english,final,space} -\ProcessOptions* % \end{macrocode} % % @@ -2128,11 +2255,26 @@ % |\vpageref|, it that is needed one has to call both commands % explicitly % \changes{v1.6a}{2019/08/25}{Command added to support hyperref better} +% \changes{v1.6e}{2020/07/25}{Changed for Japanese (gh/352)} % \begin{macrocode} -\newcommand\vref@star[2][]{% +\newcommand\vref@star[1][]{\vrefformat{#1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\vrefformat,\vrefdefaultformat} +% Japanese needs a different word order in \cs{vref@star} so this +% is separated out o that it can be changed on language level. +% \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} +% \begin{macrocode} +\def\vrefdefaultformat#1#2{% \ref{#2} \vpageref[#1]{#2}} % \end{macrocode} +% Most languages need the above definition. +% \begin{macrocode} +\let\vrefformat\vrefdefaultformat +% \end{macrocode} % \end{macro} % \begin{macro}{\vr@f} @@ -2238,8 +2380,24 @@ % \begin{macro}{\fullref} % And here is the primitive command that always produces a |\ref| % and a |\pageref|. +% \changes{v1.6e}{2020/07/25}{Changed for Japanese (gh/352)} % \begin{macrocode} -\def\fullref#1{\ref{#1} \reftextfaraway{#1}} +\newcommand\fullref{\fullrefformat} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\fullrefformat,\fullrefdefaultformat} +% Japanese needs a different word order in \cs{fullref} so this +% is separated out o that it can be changed on language level. +% \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} +% \begin{macrocode} +\def\fullrefdefaultformat#1{% + \ref{#1} \reftextfaraway{#1}} +% \end{macrocode} +% Most languages need the above definition. +% \begin{macrocode} +\let\fullrefformat\fullrefdefaultformat % \end{macrocode} % \end{macro} % @@ -2362,7 +2520,7 @@ % % % \begin{macro}{\vrefrangeformat,\vrefrangedefaultformat} -% Japanese needs a different word order in \cs{vrefrange} so this +% Japanese needs a different word order in \cs{vrefrange} so this % is separated out o that it can be changed on language level. % \changes{v1.6d}{2020/07/20}{Macro added (gh/352)} % \begin{macrocode} @@ -2389,11 +2547,26 @@ % % \begin{macro}{\Vref@star} % \changes{v1.6a}{2019/08/25}{Command added to support hyperref better} +% \changes{v1.6e}{2020/07/25}{Changed for Japanese (gh/352)} % \begin{macrocode} -\newcommand\Vref@star[2][]{% +\newcommand\Vref@star[1][]{\Vrefformat{#1}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\Vrefformat,\Vrefdefaultformat} +% Japanese needs a different word order in \cs{Vref} so this +% is separated out o that it can be changed on language level. +% \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} +% \begin{macrocode} +\def\Vrefdefaultformat#1#2{% \Ref{#2} \vpageref[#1]{#2}} % \end{macrocode} +% Most languages need the above definition. +% \begin{macrocode} +\let\Vrefformat\Vrefdefaultformat +% \end{macrocode} % \end{macro} % % \begin{macro}{\Vr@f} @@ -2524,6 +2697,12 @@ % \end{macro} % \end{macro} % +% \changes{v1.6e}{2020/07/25}{Move to handle +% the language-specific reference formats. (gh/352)} +% \begin{macrocode} +\ProcessOptions* +% \end{macrocode} +% % \begin{macrocode} %</package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex-dev/tools/xr.dtx b/Master/texmf-dist/source/latex-dev/tools/xr.dtx index a2dbea7c1e5..a963886cde7 100644 --- a/Master/texmf-dist/source/latex-dev/tools/xr.dtx +++ b/Master/texmf-dist/source/latex-dev/tools/xr.dtx @@ -110,7 +110,7 @@ \def\XR@[#1]#2{{% \makeatletter \def\XR@prefix{#1}% - \set@curr@file@trim@spaces{#2}% + \set@curr@file{#2}% \expandafter\XR@next\@curr@file.aux\relax\\}} % \end{macrocode} % |