summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex-dev
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2020-08-31 21:23:42 +0000
committerKarl Berry <karl@freefriends.org>2020-08-31 21:23:42 +0000
commit559a5f5789eaa2d6b0c848ebcdbb10d9e4997794 (patch)
tree9bff60e8286b9ddb26d4ffa06cc3e275716821da /Master/texmf-dist/source/latex-dev
parent0a15ec8dcd6ba524dfb1f80663dd69d0cc2dd899 (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/latex-dev')
-rw-r--r--Master/texmf-dist/source/latex-dev/amsmath/amsmath.dtx42
-rw-r--r--Master/texmf-dist/source/latex-dev/base/fontdef.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/format.ins23
-rw-r--r--Master/texmf-dist/source/latex-dev/base/inputenc.dtx4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latex209.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexrelease.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltboxes.dtx36
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltclass.dtx456
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltdefns.dtx703
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx6
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltexpl.dtx78
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx1538
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfiles.dtx418
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfinal.dtx224
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx31
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssini.dtx785
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lthooks.dtx1729
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lthooks.ins76
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltluatex.dtx41
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmath.dtx11
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx353
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx16
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutput.dtx15
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpage.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpictur.dtx593
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltplain.dtx32
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltsect.dtx29
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltshipout.dtx825
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltvers.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx9
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltxref.dtx5
-rw-r--r--Master/texmf-dist/source/latex-dev/base/unpack.ins2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/varioref.dtx223
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/xr.dtx2
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}
%