From 6c6a334f0aa3b95572afe30fa2d17e634c7019ce Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Fri, 1 Jan 2021 03:04:10 +0000 Subject: CTAN sync 202101010304 --- macros/latex/base/README.md | 2 +- macros/latex/base/alltt.pdf | Bin 173079 -> 173079 bytes macros/latex/base/cfgguide.pdf | Bin 220217 -> 220217 bytes macros/latex/base/changes.txt | 72 +++ macros/latex/base/classes.pdf | Bin 520851 -> 520851 bytes macros/latex/base/clsguide.pdf | Bin 372555 -> 372555 bytes macros/latex/base/cmfonts.pdf | Bin 264505 -> 264505 bytes macros/latex/base/cyrguide.pdf | Bin 216997 -> 216997 bytes macros/latex/base/doc.pdf | Bin 630922 -> 631201 bytes macros/latex/base/docstrip.pdf | Bin 479544 -> 479501 bytes macros/latex/base/encguide.pdf | Bin 1532144 -> 1532144 bytes macros/latex/base/exscale.pdf | Bin 195877 -> 195877 bytes macros/latex/base/fix-cm.pdf | Bin 262059 -> 262059 bytes macros/latex/base/fntguide.pdf | Bin 417861 -> 418342 bytes macros/latex/base/fntguide.tex | 16 +- macros/latex/base/graphpap.pdf | Bin 156277 -> 156277 bytes macros/latex/base/ifthen.pdf | Bin 205213 -> 205213 bytes macros/latex/base/inputenc.pdf | Bin 294900 -> 294900 bytes macros/latex/base/latexchanges.pdf | Bin 232390 -> 232390 bytes macros/latex/base/latexrelease.ins | 48 +- macros/latex/base/latexrelease.pdf | Bin 246195 -> 246195 bytes macros/latex/base/latexsym.pdf | Bin 192297 -> 192297 bytes macros/latex/base/lb2.pdf | Bin 138219 -> 138219 bytes macros/latex/base/letter.pdf | Bin 305700 -> 305786 bytes macros/latex/base/lgc2.pdf | Bin 101343 -> 101343 bytes macros/latex/base/lppl.pdf | Bin 125830 -> 125830 bytes macros/latex/base/ltclass.dtx | 200 +++++++- macros/latex/base/ltdefns.dtx | 13 +- macros/latex/base/ltexpl.dtx | 123 ++++- macros/latex/base/ltfilehook-code.pdf | Bin 735464 -> 744388 bytes macros/latex/base/ltfilehook-doc.pdf | Bin 516397 -> 516587 bytes macros/latex/base/ltfilehook.dtx | 174 +++++-- macros/latex/base/ltfssaxes.dtx | 2 +- macros/latex/base/ltfssbas.dtx | 23 +- macros/latex/base/lthooks-code.pdf | Bin 901929 -> 926391 bytes macros/latex/base/lthooks-doc.pdf | Bin 621088 -> 626854 bytes macros/latex/base/lthooks.dtx | 830 ++++++++++++++++++++++++---------- macros/latex/base/ltluatex.pdf | Bin 305339 -> 305339 bytes macros/latex/base/ltmath.dtx | 9 +- macros/latex/base/ltmiscen.dtx | 15 +- macros/latex/base/ltnews.pdf | Bin 989398 -> 989398 bytes macros/latex/base/ltnews01.pdf | Bin 150020 -> 150020 bytes macros/latex/base/ltnews02.pdf | Bin 134751 -> 134751 bytes macros/latex/base/ltnews03.pdf | Bin 134742 -> 134742 bytes macros/latex/base/ltnews04.pdf | Bin 128772 -> 128772 bytes macros/latex/base/ltnews05.pdf | Bin 157181 -> 157181 bytes macros/latex/base/ltnews06.pdf | Bin 133138 -> 133138 bytes macros/latex/base/ltnews07.pdf | Bin 124029 -> 124029 bytes macros/latex/base/ltnews08.pdf | Bin 144482 -> 144482 bytes macros/latex/base/ltnews09.pdf | Bin 120222 -> 120222 bytes macros/latex/base/ltnews10.pdf | Bin 147946 -> 147946 bytes macros/latex/base/ltnews11.pdf | Bin 104936 -> 104936 bytes macros/latex/base/ltnews12.pdf | Bin 137919 -> 137919 bytes macros/latex/base/ltnews13.pdf | Bin 161065 -> 161065 bytes macros/latex/base/ltnews14.pdf | Bin 150907 -> 150907 bytes macros/latex/base/ltnews15.pdf | Bin 122092 -> 122092 bytes macros/latex/base/ltnews16.pdf | Bin 130687 -> 130687 bytes macros/latex/base/ltnews17.pdf | Bin 149838 -> 149838 bytes macros/latex/base/ltnews18.pdf | Bin 36005 -> 36005 bytes macros/latex/base/ltnews19.pdf | Bin 235073 -> 235073 bytes macros/latex/base/ltnews20.pdf | Bin 283318 -> 283318 bytes macros/latex/base/ltnews21.pdf | Bin 233492 -> 233492 bytes macros/latex/base/ltnews22.pdf | Bin 302836 -> 302836 bytes macros/latex/base/ltnews23.pdf | Bin 274459 -> 274459 bytes macros/latex/base/ltnews24.pdf | Bin 252645 -> 252645 bytes macros/latex/base/ltnews25.pdf | Bin 196326 -> 196326 bytes macros/latex/base/ltnews26.pdf | Bin 362839 -> 362839 bytes macros/latex/base/ltnews27.pdf | Bin 239758 -> 239758 bytes macros/latex/base/ltnews28.pdf | Bin 368226 -> 368226 bytes macros/latex/base/ltnews29.pdf | Bin 433004 -> 433004 bytes macros/latex/base/ltnews30.pdf | Bin 491246 -> 491246 bytes macros/latex/base/ltnews31.pdf | Bin 500919 -> 500919 bytes macros/latex/base/ltnews32.pdf | Bin 520923 -> 520923 bytes macros/latex/base/ltshipout-code.pdf | Bin 749471 -> 750748 bytes macros/latex/base/ltshipout-doc.pdf | Bin 503979 -> 503965 bytes macros/latex/base/ltshipout.dtx | 22 +- macros/latex/base/ltvers.dtx | 2 +- macros/latex/base/ltx3info.pdf | Bin 191527 -> 191527 bytes macros/latex/base/ltxdoc.pdf | Bin 215102 -> 215102 bytes macros/latex/base/makeindx.pdf | Bin 160667 -> 160667 bytes macros/latex/base/manual.pdf | Bin 151347 -> 151347 bytes macros/latex/base/modguide.pdf | Bin 220388 -> 220388 bytes macros/latex/base/nfssfont.pdf | Bin 202451 -> 202451 bytes macros/latex/base/proc.pdf | Bin 216877 -> 216877 bytes macros/latex/base/slides.pdf | Bin 351586 -> 351586 bytes macros/latex/base/slifonts.pdf | Bin 214710 -> 214710 bytes macros/latex/base/source2e.pdf | Bin 4349921 -> 4357396 bytes macros/latex/base/source2edoc.cls | 39 +- macros/latex/base/syntonly.pdf | Bin 181390 -> 181787 bytes macros/latex/base/tlc2.pdf | Bin 164947 -> 164947 bytes macros/latex/base/tulm.pdf | Bin 156546 -> 156546 bytes macros/latex/base/usrguide.pdf | Bin 399035 -> 399035 bytes macros/latex/base/utf8ienc.pdf | Bin 330853 -> 331074 bytes macros/latex/base/webcomp.pdf | Bin 136159 -> 136159 bytes 94 files changed, 1228 insertions(+), 362 deletions(-) (limited to 'macros/latex/base') diff --git a/macros/latex/base/README.md b/macros/latex/base/README.md index d566ca97ce..7c6328be6d 100644 --- a/macros/latex/base/README.md +++ b/macros/latex/base/README.md @@ -1,7 +1,7 @@ The LaTeX kernel ================ -Release 2020-10-01 patch level 2 +Release 2020-10-01 patch level 3 Overview -------- diff --git a/macros/latex/base/alltt.pdf b/macros/latex/base/alltt.pdf index dce36a436c..5cb6410fa1 100644 Binary files a/macros/latex/base/alltt.pdf and b/macros/latex/base/alltt.pdf differ diff --git a/macros/latex/base/cfgguide.pdf b/macros/latex/base/cfgguide.pdf index 2f9e6e9974..c0cb3f3c6f 100644 Binary files a/macros/latex/base/cfgguide.pdf and b/macros/latex/base/cfgguide.pdf differ diff --git a/macros/latex/base/changes.txt b/macros/latex/base/changes.txt index 29f3d2937f..cc8d59b61b 100644 --- a/macros/latex/base/changes.txt +++ b/macros/latex/base/changes.txt @@ -10,6 +10,78 @@ are not part of the distribution. All changes above are only part of the development branch for the next release. ================================================================================ +######################### +# 2020-10-01 PL 3 Release +######################### + +2020-12-18 Phelype Oleinik + + * lthooks.dtx: + Moved 'top-level' code label at the very end of hooks. + - In reverse hooks, 'top-level' goes at the beginning. + - 'top-level' cannot be used as a label outside of the top-level. + - The label for the 'top-level' cannot be changed. + - Simplified internal managing of default label. + Renamed \DeclareDefaultHookLabel to \SetDefaultHookLabel (the old name + will be kept until the next release). + Provide \PushDefaultHookLabel and \PopDefaultHookLabel. + Fixed a small bug in \ShowHook and \LogHook. + + * ltclass.dtx: + Remove \@expl@@@hook@curr@name@push@@n from \@pushfilename to + follow changes to lthooks.dtx. + +2020-12-10 Frank Mittelbach + + * ltfssbas.dtx (subsection{Macros for the user}): + Drop ``m'' if the series value is a member of a fixed list + and issue warning if doing it (gh/453) + +2020-11-24 Frank Mittelbach + + * latexrelease.ins: + reorder module loading to match the order used + in the format to correctly resolve dependencies (gh/434) + + * ltexpl.dtx (subsection{Loader}): + Load xparse in latexrelease if necessary and add missing + IncludeInRelease guards (gh/434) + + * ltdefns.dtx, ltfilehook.dtx, lthooks.dtx, ltxshipout.dtx: + Add rollback support for forward case (gh/434) + +2020-11-20 Phelype Oleinik + + * ltclass.dtx: + Remove file path from \@currname and use only \@currname to identify + a package internally (gh/422). + Add \@currpath and (temporarily) \@kernel@currpathstack. + In \ProvidesPackage check the argument with \strcmp instead of \ifx. + In case of substitution, copy the option list to the requested package. + + * ltfilehook.dtx: + Keep path in the replacement file (#2) in \declare@file@substitution. + In case of a replacement, pass the actually loaded file to \@addtofilelist. + Explicitly clear replacement flag after using it. + +2020-11-17 Frank Mittelbach + + * fntguide.tex: + Updated documentation of virtual shapes \updefault and \ulcdefault + +2020-11-09 Frank Mittelbach + + * ltmath.dtx: + \negmedspace and \negthickspace have been only in amsmath, + so we need to undefine for rollback because amsmath used + \newcommand back then (gh/423) + +2020-11-09 Frank Mittelbach + + * ltclass.dtx (section{Package/class rollback mechanism}): + Change help text for suspicous rollback, because the package may have + existed then --- there is just no rollback data (gh/423) + ######################### # 2020-10-01 PL 2 Release ######################### diff --git a/macros/latex/base/classes.pdf b/macros/latex/base/classes.pdf index b0be55c53f..05b9379ef4 100644 Binary files a/macros/latex/base/classes.pdf and b/macros/latex/base/classes.pdf differ diff --git a/macros/latex/base/clsguide.pdf b/macros/latex/base/clsguide.pdf index 1a7e752cc3..c5d32dda9f 100644 Binary files a/macros/latex/base/clsguide.pdf and b/macros/latex/base/clsguide.pdf differ diff --git a/macros/latex/base/cmfonts.pdf b/macros/latex/base/cmfonts.pdf index c3502760ce..fe8f0083f6 100644 Binary files a/macros/latex/base/cmfonts.pdf and b/macros/latex/base/cmfonts.pdf differ diff --git a/macros/latex/base/cyrguide.pdf b/macros/latex/base/cyrguide.pdf index 1331bbc54f..6fa40a338b 100644 Binary files a/macros/latex/base/cyrguide.pdf and b/macros/latex/base/cyrguide.pdf differ diff --git a/macros/latex/base/doc.pdf b/macros/latex/base/doc.pdf index dcb78001b3..5feed95398 100644 Binary files a/macros/latex/base/doc.pdf and b/macros/latex/base/doc.pdf differ diff --git a/macros/latex/base/docstrip.pdf b/macros/latex/base/docstrip.pdf index aeda25af00..2e31d253a1 100644 Binary files a/macros/latex/base/docstrip.pdf and b/macros/latex/base/docstrip.pdf differ diff --git a/macros/latex/base/encguide.pdf b/macros/latex/base/encguide.pdf index 286a167553..249493684e 100644 Binary files a/macros/latex/base/encguide.pdf and b/macros/latex/base/encguide.pdf differ diff --git a/macros/latex/base/exscale.pdf b/macros/latex/base/exscale.pdf index 8d33cdefab..339a4d161a 100644 Binary files a/macros/latex/base/exscale.pdf and b/macros/latex/base/exscale.pdf differ diff --git a/macros/latex/base/fix-cm.pdf b/macros/latex/base/fix-cm.pdf index 07ff74d687..f39aca2525 100644 Binary files a/macros/latex/base/fix-cm.pdf and b/macros/latex/base/fix-cm.pdf differ diff --git a/macros/latex/base/fntguide.pdf b/macros/latex/base/fntguide.pdf index b3824b59a1..97c8a844f7 100644 Binary files a/macros/latex/base/fntguide.pdf and b/macros/latex/base/fntguide.pdf differ diff --git a/macros/latex/base/fntguide.tex b/macros/latex/base/fntguide.tex index b6576a0237..7e0928c51b 100644 --- a/macros/latex/base/fntguide.tex +++ b/macros/latex/base/fntguide.tex @@ -42,7 +42,7 @@ newer NFSS features of 2020}\\ All rights reserved.} -\date{July 2020} +\date{November 2020} \begin{document} @@ -340,22 +340,25 @@ box warning, for example: \end{verbatim} The author commands for fonts set the five attributes: \begin{center} + \hspace*{-1em}% \begin{tabular}{rcl} \emph{Author command} & \emph{Attribute} & \emph{Value in} |article| \emph{class} \\ |\textnormal{..}| or |\normalfont| & family & |cmr| \\ + & series & |m| \\ + & shape & |n| \\[1pt] |\textrm{..}| or |\rmfamily| & family & |cmr| \\ |\textsf{..}| or |\sffamily| & family & |cmss| \\ |\texttt{..}| or |\ttfamily| & family & |cmtt| \\ |\textmd{..}| or |\mdseries| & series & |m| \\ - |\textbf{..}| or |\bfseries| & series & |bx| \\ - |\textup{..}| or |\upshape| & shape & |n| \\ + |\textbf{..}| or |\bfseries| & series & |bx| \\[1pt] |\textit{..}| or |\itshape| & shape & |it| \\ |\textsl{..}| or |\slshape| & shape & |sl| \\ |\textsc{..}| or |\scshape| & shape & |sc| \\ |\textssc{..}| or |\sscshape| & shape & |ssc| \\ |\textsw{..}| or |\swshape| & shape & |sw| \\ - |\textulc{..}| or |\ulcshape| & shape & |ulc| \\ + |\textulc{..}| or |\ulcshape| & shape & |ulc| (virtual) $\to$ |n|, |it|, |sl| or |ssc| \\ + |\textup{..}| or |\upshape| & shape & |up| (virtual) $\to$ |n| or |sc| \\[1pt] |\tiny| & size & |5pt| \\ |\scriptsize| & size & |7pt| \\ |\footnotesize| & size & |8pt| \\ @@ -520,8 +523,9 @@ and the |ssub| size function, see Section~\ref{sec:sizefunct}. The shapes selected by |\textit|, |\itshape|, |\textsl|, |\slshape|, |\textsc|, |\scshape|, |\textssc|, |\sscshape|, |\textsw|, |\swshape|, |\textulc|, |\ulcshape|, |\textup| and |\upshape|. By default these are -|it|, |sl|, |sc|, |ssc|, |sw|, |ulc| and |n|. |ulc| is special here -since it is a virtual one; it doesn't exist as a real shape. The +|it|, |sl|, |sc|, |ssc|, |sw|, |ulc| and |up|. Note that |ulc| and |up| are special here +because they are virtual shapes; they don't exist as real shape values. Instead they alter +the existing shape value based on rules, i.e., the result depends on context. The respective macros |\textulc| or |\ulcshape| change small capitals back to upper/lower case but will not change the font with respect to italics, slanted or swash. |\upshape| or |\textup| in contrast will diff --git a/macros/latex/base/graphpap.pdf b/macros/latex/base/graphpap.pdf index 8ebd4c91d3..8cad84bb4c 100644 Binary files a/macros/latex/base/graphpap.pdf and b/macros/latex/base/graphpap.pdf differ diff --git a/macros/latex/base/ifthen.pdf b/macros/latex/base/ifthen.pdf index 6218e4883a..be2ea9f956 100644 Binary files a/macros/latex/base/ifthen.pdf and b/macros/latex/base/ifthen.pdf differ diff --git a/macros/latex/base/inputenc.pdf b/macros/latex/base/inputenc.pdf index 0ee0cdd0ff..4c06af39d5 100644 Binary files a/macros/latex/base/inputenc.pdf and b/macros/latex/base/inputenc.pdf differ diff --git a/macros/latex/base/latexchanges.pdf b/macros/latex/base/latexchanges.pdf index d78a1e3b5a..97fcc3330b 100644 Binary files a/macros/latex/base/latexchanges.pdf and b/macros/latex/base/latexchanges.pdf differ diff --git a/macros/latex/base/latexrelease.ins b/macros/latex/base/latexrelease.ins index 99af17e8fb..ffc92374c3 100644 --- a/macros/latex/base/latexrelease.ins +++ b/macros/latex/base/latexrelease.ins @@ -81,11 +81,16 @@ extension .ins) which are part of the distribution. %\keepsilent \usedir{tex/latex/base} +% the order should match the order in the format in case there are dependencies +% (something defined in one module and used in another) + \generateFile{latexrelease.sty}{t}{% \from{ltclass.dtx} {latexreleasefirst,tracerollback}% \from{ltvers.dtx} {latexrelease}% \from{latexrelease.dtx}{latexrelease}% \from{ltdirchk.dtx} {latexrelease}% + \from{ltplain.dtx} {latexrelease}% + \from{ltluatex.dtx} {latexrelease}% empty \from{ltexpl.dtx} {latexrelease}% empty \from{ltdefns.dtx} {latexrelease}% \from{lthooks.dtx} {latexrelease}% empty % L3 layer module @@ -93,42 +98,39 @@ extension .ins) which are part of the distribution. \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty \from{ltpar.dtx} {latexrelease}% empty + \from{ltspace.dtx} {latexrelease}% + \from{ltlogos.dtx} {latexrelease}% empty + \from{ltfiles.dtx} {latexrelease}% + \from{ltoutenc.dtx} {latexrelease}% + \from{ltcounts.dtx} {latexrelease}% + \from{ltlength.dtx} {latexrelease}% + \from{ltfssbas.dtx} {latexrelease}% + \from{ltfssaxes.dtx} {latexrelease}% + \from{ltfsstrc.dtx} {latexrelease}% + \from{ltfssdcl.dtx} {latexrelease}% + \from{ltfssini.dtx} {latexrelease}% + \from{fontdef.dtx} {latexrelease}% (covering fontmath and fonttext) + \from{ltfntcmd.dtx} {latexrelease}% empty + \from{lttextcomp.dtx} {latexrelease}% + \from{ltpageno.dtx} {latexrelease}% empty + \from{ltxref.dtx} {latexrelease}% empty + \from{ltmiscen.dtx} {latexrelease}% + \from{ltmath.dtx} {latexrelease}% \from{ltlists.dtx} {latexrelease}% empty \from{ltboxes.dtx} {latexrelease}% \from{lttab.dtx} {latexrelease}% empty - \from{ltmath.dtx} {latexrelease}% \from{ltpictur.dtx} {latexrelease}% \from{ltthm.dtx} {latexrelease}% empty \from{ltsect.dtx} {latexrelease}% empty - \from{ltfiles.dtx} {latexrelease}% - \from{ltoutenc.dtx} {latexrelease}% - \from{ltcounts.dtx} {latexrelease}% - \from{ltlength.dtx} {latexrelease}% \from{ltfloat.dtx} {latexrelease}% \from{ltidxglo.dtx} {latexrelease}% empty \from{ltbibl.dtx} {latexrelease}% empty \from{ltpage.dtx} {latexrelease}% empty + \from{ltclass.dtx} {latexrelease,tracerollback}% \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}% - \from{ltlogos.dtx} {latexrelease}% empty - \from{ltplain.dtx} {latexrelease}% - \from{ltfssdcl.dtx} {latexrelease}% - \from{ltfssini.dtx} {latexrelease}% - \from{fontdef.dtx} {latexrelease}% (covering fontmath and fonttext) - \from{ltfntcmd.dtx} {latexrelease}% empty - \from{lttextcomp.dtx} {latexrelease}% - \from{ltfssbas.dtx} {latexrelease}% - \from{ltfssaxes.dtx} {latexrelease}% - \from{ltfsstrc.dtx} {latexrelease}% - \from{ltfsscmp.dtx} {latexrelease}% - \from{ltpageno.dtx} {latexrelease}% empty - \from{ltxref.dtx} {latexrelease}% empty - \from{ltmiscen.dtx} {latexrelease}% - \from{ltluatex.dtx} {latexrelease}% - \from{ltexpl.dtx} {latexrelease}% + \from{ltfsscmp.dtx} {latexrelease}% only in latexrelease! \from{ltfinal.dtx} {latexrelease}% } diff --git a/macros/latex/base/latexrelease.pdf b/macros/latex/base/latexrelease.pdf index f458d1a97c..d619076782 100644 Binary files a/macros/latex/base/latexrelease.pdf and b/macros/latex/base/latexrelease.pdf differ diff --git a/macros/latex/base/latexsym.pdf b/macros/latex/base/latexsym.pdf index 88db5ce701..436ea23f3a 100644 Binary files a/macros/latex/base/latexsym.pdf and b/macros/latex/base/latexsym.pdf differ diff --git a/macros/latex/base/lb2.pdf b/macros/latex/base/lb2.pdf index 4885ef5646..7d989cb0a0 100644 Binary files a/macros/latex/base/lb2.pdf and b/macros/latex/base/lb2.pdf differ diff --git a/macros/latex/base/letter.pdf b/macros/latex/base/letter.pdf index 85986ca947..104f1157e2 100644 Binary files a/macros/latex/base/letter.pdf and b/macros/latex/base/letter.pdf differ diff --git a/macros/latex/base/lgc2.pdf b/macros/latex/base/lgc2.pdf index bfed998126..f900bfefb3 100644 Binary files a/macros/latex/base/lgc2.pdf and b/macros/latex/base/lgc2.pdf differ diff --git a/macros/latex/base/lppl.pdf b/macros/latex/base/lppl.pdf index 18c3995534..20a630928c 100644 Binary files a/macros/latex/base/lppl.pdf and b/macros/latex/base/lppl.pdf differ diff --git a/macros/latex/base/ltclass.dtx b/macros/latex/base/ltclass.dtx index b639ae9410..c62136c309 100644 --- a/macros/latex/base/ltclass.dtx +++ b/macros/latex/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/10/18 v1.3t LaTeX Kernel (Class & Package Interface)] + [2020/12/17 v1.3v LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -524,6 +524,27 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@currpath} +% Path to the current file if explicitly given. +% \changes{v1.3u}{2020/11/20}{Macro added} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +% +%\IncludeInRelease{2020/10/01}{\@currpath}% +% {Add \@currpath}% +\let\@currpath\@empty +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@currpath}% +% {Add \@currpath}% +%\let\@currpath\@undefined +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@currname} % Name of current package or option. % \begin{macrocode} @@ -562,6 +583,7 @@ % \changes{v1.3l}{2020/06/05}{Added \cs{@expl@push@filename@@} % and \cs{@expl@push@filename@aux@@}} % \changes{v1.3s}{2020/10/08}{Added missing 2020/02/02 \cs{IncludeInRelease}} +% \changes{v1.3v}{2020/12/14}{Removed \cs{@expl@@@hook@curr@name@push@@n}} % \begin{macrocode} % %<*2ekernel|latexrelease> @@ -578,13 +600,22 @@ % here, e.g., \cs{@expl@push@filename@@} needs cleanup and (and % should probably not have this name either). % \begin{macrocode} - \@expl@@@hook@curr@name@push@@n{}% \@expl@push@filename@@ \xdef\@currnamestack{% {\@currname}% {\@currext}% {\the\catcode`\@}% \@currnamestack}% +% \end{macrocode} +% Temporarily add a stack for \cs{@currpath} here. This should be +% integrated in the main file stack eventually, but other packages +% rely on \cs{@currnamestack} having three elements per file, so that +% isn't a trivial change. The prefix \cs{@kernel@...} hopefully +% discourages people from using it. +% \begin{macrocode} + \xdef\@kernel@currpathstack{% + {\@currpath}% + \@kernel@currpathstack}% \@expl@push@filename@aux@@} %\EndIncludeInRelease % \end{macrocode} @@ -632,6 +663,10 @@ % {Add \@expl@pop@filename@@}% \def\@popfilename{\@expl@@@hook@curr@name@pop@@ \expandafter\@p@pfilename\@currnamestack\@nil +% \end{macrocode} +% Same for popping: +% \begin{macrocode} + \expandafter\@p@pfilepath\@kernel@currpathstack\@nil \@expl@pop@filename@@} %\EndIncludeInRelease % @@ -672,6 +707,36 @@ % \end{macro} % \end{macro} % +% +% \begin{macro}{\@kernel@currpathstack} +% Path to the current file if explicitly given. The auxiliary is +% needed here to insert a \cs{@empty} to prevent the loss of braces. +% \changes{v1.3u}{2020/11/20}{Macro added} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +% +%\IncludeInRelease{2020/10/01}{\@kernel@currpathstack}% +% {Add \@kernel@currpathstack}% +\gdef\@kernel@currpathstack{} +\def\@p@pfilepath#1{% + \gdef\@currpath{#1}\@p@pfilepath@aux\@empty} +\def\@p@pfilepath@aux#1\@nil{% + \xdef\@kernel@currpathstack{#1}} +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@kernel@currpathstack}% +% {Add \@kernel@currpathstack}% +%\let\@kernel@currpathstack\@undefined +%\let\@p@pfilepath\@undefined +%\let\@p@pfilepath@aux\@undefined +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{\@ptionlist} % Returns the option list of the file. % \begin{macrocode} @@ -915,15 +980,42 @@ % \changes{v0.3c}{1994/03/12} % {use \cs{@gtempa}} % \begin{macrocode} +% +%\IncludeInRelease{2020/10/01}% +% {\ProvidesPackage}{Check name with \strcmp}% +%<*2ekernel|latexrelease> \def\ProvidesPackage#1{% \xdef\@gtempa{#1}% - \ifx\@gtempa\@currname\else +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Use string comparison instead of \cs{ifx}} +% Here \cs{@currpath} is explicitly added to the file name to report +% when a package or class is loaded using an explicit path. Loading +% using a path in the argument is supported but not encouraged. +% \begin{macrocode} + \@expandtwoargs\@expl@str@if@eq@@nnTF + {\@gtempa}{\@currpath\@currname}{}{% \@latex@warning@no@line{You have requested - \@cls@pkg\space`\@currname',\MessageBreak + \@cls@pkg\space`\@currpath\@currname',\MessageBreak but the \@cls@pkg\space provides `#1'}% - \fi + }% \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%] \@onlypreamble\ProvidesPackage +% +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}% +% {\ProvidesPackage}{Undo: check name with \strcmp}% +%\def\ProvidesPackage#1{% +% \xdef\@gtempa{#1}% +% \ifx\@gtempa\@currname\else +% \@latex@warning@no@line{You have requested +% \@cls@pkg\space`\@currname',\MessageBreak +% but the \@cls@pkg\space provides `#1'}% +% \fi +% \@ifnextchar[\@pr@videpackage{\@pr@videpackage[]}}%] +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1007,9 +1099,18 @@ % % \begin{macro}{\ProvidesClass} % Like |\ProvidesPackage|, but for classes. +% This needs a dummy \pkg{latexrelease} block to copy the definition +% of \cs{ProvidesPackage} as it changes across releases. % \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}% +% {\ProvidesClass}{Track \ProvidesPackage}% +%<*2ekernel|latexrelease> \let\ProvidesClass\ProvidesPackage \@onlypreamble\ProvidesClass +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1075,10 +1176,18 @@ \@expl@@@filehook@set@curr@file@@nNN {\@expl@@@filehook@resolve@file@subst@@w #3.#1\@nil}% \reserved@a\reserved@b + \@expl@@@filehook@clear@replacement@flag@@ \expandafter\xdef\csname opt@\reserved@a\endcsname{% \@ifundefined{opt@\reserved@a}\@empty {\csname opt@\reserved@a\endcsname,}% - \zap@space#2 \@empty}} + \zap@space#2 \@empty}% +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Copy option list to the requested package.} +% \begin{macrocode} + \expandafter\let + \csname opt@#3.#1\expandafter\endcsname + \csname opt@\reserved@a\endcsname} % %\EndIncludeInRelease % @@ -1719,8 +1828,38 @@ %\IncludeInRelease{2020/10/01}% % {\@onefilewithoptions}{Hooks and unused options issue}% \def\@onefilewithoptions#1[#2][#3]#4{% +% \end{macrocode} +% We have to sanitise file names, so that something like +% \begin{verbatim} +% \usepackage{some/local/path/array} +% \usepackage{array} +% \end{verbatim} +% won't load \file{array.sty} twice. It is remotely possible that +% those are two different files, but as a matter of principles, we +% will consider that the base file name uniquely identifies a +% package, regardless of where it lives. This assumption already +% holds for file hooks, for example, which address the hook to a file +% by its base name only. +% +% We'll use \cs{@expl@@@filehook@set@curr@file@@nNN} to parse the +% file name and return the \meta{path} and \meta{base+ext} in +% separate token lists. Further ahead, most operations use +% \cs{@currname} which doesn't have a path attached to it; only few +% actions prepend \cs{@currpath} to \cs{@currname} (namely loading, +% as we have to respect the given path). +% +% A file substituiton isn't followed just yet because at this point +% we are parsing user input, so the file is still what the user +% asked for, and not the file actually loaded. +% \begin{macrocode} + \@expl@@@filehook@set@curr@file@@nNN{#1.#4}\reserved@a\reserved@b + \edef\reserved@c{\def\noexpand\reserved@c####1% + \detokenize\expandafter{\expanded{.#4}}% + \noexpand\@nil{\def\noexpand\reserved@a{####1}}}\reserved@c + \expandafter\reserved@c\reserved@a\@nil \@pushfilename - \xdef\@currname{#1}% + \xdef\@currname{\string@makeletter\reserved@a}% + \xdef\@currpath{\ifx\reserved@b\@empty\else\reserved@b/\fi}% \global\let\@currext#4% % \end{macrocode} % The command \cs{ver@\meta{file}.\meta{ext}} is used to signal that @@ -1765,9 +1904,11 @@ % \end{macrocode} % First we take the \meta{name} and \meta{ext} given in the argument % and check if the file exists, and issue an error otherwise asking -% for a correction with \cs{@missingfileerror}. +% for a correction with \cs{@missingfileerror}. For checking if the +% file exists we use \cs{@currpath} (usually empty) before +% \cs{@currname}. % \begin{macrocode} - \IfFileExists{\@currname.\@currext}{}% + \IfFileExists{\@currpath\@currname.\@currext}{}% {\@missing@onefilewithoptions{#2}}% % \end{macrocode} % If \cs{@currname} is empty (the user replied to the ``Enter file @@ -1784,11 +1925,12 @@ % do the bookkeeping with \cs{@filehook@file@push} % then call \cs{set@curr@file} to set \cs{@curr@file} (and do any % required substitution), then actually load the class/package with -% \cs{load@onefile@withoptions}. +% \cs{load@onefile@withoptions}. \cs{set@curr@file} also needs the +% file path. % \begin{macrocode} \@disable@packageload@do{\@currname.\@currext}% {\@expl@@@filehook@file@push@@ - \set@curr@file{\@currname.\@currext}% + \set@curr@file{\@currpath\@currname.\@currext}% \@filehook@set@CurrentFile % \end{macrocode} % \changes{v1.3q}{2020/09/06} @@ -1812,10 +1954,15 @@ \expandafter\@swaptwoargs\expandafter {\expandafter{\@currpkg@reqd}}% {% < +% \end{macrocode} +% \cs{@currpkg@reqd} doesn't take a path because it is used later to +% assign \cs[no-index]{opt@...} and \cs[no-index]{ver@...}. +% \begin{macrocode} \edef\@currpkg@reqd{\@currname.\@currext}% \ifx\CurrentFile\CurrentFileUsed \else \filename@parse\@curr@file + \edef\@currpath{\string@makeletter\filename@area}% \edef\@currname{\string@makeletter\filename@base}% \edef\@currext{\string@makeletter\filename@ext}% \fi @@ -1864,11 +2011,13 @@ % \end{macro} % % \begin{macro}{\@missing@onefilewithoptions} -% Now the action taken when a file is not found. +% Now the action taken when a file is not found. Path must be +% included here as it eventually leads to a file lookup. % \begin{macrocode} \def\@missing@onefilewithoptions#1{% - \@missingfileerror\@currname\@currext - \xdef\@currname{\@missingfile@area\@missingfile@base}% + \@missingfileerror{\@currpath\@currname}\@currext + \global\let\@currpath\@missingfile@area + \global\let\@currname\@missingfile@base \global\let\@currext\@missingfile@ext} % \end{macrocode} % \end{macro} @@ -1887,6 +2036,13 @@ % \begin{macrocode} \def\reserved@a{% \@pass@ptions\@currext{#1}{\@currname}% +% \end{macrocode} +% \changes{v1.3u}{2020/11/20} +% {Copy option list to the requested package.} +% \begin{macrocode} + \expandafter\let + \csname opt@\@currpkg@reqd\expandafter\endcsname + \csname opt@\@currname.\@currext\endcsname \global\expandafter \let\csname ver@\@currname.\@currext\endcsname\@empty % \end{macrocode} @@ -1912,11 +2068,12 @@ \fi % \end{macrocode} % Now actually load the file (at this point we are certain it exists, -% but use \cs{InputIfFileExists} so that file hooks are executed): +% but use \cs{InputIfFileExists} so that file hooks are executed). +% \cs{@currpath} is needed here too. % \begin{macrocode} - \InputIfFileExists{\@currpkg@reqd}{}% + \InputIfFileExists{\@currpath\@currpkg@reqd}{}% {\@latex@error - {The \@cls@pkg\space\@currpkg@reqd\space failed to load.}\@ehd}% + {The \@cls@pkg\space\@currpkg@reqd\space failed to load}\@ehd}% %----------------------------------------- % \end{macrocode} % In older versions of the code |\@unprocessedoptions| would @@ -3271,19 +3428,20 @@ % A similar error is given if global rollback date and min-date on % a specific package conflict with each other, but that case is % happens only once so it is inlined. +% \changes{v1.3u}{2020/11/09}{Change help text because the package may have +% existed then --- there is just no rollback data (gh/423).} % \begin{macrocode} \def\pkgcls@rollbackdate@error#1{% \@latex@error{Suspicious rollback date given}% - {The \@cls@pkg\space'\@currname' claims that it - came into existence on #1 which\MessageBreak + {The \@cls@pkg\space'\@currname' has no rollback data + before #1 which\MessageBreak is after your requested rollback date --- so - something is wrong here.\MessageBreak + something may be wrong here.\MessageBreak Continue and we use the earliest known release.}} % \end{macrocode} % \end{macro} % % -% % \begin{macro}{\DeclareCurrentRelease} % This declares the date (and possible name) of the current version % of a package or class. diff --git a/macros/latex/base/ltdefns.dtx b/macros/latex/base/ltdefns.dtx index 569c9db4df..920c1acde6 100644 --- a/macros/latex/base/ltdefns.dtx +++ b/macros/latex/base/ltdefns.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2020/09/25 v1.5n LaTeX Kernel (definition commands)] + [2020/11/25 v1.5o LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -385,8 +385,19 @@ % \begin{macro}{\@carcube} % |\@carcube T1 ... Tn\@nil| = |T1| |T2| |T3| , $n > 3$ % \changes{v1.5k}{2020/08/19}{Made \cs{long} for \cs{NewCommandCopy}} +% \changes{v1.5o}{2020/11/25}{Added missing latexrelease entry} % \begin{macrocode} +% +%\IncludeInRelease{2020/10/01}{\@carcube}{Make \@carcube long}% +%<*2ekernel|latexrelease> \long\def\@carcube#1#2#3#4\@nil{#1#2#3} +% +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\@carcube}{Undo: Make \@carcube long}% +%\def\@carcube#1#2#3#4\@nil{#1#2#3} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/ltexpl.dtx b/macros/latex/base/ltexpl.dtx index 4100da79c2..7f9019ede3 100644 --- a/macros/latex/base/ltexpl.dtx +++ b/macros/latex/base/ltexpl.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2020/09/06 v1.2f LaTeX Kernel (expl3-dependent code)] + [2020/12/18 v1.2h LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -72,16 +72,45 @@ % {Define a local version of some \LaTeXe{} basic macros to support % package loading} % +% \begin{macro}{\@kernel@after@enddocument, +% \@kernel@after@enddocument@afterlastpage} +% These two kernel hooks are used by the shipout code. They are +% defined earlier here because the \pkg{lthooks} code adds material +% to them. +% \changes{v1.2h}{2020/12/18} +% {Define kernel \cs{enddocument} hooks early} +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% +\let\@kernel@after@enddocument\@empty +\let\@kernel@after@enddocument@afterlastpage\@empty +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% +%\let\@kernel@after@enddocument\@undefined +%\let\@kernel@after@enddocument@afterlastpage\@undefined +%\EndIncludeInRelease +% +% \end{macrocode} +% \end{macro} +% % First define some blank commands, so that in case something goes wrong while % loading \textsf{expl3}, we won't get strange \texttt{Undefined control % sequence} errors. % \begin{macrocode} -%<*2ekernel> +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/10/01}% +% {\@expl@sys@load@backend@@}{Roll forward support}% \def\@expl@sys@load@backend@@{} \def\@expl@push@filename@@{} \def\@expl@push@filename@aux@@{} \def\@expl@pop@filename@@{} -% +%\EndIncludeInRelease +% % \end{macrocode} % % \changes{v1.2d}{2020/07/08} @@ -183,9 +212,20 @@ \errmessage{LaTeX requires expl3}% \batchmode \read -1 to \reserved@a % +% \end{macrocode} +% We do not support a roll forward across 2019. You need to start +% with 2019 if you want to get to 2020 or beyond. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} %<*latexrelease> - \@latex@error{LaTeX requires expl3}\@ehd - \@gobble + \@latex@warning@no@line + {You need a format that already contains a recent\MessageBreak + expl3 as part of the kernel, e.g. at least a kernel\MessageBreak + from 2019 to roll forward to that date!\MessageBreak + --- I'm giving up!\MessageBreak\MessageBreak + Note that manually loading the expl3 package\MessageBreak + from your distribution is not enough}% + \@@end % die % }% {% @@ -222,6 +262,36 @@ %\EndIncludeInRelease % \end{macrocode} % +% +% Starting with 2020-10 the kernel contains most of the +% \texttt{xparse} interfaces loaded above. These interfaces are +% later used to define various user command. However, if somebody +% with an earlier installation tries to roll forward (using a +% \texttt{latexrelease} package from a newer release) this will not +% work as the earlier kernel doesn't contain commands such as +% \cs{NewDocumentCommand}. +% +% We therefore add code into \texttt{latexrelease.sty} to load the +% \texttt{xparse} package of the current installation instead. this +% may not work if the installation is really old, but roll forward +% can't do miracles. +% +% If the kernel is 2020-10 or later \cs{NewDocumentCommand} is +% already known (whether or not you roll forward or back) so +% nothing happens, but if you start from am earlier kernel the +% \texttt{xparse} package gets loaded by \texttt{latexrelease}. +% \changes{v1.2g}{2020/11/24}{Load xparse in latexrelease if needed (gh/434)} +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}% +% {\NewDocumentCommand}{Emergency loading xparse}% +% +%\ifdefined\NewDocumentCommand \else +% \RequirePackage{xparse} +%\fi +% +%\EndIncludeInRelease +% \end{macrocode} +% % \subsection{Using expl3 code} % % In order to ease the implemantation of some new features in @@ -242,9 +312,6 @@ % if that \pkg{expl3} command is needed in places that are others % coded in \LaTeXe{} conventions. % -% \begin{macrocode} -\ExplSyntaxOn -% \end{macrocode} % % In this file, each release of LaTeX adds an \cs{IncludeInRelease} % block, in which the macros copied for that release were defined. @@ -259,8 +326,16 @@ % redefinitions. % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{expl3~2020-10-01}% -% {expl3~macros~added~for~the~2020-10-01~release}% +%\IncludeInRelease{2020/10/01}{\@expl@cs@to@str@@N}% +% {expl3 macros added for the 2020-10-01 release}% +% \end{macrocode} +% +% The expl3 activation needs to be inside the release guards as +% otherwise rolling forward is broken in old kernels that do not +% have expl3 loaded. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +\ExplSyntaxOn % \end{macrocode} % % \changes{v1.2e}{2020/08/19} @@ -290,21 +365,27 @@ % \end{macrocode} % % \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% +% Here we can't assume that expl3 is available. It will be if we +% roll back but if this code is executed rolling forward it needs +% to be pure 2e. +% \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} %\EndIncludeInRelease -%\IncludeInRelease{0000/00/00}{expl3~2020-10-01}% -% {expl3~macros~added~for~the~2020-10-01~release}% -%\cs_undefine:N \@expl@cs@to@str@@N -%\cs_undefine:N \@expl@str@if@eq@@nnTF -%\cs_undefine:N \@expl@cs@prefix@spec@@N -%\cs_undefine:N \@expl@cs@argument@spec@@N -%\cs_undefine:N \@expl@cs@replacement@spec@@N -%\cs_undefine:N \@expl@str@map@function@@NN +%\IncludeInRelease{0000/00/00}{\@expl@cs@to@str@@N}% +% {expl3 macros added for the 2020-10-01 release}% +%\let \@expl@cs@to@str@@N \@undefined +%\let \@expl@str@if@eq@@nnTF \@undefined +%\let \@expl@cs@prefix@spec@@N \@undefined +%\let \@expl@cs@argument@spec@@N \@undefined +%\let \@expl@cs@replacement@spec@@N \@undefined +%\let \@expl@str@map@function@@NN \@undefined %\EndIncludeInRelease % % \end{macrocode} % -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} % % \Finale diff --git a/macros/latex/base/ltfilehook-code.pdf b/macros/latex/base/ltfilehook-code.pdf index e35be13efe..fcbf09fe98 100644 Binary files a/macros/latex/base/ltfilehook-code.pdf and b/macros/latex/base/ltfilehook-code.pdf differ diff --git a/macros/latex/base/ltfilehook-doc.pdf b/macros/latex/base/ltfilehook-doc.pdf index 7bd9392a4d..bf7f37f22b 100644 Binary files a/macros/latex/base/ltfilehook-doc.pdf and b/macros/latex/base/ltfilehook-doc.pdf differ diff --git a/macros/latex/base/ltfilehook.dtx b/macros/latex/base/ltfilehook.dtx index ecb499f347..c7ed13f041 100644 --- a/macros/latex/base/ltfilehook.dtx +++ b/macros/latex/base/ltfilehook.dtx @@ -31,8 +31,8 @@ %%% From File: ltfilehook.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v1.0c} -\providecommand\ltfilehookdate{2020/10/18} +\providecommand\ltfilehookversion{v1.0d} +\providecommand\ltfilehookdate{2020/11/24} % \end{macrocode} % %<*driver> @@ -615,6 +615,62 @@ % \begin{macrocode} % %\EndIncludeInRelease +% \end{macrocode} +% +% When rolling forward the following expl3 functions may not be defined. +% If we roll back the code does nothing. +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}% +% {\file_parse_full_name_apply:nN}{Roll forward help}% +% +%\ExplSyntaxOn +%\cs_if_exist:NF\file_parse_full_name_apply:nN +%{ +%\cs_new:Npn \file_parse_full_name_apply:nN #1 +% { +% \exp_args:Ne \__file_parse_full_name_auxi:nN +% { \__kernel_file_name_sanitize:n {#1} } +% } +%\cs_new:Npn \__file_parse_full_name_auxi:nN #1 +% { +% \__file_parse_full_name_area:nw { } #1 +% / \s__file_stop +% } +%\cs_new:Npn \__file_parse_full_name_area:nw #1 #2 / #3 \s__file_stop +% { +% \tl_if_empty:nTF {#3} +% { \__file_parse_full_name_base:nw { } #2 . \s__file_stop {#1} } +% { \__file_parse_full_name_area:nw { #1 / #2 } #3 \s__file_stop } +% } +%\cs_new:Npn \__file_parse_full_name_base:nw #1 #2 . #3 \s__file_stop +% { +% \tl_if_empty:nTF {#3} +% { +% \tl_if_empty:nTF {#1} +% { +% \tl_if_empty:nTF {#2} +% { \__file_parse_full_name_tidy:nnnN { } { } } +% { \__file_parse_full_name_tidy:nnnN { .#2 } { } } +% } +% { \__file_parse_full_name_tidy:nnnN {#1} { .#2 } } +% } +% { \__file_parse_full_name_base:nw { #1 . #2 } #3 \s__file_stop } +% } +%\cs_new:Npn \__file_parse_full_name_tidy:nnnN #1 #2 #3 #4 +% { +% \exp_args:Nee #4 +% { +% \str_if_eq:nnF {#3} { / } { \use_none:n } +% #3 \prg_do_nothing: +% } +% { \use_none:n #1 \prg_do_nothing: } +% {#2} +% } +%} +%\ExplSyntaxOff +% +%\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % @@ -643,6 +699,8 @@ % kernel we do this only now and not in \texttt{ltfiles}. % % \begin{macro}{\InputIfFileExists} +% \begin{macro}{\@input@file@exists@with@hooks} +% \begin{macro}{\unqu@tefilef@und} % \cs{InputIfFileExists} loads any file if it is available so we % have to add the hooks \texttt{file/before} and % \texttt{file/after} in the right places. If the file doesn't @@ -665,7 +723,7 @@ % 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 +% preserve the name and then restore it for the % \texttt{file/after/...} hook. % % The hook always refers to the file requested by the user. The hook @@ -683,33 +741,68 @@ % refer to the file by their name only. The path to the file is % returned in \cs{CurrentFilePath}. % \begin{macrocode} - \edef\reserved@a{\@filef@und + \edef\reserved@a{% \@expl@@@filehook@file@pop@assign@@nnnn {\CurrentFilePathUsed}% {\CurrentFileUsed}% {\CurrentFilePath}% - {\CurrentFile}}% + {\CurrentFile}% +% \end{macrocode} +% +% We pre-expand \cs{@filef@und} so that in case another file is +% loaded in the true branch of \cs{InputIfFileExists}, these don't +% change their value meanwhile. This isn't a worry with +% \cs[no-index]{CurrentFile...} because they are kept in a stack. +% +% \changes{v1.0d}{2020/11/20} +% {Move loading to \cs{@input@file@exists@with@hooks} and expand +% \cs{@filef@und} to avoid getting the wrong file name in the case of +% a substitution.} +% \begin{macrocode} + \noexpand\@input@file@exists@with@hooks{\@filef@und}}% \expandafter\@swaptwoargs\expandafter {\reserved@a}% - {% - #2% - \@addtofilelist{#1}% - \UseHook{file/before}% + {#2}% + \@expl@@@filehook@file@pop@@ + }% +} +% \end{macrocode} +% +% Before adding to the file list we need to make all (letter) characters +% catcode~11, because several packages use constructions like +% \begin{verbatim} +% \filename@parse{} +% \ifx\filename@ext\@clsextension +% ... +% \fi +% \end{verbatim} +% and that doesn't work if \cs{filename@ext} is \cs{detokenize}d. +% Making \cs{@clsextension} a string doesn't help much because some +% packages define their own \cs[no-index]{@someextension} with +% normal catcodes. This is not entirely correct because packages loaded +% (somehow) with catcode~12 alphabetic tokens (say, as the result of +% a \cs{string} or \cs{detokenize} command, or from a \TeX{} string like +% \cs{jobname}) will have these character tokens incorrectly turned into +% letter tokens. This however is rare, so we'll go for the all-letters +% approach (grepping the packages in \TeX{} Live didn't bring up any +% obvious candidate for breaking with this catcode change). +% \begin{macrocode} +\def\@input@file@exists@with@hooks#1{% + \edef\reserved@a{\unqu@tefilef@und#1\@nil}% + \@addtofilelist{\string@makeletter\reserved@a}% + \UseHook{file/before}% % \end{macrocode} % The current file name is available in \cs{CurrentFile} so we use % that in the specific hook. % \begin{macrocode} - \UseHook{file/before/\CurrentFile}% - \@@input - }% + \UseHook{file/before/\CurrentFile}% + \@@input #1% <- trailing space comes from \@filef@und % \end{macrocode} % And it is restored here so we can use it once more. % \begin{macrocode} - \UseHook{file/after/\CurrentFile}% - \UseHook{file/after}% - \@expl@@@filehook@file@pop@@ - }% -} + \UseHook{file/after/\CurrentFile}% + \UseHook{file/after}} +\def\unqu@tefilef@und"#1" \@nil{#1} %\EndIncludeInRelease % % \end{macrocode} @@ -737,6 +830,8 @@ % {% % \expandafter\@swaptwoargs\expandafter % {\@filef@und}{#2\@addtofilelist{#1}\@@input}}} +%\let\@input@file@exists@with@hooks\@undefined +%\let\unqu@tefilef@und\@undefined %\EndIncludeInRelease % \end{macrocode} % @@ -746,10 +841,14 @@ %\long\def \InputIfFileExists#1#2{% % \IfFileExists{#1}% % {#2\@addtofilelist{#1}\@@input \@filef@und}} +%\let\@input@file@exists@with@hooks\@undefined +%\let\unqu@tefilef@und\@undefined %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} % % % @@ -772,8 +871,8 @@ % % % \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 +% \@@_subst_file_normalize:Nn,\@@_subst_empty_name_chk:NN} +% \cs{@@_subst_add: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 @@ -787,8 +886,12 @@ \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} } + \cs_gset:cpx + { + @file-subst@ + \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1} + } + { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn {#2} } \group_end: } \cs_new_protected:Npn \@@_subst_remove:n #1 @@ -796,14 +899,18 @@ \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} } + \cs_undefine:c + { + @file-subst@ + \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1} + } \group_end: } -\cs_new:Npn \@@_subst_file_normalize:n #1 +\cs_new:Npn \@@_subst_file_normalize:Nn #1 #2 { \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:w \@@_file_parse_full_name:nN {#2} #1 \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: } @@ -929,6 +1036,7 @@ \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}% + \@expl@@@filehook@clear@replacement@flag@@ \endgroup} % %\EndIncludeInRelease @@ -1079,18 +1187,25 @@ % % \begin{macro}{flag @@_file_replaced} % \begin{macro}{\@@_if_file_replaced:TF} +% \begin{macro}{\@@_clear_replacement_flag:} % 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). +% optimising). The flag raised during the file substitution algorithm +% must be explicitly cleared after the \cs{@@_if_file_replaced:TF} +% conditional is no longer needed, otherwise further uses of +% \cs{@@_if_file_replaced:TF} will wrongly return true. % \begin{macrocode} \flag_new:n { @@_file_replaced } \cs_new:Npn \@@_if_file_replaced:TF #1 #2 - { \flag_if_raised:nTF { @@_file_replaced } {#1} {#2} } + { \flag_if_raised:nTF { @@_file_replaced } {#1} {#2} } +\cs_new_protected:Npn \@@_clear_replacement_flag: + { \flag_clear:n { @@_file_replaced } } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@@_file_subst_begin:nnn} % First off, start by checking if the current file ($\meta{name} + @@ -1343,7 +1458,12 @@ \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@clear@replacement@flag@@ + \__filehook_clear_replacement_flag: +% \end{macrocode} +% % \begin{macrocode} \cs_new_eq:NN \@expl@@@filehook@drop@extension@@N \__filehook_drop_extension:N diff --git a/macros/latex/base/ltfssaxes.dtx b/macros/latex/base/ltfssaxes.dtx index d8e4286b78..a66a26cd39 100644 --- a/macros/latex/base/ltfssaxes.dtx +++ b/macros/latex/base/ltfssaxes.dtx @@ -836,7 +836,7 @@ % condensed series, etc.). We do this in all branches above because a user % might have written %\begin{verbatim} -\DeclareFontSeriesChangeRule {m}{sc}{msc}{mc} +% \DeclareFontSeriesChangeRule {m}{sc}{msc}{mc} %\end{verbatim} % instead of using \texttt{sc} and \texttt{c} as needed in the % \texttt{.fd} file. diff --git a/macros/latex/base/ltfssbas.dtx b/macros/latex/base/ltfssbas.dtx index 4a6afca3ac..30f500b6e4 100644 --- a/macros/latex/base/ltfssbas.dtx +++ b/macros/latex/base/ltfssbas.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2020/02/27 v3.2g LaTeX Kernel (NFSS Basic Macros)] + [2020/12/10 v3.2h LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -891,12 +891,31 @@ % series and shape which is not desired if we intend to use an % explicit font shape! % \changes{v3.2e}{2019/12/17}{Don't call \cs{fontseries} or \cs{fontshape}} +% \changes{v3.2h}{2020/12/10}{Drop ``m'' if the series value is a member +% of a fixed list and issue warning if doing it (gh/453)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/02/02}% +% {\usefont}{Drop m in usefont}% \DeclareRobustCommand\usefont[4]{\fontencoding{#1}% \edef\f@family{#2}% - \edef\f@series{#3}% + \set@target@series{#3}% \edef\f@shape{#4}\selectfont \ignorespaces} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\usefont}{Drop m in usefont}% +% +%\DeclareRobustCommand\usefont[4]{\fontencoding{#1}% +% \edef\f@family{#2}% +% \edef\f@series{#3}% +% \edef\f@shape{#4}\selectfont +% \ignorespaces} +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/lthooks-code.pdf b/macros/latex/base/lthooks-code.pdf index e181e4bb27..5bb5d7899f 100644 Binary files a/macros/latex/base/lthooks-code.pdf and b/macros/latex/base/lthooks-code.pdf differ diff --git a/macros/latex/base/lthooks-doc.pdf b/macros/latex/base/lthooks-doc.pdf index 5949974141..1ca6ef3a6d 100644 Binary files a/macros/latex/base/lthooks-doc.pdf and b/macros/latex/base/lthooks-doc.pdf differ diff --git a/macros/latex/base/lthooks.dtx b/macros/latex/base/lthooks.dtx index e4ff7dd2ed..cc79892ca7 100644 --- a/macros/latex/base/lthooks.dtx +++ b/macros/latex/base/lthooks.dtx @@ -31,8 +31,8 @@ %%% From File: lthooks.dtx % % \begin{macrocode} -\def\lthooksversion{v1.0e} -\def\lthooksdate{2020/10/23} +\def\lthooksversion{v1.0g} +\def\lthooksdate{2020/12/18} % \end{macrocode} % %<*driver> @@ -222,11 +222,13 @@ % \begin{syntax} % \cs{AddToHook} \Arg{hook}\oarg{label}\Arg{code} % \end{syntax} -% Adds \meta{code} to the \meta{hook} labeled by \meta{label}. If -% the optional argument \meta{label} is not provided, if \cs{AddToHook} -% is used in a package/class, then the current -% package/class name is used, otherwise \hook{top-level} is -% used~(see section~\ref{sec:default-label}). +% Adds \meta{code} to the \meta{hook} labeled by \meta{label}. +% When the optional argument \meta{label} is not provided, the +% \meta{default label} is used (see section~\ref{sec:default-label}). +% If \cs{AddToHook} is used in a package/class, the +% \meta{default label} is the package/class name, otherwise it is +% \hook{top-level} (the \hook{top-level} label is treated +% differently: see section~\ref{sec:top-level}). % % If there already exists code under the \meta{label} then the new % \meta{code} is appended to the existing one (even if this is a reversed hook). @@ -234,10 +236,10 @@ % \meta{label}, first apply \cs{RemoveFromHook}. % % The hook doesn't have to exist for code to be added to -% it. However, if it is not declared later then obviously the +% it. However, if it is not declared, then obviously the % added \meta{code} will never be executed. This % allows for hooks to work regardless of package loading order and -% enables packages to add to hook of other packages without +% enables packages to add to hooks from other packages without % worrying whether they are actually used in the current document. % See section~\ref{sec:querying}. % @@ -251,10 +253,8 @@ % \cs{RemoveFromHook} \Arg{hook}\oarg{label} % \end{syntax} % Removes any code labeled by \meta{label} from the \meta{hook}. -% If the optional -% argument \meta{label} is not provided, if \cs{AddToHook} -% is used in a package/class, then the current -% package/class name is used, otherwise \hook{top-level} is used. +% When the optional argument \meta{label} is not provided, the +% \meta{default label} is used (see section~\ref{sec:default-label}). % % If the code for that \meta{label} wasn't yet added to the % \meta{hook}, an order is set so that when some code attempts to add @@ -273,7 +273,7 @@ % \medskip % % In contrast to the \texttt{voids} relationship between two labels -% in a \cs{DeclareHookrule} this is a destructive operation as the +% 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. @@ -367,7 +367,8 @@ % token, a low-level \TeX{} error is raised (namely, the \meta{hook} is % expanded using \TeX's \cs{csname}\ldots\cs{endcsname}, as such, % Unicode characters are allowed in \meta{hook} and \meta{label} -% arguments). The arguments of \cs{UseHook} and \cs{UseOneTimeHook} are +% arguments). The arguments of \cs{UseHook}, \cs{UseOneTimeHook}, +% \cs{IfHookEmptyTF}, and \cs{IfHookExistsTF} are % processed much in the same way except that spaces are not trimmed % around the argument, for better performance. % @@ -377,10 +378,10 @@ % chunk and to prevent clashes. This should be the standard practice, % so this hook management code provides a shortcut to refer to the % current package in the name of a \meta{hook} and in a \meta{label}. -% If \meta{hook} name or \meta{label} consist just of a single dot +% If the \meta{hook} name or the \meta{label} consist just of a single dot % (|.|), or starts with a dot followed by a slash (|./|) then the dot % denotes the \meta{default label} (usually the current package or class -% name---see~\cs{DeclareDefaultHookLabel}). +% name---see~\cs{SetDefaultHookLabel}). % A \enquote{|.|} or \enquote{|./|} anywhere else in a \meta{hook} or in % \meta{label} is treated literally and is not replaced. % @@ -403,15 +404,15 @@ % \AddToHook {file/after/foo.tex}{code} % unchanged % \end{verbatim} % -% The \meta{default label} is automatically set to the name of the -% current package or class (using \cs{@currname}). If \cs{@currname} -% is not set (because the hook command is used outside of a package, or -% the current file wasn't loaded with \cs{usepackage} or -% \cs{documentclass}), then the \texttt{top-level} is used as the -% \meta{default label}. +% The \meta{default label} is automatically set equal to the name of the +% current package or class at the time the package is loaded. If the +% hook command is used outside of a package, or the current file wasn't +% loaded with \cs{usepackage} or \cs{documentclass}, then the +% \texttt{top-level} is used as the \meta{default label}. This may have +% exceptions---see \cs{PushDefaultHookLabel}. % % This syntax is available in all \meta{label} arguments and most -% \meta{hook}, both in the \LaTeXe{} interface, and the \LaTeX3 +% \meta{hook} arguments, both in the \LaTeXe{} interface, and the \LaTeX3 % interface described in section~\ref{sec:l3hook-interface}. % % Note, however, that the replacement of |.| by the \meta{default label} @@ -430,29 +431,104 @@ % In some cases, for example in large packages, one may want to separate % it in logical parts, but still use the main package name as % \meta{label}, then the \meta{default label} can be set using -% \cs{DeclareDefaultHookLabel}: +% \cs{SetDefaultHookLabel} or +% \cs{PushDefaultHookLabel}..\cs{PopDefaultHookLabel}. % -% \begin{function}{\DeclareDefaultHookLabel} +% \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel} % \begin{syntax} -% \cs{DeclareDefaultHookLabel} \Arg{default label} +% \cs{PushDefaultHookLabel} \Arg{default label} +% \quad \meta{code} +% \cs{PopDefaultHookLabel} % \end{syntax} -% Sets the \meta{default label} to be used in \meta{label} arguments. -% If \cs{DeclareDefaultHookLabel} is not used in the -% current package, \cs{@currname} is used instead. If \cs{@currname} -% is not set, the code is assumed to be in the main document, in which -% case \texttt{top-level} is used. -% -% The effect of \cs{DeclareDefaultHookLabel} holds for the current -% file, and is reset to the previous value when the file is closed. +% \cs{PushDefaultHookLabel} sets the current \meta{default label} to +% be used in \meta{label} arguments, or when replacing a leading +% ``|.|'' (see above). \cs{PopDefaultHookLabel} reverts the +% \meta{default label} to its previous value. +% +% Inside a package or class, the \meta{default label} is equal to the +% package or class name, unless explicitly changed. Everywhere else, +% the \meta{default label} is |top-level| (see +% section~\ref{sec:top-level}) unless explicitly changed. +% +% The effect of \cs{PushDefaultHookLabel} holds until the next +% \cs{PopDefaultHookLabel}. \cs{usepackage} (and \cs{RequirePackage} +% and \cs{documentclass}) internally use +% \begin{quote} +% \cs{PushDefaultHookLabel}\Arg{package name} \\ +% \null \quad \meta{package code} \\ +% \cs{PopDefaultHookLabel} +% \end{quote} +% to set the \meta{default label} for the package or class file. +% Inside the \meta{package code} the \meta{default label} can also be +% changed with \cs{SetDefaultHookLabel}. \cs{input} and other +% file input-related commands from the \LaTeX{} kernel do not use +% \cs{PushDefaultHookLabel}, so code within files loaded by these +% commands does \emph{not} get a dedicated \meta{label}! (that is, the +% \meta{default label} is the current active one when the file was +% loaded.) +% +% Packages that provide their own package-like interfaces +% (Ti\textit{k}Z's \cs{usetikzlibrary}, for example) can use +% \cs{PushDefaultHookLabel} and \cs{PopDefaultHookLabel} to set +% dedicated labels and emulate \cs{usepackage}-like hook behaviour +% within those contexts. +% +% The |top-level| label is treated differently, and is reserved to the +% user document, so it is not allowed to change the +% \meta{default label} to |top-level|. +% \end{function} +% +% \begin{function}{\SetDefaultHookLabel} +% \begin{syntax} +% \cs{SetDefaultHookLabel} \Arg{default label} +% \end{syntax} +% Similarly to \cs{PushDefaultHookLabel}, +% sets the current \meta{default label} to +% be used in \meta{label} arguments, or when replacing a leading +% ``|.|''. The effect holds until the label is changed again or until +% the next \cs{PopDefaultHookLabel}. The difference between +% \cs{PushDefaultHookLabel} and \cs{SetDefaultHookLabel} is that the +% latter does not save the current \meta{default label}. +% +% This command is useful when a large package is composed of several +% smaller packages, but all should have the same \meta{label}, so +% \cs{SetDefaultHookLabel} can be used at the beginning of each +% package file to set the correct label. +% +% \cs{SetDefaultHookLabel} is not allowed in the main document, where +% the \meta{default label} is |top-level| and there is no +% \cs{PopDefaultHookLabel} to end its effect. +% It is also not allowed to change the \meta{default label} to +% |top-level|. % \end{function} % +% \subsubsection{The \texttt{top-level} label} +% \label{sec:top-level} +% +% The |top-level| label, assigned to code added from the main document, +% is different from other labels. Code added to hooks (usually +% \cs{AtBeginDocument}) in the preamble is almost always to change +% something defined by a package, so it should go at the very end of the +% hook. +% +% Therefore, code added in the |top-level| is always executed at the end +% of the hook, regardless of where it was declared. If the hook is +% reversed (see \cs{NewReversedHook}), the |top-level| chunk is executed +% at the very beginning instead. +% +% Rules regarding |top-level| have no effect: if a user wants to have a +% specific set of rules for a code chunk, they should use a different +% label to said code chunk, and provide a rule for that label instead. +% +% The |top-level| label is exclusive for the user, so trying to add code +% with that label from a package results in an error. % % \subsubsection{Defining relations between hook code} % % The default assumption is that code added to hooks by different -% packages is independent and the order in which it is executed is -% irrelevant. While this is true in many case it is obviously false -% in many others. +% packages are independent and the order in which they are executed is +% irrelevant. While this is true in many cases it is obviously false +% in others. % % Before the hook management system was introduced % packages had to take elaborate precaution to determine of some other @@ -589,7 +665,8 @@ % its permanent code pool, or to its ``next'' token list. The hook % doesn't need to be declared to have code added to its code pool. % A hook is said to exist when it was declared with \cs{NewHook} or -% some variant thereof. +% some variant thereof. Generic \hook{file} and \hook{env} hooks are +% automatically declared when code is added to them. % % \begin{function}[EXP]{\IfHookEmptyTF} % \begin{syntax} @@ -650,6 +727,7 @@ % \item % any code executed on the next invocation only. % \end{itemize} +% \end{function} % % \cs{LogHook} prints the information to the |.log| file, and % \cs{ShowHook} prints them to the terminal/command window and starts @@ -660,6 +738,7 @@ % %^^A % Code for the listing below: %^^A \NewHook{example-hook} +%^^A \AddToHook{example-hook}{[code from 'top-level']} %^^A \AddToHook{example-hook}[foo]{[code from package 'foo']} %^^A \AddToHook{example-hook}[bar]{[from package 'bar']} %^^A \AddToHook{example-hook}[baz]{[package 'baz' is here]} @@ -680,13 +759,15 @@ % > foo -> [code from package 'foo'] % > bar -> [from package 'bar'] % > baz -> [package 'baz' is here] +% > Document-level (top-level) code (executed last): +% > -> [code from 'top-level'] % > Extra code for next invocation: % > -> [one-time code] % > Rules: % > foo|baz with relation > % > baz|bar with default relation < % > Execution order (after applying rules): -% > bar, baz, foo. +% > baz, foo, bar. % \end{verbatim} % % In the listing above, lines~3 to~5 show the three code chunks added @@ -695,7 +776,18 @@ % \quad \meta{label}\verb| -> |\meta{code} % \end{quote} % -% Line~7 shows the code chunk for the next execution of the hook in +% Line~7 shows the code chunk added by the user in the main document +% (labeled |top-level|) in the format +% \begin{quote} +% \quad\verb|Document-level (top-level) code (executed |%^^A +% \meta{first\texttt{\string|}last}\verb|):|\\ +% \quad\verb| -> |\meta{\texttt{top-level} code} +% \end{quote} +% This code will be either the first or last code executed by the hook +% (|last| if the hook is normal, |first| if it is reversed). This +% chunk is not affected by rules and does not take part in sorting. +% +% Line~9 shows the code chunk for the next execution of the hook in % the format % \begin{quote} % \quad \verb|-> |\meta{next-code} @@ -705,7 +797,7 @@ % earlier, which can only be removed from that hook by doing % \verb|\RemoveFromHook{|\meta{label}|}[example-hook]|. % -% Lines~9 and~10 show the rules declared that affect this hook in the +% Lines~11 and~12 show the rules declared that affect this hook in the % format % \begin{quote} % \quad \meta{label-1}\verb+|+\meta{label-2}| with |%^^A @@ -717,9 +809,8 @@ % to \meta{label-1} and \meta{label-2} in \emph{all} hooks, (unless % overrided by a non-default relation). % -% Finally, line~12 lists the labels in the hook after sorting; +% Finally, line~14 lists the labels in the hook after sorting; % that is, in the order they will be executed when the hook is used. -% \end{function} % % % \subsubsection{Debugging hook code} @@ -749,8 +840,9 @@ % \begin{function} % {\hook_new:n,\hook_new_reversed:n,\hook_new_pair:nn} % \begin{syntax} -% \cs{hook_new:n}\Arg{hook} -% \cs{hook_new_pair:nn}\Arg{hook-1}\Arg{hook-2} +% \cs{hook_new:n} \Arg{hook} +% \cs{hook_new_reversed:n} \Arg{hook} +% \cs{hook_new_pair:nn} \Arg{hook-1} \Arg{hook-2} % \end{syntax} % Creates a new \meta{hook} with normal or reverse ordering of code % chunks. \cs{hook_new_pair:nn} creates a pair of such hooks with @@ -782,7 +874,6 @@ % Changes the \Arg{hook} status so that from now on any addition to % the hook code is executed immediately. Then execute any % \Arg{hook} code already set up. -% \fmi{better L3 name?} % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. @@ -954,17 +1045,19 @@ % \texttt{packageB}, \texttt{packageC} which you can verify with % \cs{ShowHook}\texttt{\{myhook\}}: %\begin{verbatim} -% The hook 'myhook': -% Code chunks: -% packageA -> \typeout {A} -% packageB -> \typeout {B} -% packageC -> \typeout {C} -% Extra code next invocation: -% --- -% Rules: -% --- -% Execution order: -% packageA, packageB, packageC +% -> The hook 'myhook': +% > Code chunks: +% > packageA -> \typeout {A} +% > packageB -> \typeout {B} +% > packageC -> \typeout {C} +% > Document-level (top-level) code (executed last): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > --- +% > Execution order: +% > packageA, packageB, packageC. %\end{verbatim} % The reason is that the code chunks are internally saved in a property list % and the initial order of such a property list is the order in @@ -988,17 +1081,19 @@ %\end{verbatim} % instead of the previous lines we get %\begin{verbatim} -% The hook 'myhook': -% Code chunks: -% packageA -> \typeout {A} -% packageB -> \typeout {B} -% packageC -> \typeout {C} -% Extra code next invocation: -% --- -% Rules: -% packageA|packageB with relation before -% Execution order (after applying rules): -% packageA, packageC, packageB +% -> The hook 'myhook': +% > Code chunks: +% > packageA -> \typeout {A} +% > packageB -> \typeout {B} +% > packageC -> \typeout {C} +% > Document-level (top-level) code (executed last): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > packageB|packageA with relation > +% > Execution order (after applying rules): +% > packageA, packageC, packageB. %\end{verbatim} % As you can see the code chunks are still in the same order, but % in the execution order for the labels \texttt{packageB} and @@ -1010,7 +1105,7 @@ % doesn't run at all as there is nothing to resolve). % Incidentally, if we had instead specified the redundant rule %\begin{verbatim} -% \DeclareHookRule{myhook}{packageB}{before}{label-3} +% \DeclareHookRule{myhook}{packageB}{before}{packageC} %\end{verbatim} % the execution order would not have changed. % @@ -1039,17 +1134,17 @@ % \AddToHook{env/quote/after} [package-1]{\end{itshape}} %\end{verbatim} % As a result, all quotes will be in italics. -% Now suppose further that the user wants the quotes also in blue -% and therefore adds: +% Now suppose further that another |package-too| makes the quotes +% also in blue and therefore adds: %\begin{verbatim} % \usepackage{color} -% \AddToHook{env/quote/before}{\begin{color}{blue}} -% \AddToHook{env/quote/after} {\end{color}} +% \AddToHook{env/quote/before}[package-too]{\begin{color}{blue}} +% \AddToHook{env/quote/after} [package-too]{\end{color}} %\end{verbatim} % Now if the \hook{env/quote/after} hook would be a normal hook we % would get the same execution order in both hooks, namely: %\begin{verbatim} -% package-1, top-level +% package-1, package-too %\end{verbatim} % (or vice versa) and as a result, would get: %\begin{verbatim} @@ -1063,16 +1158,18 @@ % the correct sequence and \cs{ShowHook} would give us the % following output: %\begin{verbatim} -% The hook 'env/quote/after': -% Code chunks: -% package-1 -> \end {itshape} -% top-level -> \end {color} -% Extra code next invocation: -% --- -% Rules: -% --- -% Execution order (after reversal): -% top-level, package-1 +% -> The hook 'env/quote/after': +% > Code chunks: +% > package-1 -> \end {itshape} +% > package-too -> \end {color} +% > Document-level (top-level) code (executed first): +% > --- +% > Extra code for next invocation: +% > --- +% > Rules: +% > --- +% > Execution order (after reversal): +% > package-too, package-1. %\end{verbatim} % % The reversal of the execution order happens before applying any @@ -1206,13 +1303,15 @@ % \hook{begindocument} % (which is executed inside \verb=\begin{document}=). % However, all code added this way is labeled with the label -% \hook{top-level} if done outside of a package or class or with the -% package/class name if called inside such a file. +% \hook{top-level} (see section~\ref{sec:top-level}) +% if done outside of a package or class or with the +% package/class name if called inside such a file +% (see section~\ref{sec:default-label}). % % This way one can add further code to the hook using % \cs{AddToHook} or \cs{AtBeginDocument} using a different label % and explicitly order the code chunks as necessary, e.g., run some -% code before or after the \hook{top-level} code. When using the +% code before or after another package's code. When using the % optional argument the call is equivalent to running % \cs{AddToHook} \texttt{\{begindocument\}} \oarg{label} % \Arg{code}. @@ -1251,7 +1350,7 @@ % 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 +% \cs{AtBeginDocument}. 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 @@ -1333,8 +1432,8 @@ % \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. +% using the \meta{label}. If \meta{label} is not given, the +% \meta{default label} is used (see section~\ref{sec:default-label}). % \end{function} % % \begin{function}{\AtBeginEnvironment} @@ -1774,6 +1873,37 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_tl_set:Nn,\@@_tl_set:cn,\@@_tl_set:cx} +% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:cn,\@@_tl_gset:co,\@@_tl_gset:cx} +% \begin{macro}{\@@_tl_gput_right:Nn,\@@_tl_gput_right:No,\@@_tl_gput_right:cn} +% \begin{macro}{\@@_tl_gput_left:Nn,\@@_tl_gput_left:No} +% \begin{macro}{\@@_tl_gclear:N,\@@_tl_gclear:c} +% \begin{macro}{\@@_tl_gset_eq:NN} +% Private copies of a few \pkg{expl3} functions. \pkg{l3debug} will +% only add debugging to the public names, not to these copies, so we +% don't have to use \cs{debug_suspend:} and \cs{debug_resume:} +% everywhere. +% \begin{macrocode} +\cs_new_eq:NN \@@_tl_set:Nn \tl_set:Nn +\cs_generate_variant:Nn \@@_tl_set:Nn { cn, cx } +\cs_new_eq:NN \@@_tl_gset:Nn \tl_gset:Nn +\cs_generate_variant:Nn \@@_tl_gset:Nn { cn, co, cx } +\cs_new_eq:NN \@@_tl_gput_right:Nn \tl_gput_right:Nn +\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No, cn } +\cs_new_eq:NN \@@_tl_gput_left:Nn \tl_gput_left:Nn +\cs_generate_variant:Nn \@@_tl_gput_left:Nn { No } +\cs_new_protected:Npn \@@_tl_gclear:N #1 + { \@@_tl_gset_eq:NN #1 \c_empty_tl } +\cs_generate_variant:Nn \@@_tl_gclear:N { c } +\cs_new_eq:NN \@@_tl_gset_eq:NN \tl_gset_eq:NN +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % % \subsection{Providing new hooks} % @@ -1808,6 +1938,13 @@ % $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed % ones. % +% \item[\cs{@@_toplevel~\meta{name}}] This token list stores the code +% inserted in the hook from the user's document, in the |top-level| +% label. This label is special, and doesn't participate in sorting. +% Instead, all code is appended to it and executed after (or before, +% if the hook is reversed) the normal +% hook code, but before the |next| code chunk. +% % \item[\cs{@@_next~\meta{name}}] 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 @@ -1890,15 +2027,16 @@ % \begin{macro}{\@@_declare:n} % This function declares the basic data structures for a hook without % actually declaring the hook itself. This is needed to allow adding -% to undeclared hooks. Here it is unnecessary to check whether both -% variables exist, since both are declared at the same time (either -% both exist, or neither). +% to undeclared hooks. Here it is unnecessary to check whether all +% variables exist, since all three are declared at the same time +% (either all of them exist, or none). % \begin{macrocode} \cs_new_protected:Npn \@@_declare:n #1 { \@@_if_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } + \tl_new:c { @@_toplevel~#1 } \tl_new:c { @@_next~#1 } } } @@ -1951,13 +2089,6 @@ \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 -% using non L3 names such as \cs{@enddocumenthook} with \pkg{expl3} -% functions will trigger warnings so we run this code with -% 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} @@ -1975,10 +2106,9 @@ % 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_gclear:c { @#1hook } + \@@_tl_gclear:c { @#1hook } } } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -1990,79 +2120,76 @@ % \begin{macro}[EXP]{\@@_parse_label_default:n} % This macro checks if a label was given (not \cs{c_novalue_tl}), and % if so, tries to parse the label looking for a leading \verb|.| to -% replace for \cs{@currname}. Otherwise \cs{@@_currname_or_default:n} -% is used to pick \cs{@currname} or the fallback value. -% -% The default |top-level| is hard-coded here. It once was an -% argument, but it's no longer needed. \pho{can't remember why} +% replace by \cs{@@_currname_or_default:}. % \begin{macrocode} \cs_new:Npn \@@_parse_label_default:n #1 { \tl_if_novalue:nTF {#1} - { \@@_currname_or_default:n { top-level } } - { - \tl_trim_spaces_apply:nN {#1} - \@@_parse_dot_label:nn { top-level } - } + { \@@_currname_or_default: } + { \tl_trim_spaces_apply:nN {#1} \@@_parse_dot_label:n } } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_parse_dot_label:nn} +% \begin{macro}[EXP]{\@@_parse_dot_label:n} % \begin{macro}[EXP]{ -% \@@_parse_dot_label:nw, +% \@@_parse_dot_label:w, % \@@_parse_dot_label_cleanup:w, -% \@@_parse_dot_label_aux:nw +% \@@_parse_dot_label_aux:w % } % Start by checking if the label is empty, which raises an error, and % uses the fallback value. If not, % split the label at a \verb|./|, if any, and check if no tokens are % before the \verb|./|, or if the only character is a \verb|.|. % If these requirements are fulfilled, the leading -% \verb|.| is replaced with \cs{@@_currname_or_default:n}. Otherwise +% \verb|.| is replaced with \cs{@@_currname_or_default:}. Otherwise % the label is returned unchanged. % \begin{macrocode} -\cs_new:Npn \@@_parse_dot_label:nn #1 #2 +\cs_new:Npn \@@_parse_dot_label:n #1 { \tl_if_empty:nTF {#1} { - \msg_expandable_error:nnn { hooks } { empty-label } {#2} - #2 + \msg_expandable_error:nn { hooks } { empty-label } + \@@_currname_or_default: } { \str_if_eq:nnTF {#1} { . } - { \@@_currname_or_default:n {#2} } - { \@@_parse_dot_label:nw {#2} #1 ./ \s_@@_mark } + { \@@_currname_or_default: } + { \@@_parse_dot_label:w #1 ./ \s_@@_mark } } } -\cs_new:Npn \@@_parse_dot_label:nw #1 #2 ./ #3 \s_@@_mark +\cs_new:Npn \@@_parse_dot_label:w #1 ./ #2 \s_@@_mark { - \tl_if_empty:nTF {#2} - { \@@_parse_dot_label_aux:nw {#1} #3 \s_@@_mark } + \tl_if_empty:nTF {#1} + { \@@_parse_dot_label_aux:w #2 \s_@@_mark } { - \tl_if_empty:nTF {#3} - { \@@_make_name:n {#2} } - { \@@_parse_dot_label_cleanup:w #2 ./ #3 \s_@@_mark } + \tl_if_empty:nTF {#2} + { \@@_make_name:n {#1} } + { \@@_parse_dot_label_cleanup:w #1 ./ #2 \s_@@_mark } } } \cs_new:Npn \@@_parse_dot_label_cleanup:w #1 ./ \s_@@_mark {#1} -\cs_new:Npn \@@_parse_dot_label_aux:nw #1 #2 ./ \s_@@_mark - { \@@_currname_or_default:n {#1} / \@@_make_name:n {#2} } +\cs_new:Npn \@@_parse_dot_label_aux:w #1 ./ \s_@@_mark + { \@@_currname_or_default: / \@@_make_name:n {#1} } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_currname_or_default:n} +% \begin{macro}[EXP]{\@@_currname_or_default:} % Uses \cs{g_@@_hook_curr_name_tl} if it is set, otherwise tries -% \cs{@currname}. If neither is set, uses the fallback value -% \verb|#1| (usually \texttt{top-level}). +% \cs{@currname}. If neither is set, raises an error and uses the +% fallback value \verb|label-missing|. % \begin{macrocode} -\cs_new:Npn \@@_currname_or_default:n #1 +\cs_new:Npn \@@_currname_or_default: { \tl_if_empty:NTF \g_@@_hook_curr_name_tl { \tl_if_empty:NTF \@currname - { \@@_make_name:n {#1} } + { + \msg_expandable_error:nnn { hooks } { should-not-happen } + { Empty~default~label. } + \@@_make_name:n { label-missing } + } { \@currname } } { \g_@@_hook_curr_name_tl } @@ -2213,14 +2340,33 @@ % \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=. +% otherwise just put \verb=#3=. If the current label is |top-level|, +% the code is added to a dedicated token list +% \cs[no-index]{@@_toplevel~\meta{hook}} that goes at the end of the +% hook (or at the beginning, for a reversed hook), just before +% \cs[no-index]{@@_next~\meta{hook}}. +% \begin{macrocode} + \str_if_eq:nnTF {#2} { top-level } + { + \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } + { +% \end{macrocode} +% If the hook's basic structure does not exist, we need to declare it +% with \cs{@@_declare:n}. % \begin{macrocode} - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + \@@_declare:n {#1} + \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} + } + { \msg_error:nnn { hooks } { misused-top-level } {#1} } + } { - \prop_gput:cno { g_@@_#1_code_prop } {#2} - { \l_@@_return_tl #3 } + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { + \prop_gput:cno { g_@@_#1_code_prop } {#2} + { \l_@@_return_tl #3 } + } + { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } } - { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } } % \end{macrocode} % \end{macro} @@ -2434,24 +2580,48 @@ % hook before its defined (see section~\ref{sec:querying}). % \begin{macrocode} \@@_if_exist:nTF {#1} + { % \end{macrocode} % Then remove the chunk and run \cs{@@_update_hook_code:n} so % that the execution token list reflects the change if we are after % \verb=\begin{document}=. +% +% If all code is to be removed, clear the code pool +% \cs[no-index]{g_@@_\meta{hook}_code_prop}, the top-level code +% \cs[no-index]{@@_toplevel~\meta{hook}}, and the next-execution code +% \cs[no-index]{@@_next~\meta{hook}}. % \begin{macrocode} - { \str_if_eq:nnTF {#2} {*} - { \prop_gclear:c { g_@@_#1_code_prop } } { + \prop_gclear:c { g_@@_#1_code_prop } + \@@_tl_gclear:c { @@_toplevel~#1 } + \@@_tl_gclear:c { @@_next~#1 } + } + { +% \end{macrocode} +% If the label is |top-level| then clear the token list, as all code +% there is under the same label. Marked removal is not implemented +% for |top-level| because it is hard to reliably know that no code +% was added to \cs[no-index]{@@_toplevel~\meta{hook}} (granted that +% an empty code could be interpreted as that, but then it differs in +% behaviour from other labels, in which an empty chunk is still valid +% for removal). Besides, it doesn't make much (if any) sense for +% packages to remove |top-level| code. So here the chunk is just +% cleared unconditionally. +% \begin{macrocode} + \str_if_eq:nnTF {#2} { top-level } + { \@@_tl_gclear:c { @@_toplevel~#1 } } + { % \end{macrocode} -% Check if the label being removed exists in the code pool. If it does, -% just call \cs{@@_gremove_code_do:nn} to do the removal, otherwise mark it -% to be removed. +% Otherwise check if the label being removed exists in the code pool. +% If it does, just call \cs{@@_gremove_code_do:nn} to do the removal, +% otherwise mark it to be removed. % \begin{macrocode} - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl - { \@@_gremove_code_do:nn } - { \@@_mark_removal:nn } - {#1} {#2} + \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + { \@@_gremove_code_do:nn } + { \@@_mark_removal:nn } + {#1} {#2} + } } % \end{macrocode} % Finally update the code, if the hook exists. @@ -2470,6 +2640,7 @@ % \end{macrocode} % % \begin{macro}{\@@_gremove_code_do:nn} +% Remove code for a given label. % \begin{macrocode} \cs_new_protected:Npn \@@_gremove_code_do:nn #1 #2 { \prop_gremove:cn { g_@@_#1_code_prop } {#2} } @@ -2605,7 +2776,6 @@ % Then we call the function to handle the given rule. Throw an error if the % rule is invalid. % \begin{macrocode} - \debug_suspend: \cs_if_exist_use:cTF { @@_rule_#3_gset:nnn } { {#1} {#2} {#4} @@ -2613,7 +2783,6 @@ } { \msg_error:nnnnnn { hooks } { unknown-rule } {#1} {#2} {#3} {#4} } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -2639,7 +2808,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_before_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { < } { > } } } \cs_new_eq:cN { @@_rule_<_gset:nnn } \@@_rule_before_gset:nnn @@ -2648,7 +2817,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_after_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } { \@@_label_ordered:nnTF {#3} {#2} { < } { > } } } \cs_new_eq:cN { @@_rule_>_gset:nnn } \@@_rule_after_gset:nnn @@ -2661,7 +2830,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_voids_gset:nnn #1#2#3 { - \tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { -> } { <- } } } % \end{macrocode} @@ -2675,9 +2844,9 @@ % together in hook |#1|. % \begin{macrocode} \cs_new_protected:cpn { @@_rule_incompatible-error_gset:nnn } #1#2#3 - { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } \cs_new_protected:cpn { @@_rule_incompatible-warning_gset:nnn } #1#2#3 - { \tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } % \end{macrocode} % \end{macro} % @@ -2722,7 +2891,7 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_if_label_case:nnnnn} -% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNNn} +% To avoid doing the string comparison twice in \cs{@@_initialize_single:NNn} % (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 @@ -2800,7 +2969,6 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_initialize_hook_code:n #1 { - \debug_suspend: \@@_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~ '#1' \on@line :^^J} } % \end{macrocode} @@ -2815,17 +2983,22 @@ % 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{@@~\meta{hook}} to hold the next -% code. If there are code chunks we call -% \cs{@@_initialize_single:NNNn} and pass to it ready made csnames +% case just update \cs{@@~\meta{hook}} to hold the |top-level| and +% |next| code chunks. If there are code chunks we call +% \cs{@@_initialize_single:NNn} 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} \hook_if_exist:nT {#1} { \prop_if_empty:cTF {g_@@_#1_code_prop} - { \tl_gset:co { @@~#1 } - { \cs:w @@_next~#1 \cs_end: } } + { + \@@_tl_gset:co { @@~#1 } + { + \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: + \cs:w @@_next~#1 \cs_end: + } + } { % \end{macrocode} % By default the algorithm sorts the code chunks and then saves the @@ -2836,9 +3009,9 @@ % in preparation is to change two definitions used later on. % \begin{macrocode} \@@_if_reversed:nTF {#1} - { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_left:NV + { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_left:Nn \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV } - { \cs_set_eq:NN \@@_tl_gput:NV \tl_gput_right:NV + { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_right:Nn \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } % \end{macrocode} % @@ -2848,9 +3021,8 @@ % save the old code property list so that it can be restored later. % \begin{macrocode} \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } - \@@_initialize_single:cccn - { @@~#1 } { @@_next~#1 } - { g_@@_#1_labels_clist } {#1} + \@@_initialize_single:ccn + { @@~#1 } { 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 @@ -2862,7 +3034,6 @@ \g_@@_used_prop {#1}{} } } } - \debug_resume: } % \end{macrocode} % \end{macro} @@ -2918,12 +3089,13 @@ % \end{macro} % % -% \begin{macro}{\@@_initialize_single:NNNn,\@@_initialize_single:cccn} +% \begin{macro}{\@@_initialize_single:NNn,\@@_initialize_single:ccn} % -% \cs{@@_initialize_single:NNNn} implements the sorting of the code +% \cs{@@_initialize_single:NNn} 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}, +% execution (\verb=#4=). The arguments are \meta{hook-code-plist}, +% \meta{hook-code-tl}, \meta{hook-top-level-code-tl}, +% \meta{hook-next-code-tl}, % \meta{hook-ordered-labels-clist} and \meta{hook-name} (the latter % is only used for debugging---the \meta{hook-rule-plist} is accessed % using the \meta{hook-name}). @@ -2935,8 +3107,12 @@ % far as possible. The result is a restriction I do not test for at % the moment: a label can't be equal to the number 0! \fmi{Needs % checking for, just in case} +% +% ^^A #1 <- \@@~#1 +% ^^A #2 <- \g_@@_#1_labels_clist +% ^^A #3 <- #1 % \begin{macrocode} -\cs_new_protected:Npn \@@_initialize_single:NNNn #1#2#3#4 +\cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 { % \end{macrocode} % Step T1: Initialize the data structure \ldots @@ -2947,7 +3123,7 @@ % % Store the name of the hook: % \begin{macrocode} - \tl_set:Nn \l_@@_cur_hook_tl {#4} + \tl_set:Nn \l_@@_cur_hook_tl {#3} % \end{macrocode} % % We loop over the property list holding the code and record all @@ -2961,7 +3137,7 @@ { \int_incr:N \l_@@_labels_int \seq_put_right:Nn \l_@@_labels_seq {##1} - \tl_set:cn { \@@_tl_csname:n {##1} }{0} + \@@_tl_set:cn { \@@_tl_csname:n {##1} } { 0 } \seq_clear_new:c { \@@_seq_csname:n {##1} } } % \end{macrocode} @@ -2987,7 +3163,7 @@ { \prop_map_break: } { \@@_apply_label_pair:nnn {##1} {####1} } { \@@_apply_label_pair:nnn {####1} {##1} } - {#4} + {#3} } } % \end{macrocode} @@ -3014,8 +3190,8 @@ % \end{macrocode} % % \begin{macrocode} - \tl_gclear:N #1 - \clist_gclear:N #3 + \@@_tl_gclear:N #1 + \clist_gclear:N #2 % \end{macrocode} % % The whole loop combines steps T5--T7: @@ -3027,11 +3203,11 @@ % \begin{macrocode} \int_decr:N \l_@@_labels_int \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl - \@@_tl_gput:NV #1 \l_@@_return_tl + \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl % \end{macrocode} % % \begin{macrocode} - \@@_clist_gput:NV #3 \l_@@_front_tl + \@@_clist_gput:NV #2 \l_@@_front_tl \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } % \end{macrocode} % @@ -3078,27 +3254,31 @@ } % \end{macrocode} % 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=#2= but is normally empty. -% \begin{macrocode} - \tl_gput_right:Nn #1 {#2} +% with adding extra code for the |top-level| (\verb=#2=) and for one +% time execution (\verb=#3=). These should normally be empty. The +% |top-level| code is added with \cs{@@_tl_gput:Nn} as that might +% change for a reversed hook (then |top-level| is the very first code +% chunk added). The |next| code is always added last. +% \begin{macrocode} + \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } + \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } } % \end{macrocode} -% +% % \begin{macrocode} -\cs_generate_variant:Nn \@@_initialize_single:NNNn {ccc} +\cs_generate_variant:Nn \@@_initialize_single:NNn { cc } % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_tl_gput:NV,\@@_clist_gput:NV} +% \begin{macro}{\@@_tl_gput:Nn,\@@_clist_gput:NV} % These append either on the right (normal hook) or on the left % (reversed hook). This is setup up in % \cs{@@_initialize_hook_code:n}, elsewhere their behavior is undefined. % \begin{macrocode} -\cs_new:Npn \@@_tl_gput:NV {\ERROR} -\cs_new:Npn \@@_clist_gput:NV {\ERROR} +\cs_new:Npn \@@_tl_gput:Nn { \ERROR } +\cs_new:Npn \@@_clist_gput:NV { \ERROR } % \end{macrocode} % \end{macro} % @@ -3347,7 +3527,8 @@ % \begin{macrocode} \hook_if_exist:nF {#1} { \@@_log_line:x { is~not~declared! } } - \@@_if_exist:nTF {#1} + \hook_if_empty:nTF {#1} + { #2 { The~hook~is~empty } } { \@@_log_line:x { Code~chunks: } \prop_if_empty:cTF { g_@@_#1_code_prop } @@ -3357,9 +3538,25 @@ { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } } % \end{macrocode} -% +% +% If there is code in the |top-level| token list, print it: % \begin{macrocode} - \@@_log_line:x { Extra~code~for~next~invocation:} + \@@_log_line:x + { + Document-level~(top-level)~code + \hook_if_exist:nT {#1} + { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } : + } + \@@_log_line_indent:x + { + \tl_if_empty:cTF { @@_toplevel~#1 } + { --- } + { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } + } +% \end{macrocode} +% +% \begin{macrocode} + \@@_log_line:x { Extra~code~for~next~invocation: } \@@_log_line_indent:x { \tl_if_empty:cTF { @@_next~#1 } @@ -3427,7 +3624,6 @@ } } } - { #2 { The~hook~is~empty. } } } % \end{macrocode} % @@ -3478,7 +3674,7 @@ % \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} {#3} { \@@_list_if_rule_exists:nnnF {#1} {#2} { ?? } { } } } \cs_new_protected:Npn \@@_list_if_rule_exists:nnnF #1#2#3 @@ -3486,7 +3682,9 @@ \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} + \exp_after:wN \use_none:nn \fi: + \use:n } % \end{macrocode} % \end{macro} @@ -3528,12 +3726,10 @@ { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 { - \debug_suspend: \@@_declare:n {#1} \hook_if_exist:nTF {#1} { \@@_gput_next_do:nn {#1} {#2} } { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } - \debug_resume: } \cs_new_protected:Npn \@@_gput_next_do:nn #1 { @@ -3556,8 +3752,8 @@ \tl_if_empty:cT { @@~#2 } { \@@_update_hook_code:n {#2} } \tl_if_empty:NT #1 - { \tl_gset:Nn #1 { \@@_clear_next:n {#2} } } - \tl_gput_right:Nn #1 + { \@@_tl_gset:Nn #1 { \@@_clear_next:n {#2} } } + \@@_tl_gput_right:Nn #1 } \cs_new_protected:Npn \@@_clear_next:n #1 { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } @@ -3565,7 +3761,6 @@ % \end{macro} % \end{macro} % -% % \subsection{Using the hook} % % \begin{macro}{\hook_use:n} @@ -3720,8 +3915,9 @@ % % \begin{macro}[pTF]{\hook_if_empty:n} % 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 +% A \meta{hook} being empty means that all three of its +% \cs[no-index]{g_@@_\meta{hook}_code_prop}, its +% \cs[no-index]{@@_toplevel~\meta{hook}} and its % \cs[no-index]{@@_next~\meta{hook}} are empty. % \begin{macrocode} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } @@ -3730,7 +3926,11 @@ { \bool_lazy_and:nnTF { \prop_if_empty_p:c { g_@@_#1_code_prop } } - { \tl_if_empty_p:c { @@_next~#1 } } + { + \bool_lazy_and_p:nn + { \tl_if_empty_p:c { @@_toplevel~#1 } } + { \tl_if_empty_p:c { @@_next~#1 } } + } { \prg_return_true: } { \prg_return_false: } } @@ -3812,9 +4012,20 @@ % % \begin{macrocode} \msg_new:nnn { hooks } { empty-label } - { Empty~code~label~\msg_line_context:.~Using~`#1'~instead. } + { + Empty~code~label~\msg_line_context:.~ + Using~`\@@_currname_or_default:'~instead. + } % \end{macrocode} -% +% +% \begin{macrocode} +\msg_new:nnn { hooks } { no-default-label } + { + Missing~(empty)~default~label~\msg_line_context:. \\ + This~command~was~ignored. + } +% \end{macrocode} +% % \begin{macrocode} \msg_new:nnnn { hooks } { unknown-rule } { Unknown~ relationship~ `#3'~ @@ -3834,6 +4045,51 @@ % \end{macrocode} % % \begin{macrocode} +\msg_new:nnnn { hooks } { misused-top-level } + { + Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\ + 'top-level'~is~reserved~for~the~user's~document. + } + { + The~'top-level'~label~is~meant~for~user~code~only,~and~should~only~ + be~used~(sparingly)~in~the~main~document.~Use~the~default~label~ + '\@@_currname_or_default:'~for~this~\@cls@pkg,~or~another~ + suitable~label. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { set-top-level } + { + You~cannot~change~the~default~label~#1~`top-level'.~Illegal \\ + \use:nn { ~ } { ~ } \iow_char:N \\#2{#3} \\ + \msg_line_context:. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { ddhl-deprecated } + { + \iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\ + Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\ + The~deprecated~name~will~be~removed~in~the~next~release. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnn { hooks } { extra-pop-label } + { + Extra~\iow_char:N \\PopDefaultHookLabel. \\ + This~command~will~be~ignored. + } +\msg_new:nnn { hooks } { missing-pop-label } + { + Missing~\iow_char:N \\PopDefaultHookLabel. \\ + The~label~`#1'~was~pushed~but~never~popped.~Something~is~wrong. + } +% \end{macrocode} +% +% \begin{macrocode} \msg_new:nnn { hooks } { should-not-happen } { ERROR!~This~should~not~happen.~#1 \\ @@ -3879,39 +4135,77 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\SetDefaultHookLabel} +% \begin{macro}{\PushDefaultHookLabel} +% \begin{macro}{\PopDefaultHookLabel} % \begin{macro}{\DeclareDefaultHookLabel} -% \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_pop:} +% \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_push_aux:n} +% \begin{macro}{\@@_curr_name_pop:} +% \begin{macro}{\@@_end_document_label_check:} % The token list \cs{g_@@_hook_curr_name_tl} stores the name of the % current package/file to be used as label for hooks. % Providing a consistent interface is tricky, because packages can % be loaded within packages, and some packages may not use -% \cs{DeclareDefaultHookLabel} to change the default label (in which case -% \cs{@currname} is used, if set). +% \cs{SetDefaultHookLabel} to change the default label (in which +% case \cs{@currname} is used). % -% To pull that off, we keep a stack that contains the default label -% for each level of input. The bottom of the stack contains the -% 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. 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. +% To pull that one off, we keep a stack that contains the default +% label for each level of input. The bottom of the stack contains the +% default label for the |top-level| (this stack should never go +% empty). If we're building the format, set the default label to be +% |top-level|: % \begin{macrocode} -\seq_gpush:Nn \g_@@_name_stack_seq { } +\tl_gset:Nn \g_@@_hook_curr_name_tl { top-level } % \end{macrocode} % +% Then, in case we're in \pkg{latexrelease} we push something on +% the stack to support roll forward. But in some rare cases, +% \pkg{latexrelease} may be loaded inside another package (notably +% \pkg{platexrelease}), so we'll first push the |top-level| entry: +% \begin{macrocode} +%\seq_gput_right:Nn \g_@@_name_stack_seq { top-level } +% \end{macrocode} +% then we dissect the \cs{@currnamestack}, adding \cs{@currname} to +% the stack: +% \changes{v1.0f}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\cs_set_protected:Npn \@@_tmp:w #1 #2 #3 +% { +% \quark_if_recursion_tail_stop:n {#1} +% \seq_gput_right:Nn \g_@@_name_stack_seq {#1} +% \@@_tmp:w +% } +%\exp_after:wN \@@_tmp:w \@currnamestack +% \q_recursion_tail \q_recursion_tail +% \q_recursion_tail \q_recursion_stop +% \end{macrocode} +% and finalle set the default label to be the \cs{@currname}: +% \begin{macrocode} +%\tl_gset:Nx \g_@@_hook_curr_name_tl { \@currname } +% \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: +% \cs{@@_curr_name_push:n} pushes the current default label to the +% stack, and sets the new default label in one go: % \begin{macrocode} \cs_new_protected:Npn \@@_curr_name_push:n #1 + { \exp_args:Nx \@@_curr_name_push_aux:n { \@@_make_name:n {#1} } } +\cs_new_protected:Npn \@@_curr_name_push_aux:n #1 { - \seq_gpush:Nn \g_@@_name_stack_seq {#1} - \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} + \tl_if_blank:nTF {#1} + { \msg_error:nn { hooks } { no-default-label } } + { + \str_if_eq:nnTF {#1} { top-level } + { + \msg_error:nnnnn { hooks } { set-top-level } + { to } { PushDefaultHookLabel } {#1} + } + { + \seq_gpush:NV \g_@@_name_stack_seq \g_@@_hook_curr_name_tl + \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} + } + } } -% % \end{macrocode} % and when an input is over, the topmost item of the stack is popped, % since the label will not be used again, and \cs{g_@@_hook_curr_name_tl} @@ -3919,12 +4213,27 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_curr_name_pop: { - \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl - \seq_get:NNTF \g_@@_name_stack_seq \l_@@_return_tl + \seq_gpop:NNTF \g_@@_name_stack_seq \l_@@_return_tl { \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl } + { \msg_error:nn { hooks } { extra-pop-label } } + } +% \end{macrocode} +% +% At the end of the document we want to check if there was no +% \cs{@@_curr_name_push:} without a matching \cs{@@_curr_name_pop:} +% (not a critical error, but it might indicate that something else is +% not quite right): +% \begin{macrocode} +\tl_gput_right:Nn \@kernel@after@enddocument@afterlastpage + { \@@_end_document_label_check: } +\cs_new_protected:Npn \@@_end_document_label_check: + { + \seq_gpop:NNT \g_@@_name_stack_seq \l_@@_return_tl { - \msg_error:nnn { hooks } { should-not-happen } - { Tried~to~pop~from~an~empty~default~label~stack. } + \msg_error:nnx { hooks } { missing-pop-label } + { \g_@@_hook_curr_name_tl } + \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl + \@@_end_document_label_check: } } % \end{macrocode} @@ -3935,14 +4244,69 @@ % Now define a wrapper that replaces the top of the stack with the % argument, and updates \cs{g_@@_hook_curr_name_tl} accordingly. % \begin{macrocode} +\NewDocumentCommand \SetDefaultHookLabel { m } + { + \seq_if_empty:NTF \g_@@_name_stack_seq + { + \msg_error:nnnnn { hooks } { set-top-level } + { for } { SetDefaultHookLabel } {#1} + } + { \exp_args:Nx \@@_set_default_label:n { \@@_make_name:n {#1} } } + } +\cs_new_protected:Npn \@@_set_default_label:n #1 + { + \str_if_eq:nnTF {#1} { top-level } + { + \msg_error:nnnnn { hooks } { set-top-level } + { to } { SetDefaultHookLabel } {#1} + } + { \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} } + } \NewDocumentCommand \DeclareDefaultHookLabel { m } { - \seq_gpop:NN \g_@@_name_stack_seq \l_@@_return_tl - \@@_curr_name_push:n {#1} + \msg_error:nn { hooks } { ddhl-deprecated } + \SetDefaultHookLabel {#1} + } +% \end{macrocode} +% +% The label is only automatically updated with \cs{@onefilewithoptions} +% (\cs{usepackage} and \cs{documentclass}), but some packages, like +% Ti\emph{k}Z, define package-like interfaces, like +% \cs{usetikzlibrary} that are wrappers around \cs{input}, so they +% inherit the default label currently in force (usually |top-level|, +% but it may change if loaded in another package). To provide a +% package-like behaviour also for hooks in these files, we provide +% high-level access to the default label stack. +% \begin{macrocode} +\NewDocumentCommand \PushDefaultHookLabel { m } + { \@@_curr_name_push:n {#1} } +\NewDocumentCommand \PopDefaultHookLabel { } + { \@@_curr_name_pop: } +% \end{macrocode} +% +% The current label stack holds the labels for all files but the +% current one (more or less like \cs{@currnamestack}), and the current +% label token list, \cs{g_@@_hook_curr_name_tl}, holds the label for +% the current file. However \cs{@pushfilename} happens before +% \cs{@currname} is set, so we need to look ahead to get the +% \cs{@currname} for the label. \pkg{expl3} also requires the current +% file in \cs{@pushfilename}, so here we abuse +% \cs{@expl@push@filename@aux@@@@} to do \cs{@@_curr_name_push:n}. +% \begin{macrocode} +\cs_gset_protected:Npn \@expl@push@filename@aux@@@@ #1#2#3 + { + \@@_curr_name_push:n {#3} + \str_gset:Nx \g_file_curr_name_str {#3} + #1 #2 {#3} } % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % % @@ -4029,20 +4393,14 @@ % \end{macrocode} % % \begin{macro}{\@expl@@@initialize@all@@, -% \@expl@@@hook@curr@name@push@@n, % \@expl@@@hook@curr@name@pop@@} -% +% % \begin{macrocode} \cs_new_eq:NN \@expl@@@initialize@all@@ \__hook_initialize_all: % \end{macrocode} % % \begin{macrocode} -\cs_new_eq:NN \@expl@@@hook@curr@name@push@@n - \__hook_curr_name_push:n -% \end{macrocode} -% -% \begin{macrocode} \cs_new_eq:NN \@expl@@@hook@curr@name@pop@@ \__hook_curr_name_pop: % \end{macrocode} diff --git a/macros/latex/base/ltluatex.pdf b/macros/latex/base/ltluatex.pdf index e20118360c..7e559ecf45 100644 Binary files a/macros/latex/base/ltluatex.pdf and b/macros/latex/base/ltluatex.pdf differ diff --git a/macros/latex/base/ltmath.dtx b/macros/latex/base/ltmath.dtx index 36b8bb7ec4..770367c8a3 100644 --- a/macros/latex/base/ltmath.dtx +++ b/macros/latex/base/ltmath.dtx @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2020/07/27 v1.2g LaTeX Kernel (Math Setup)] + [2020/11/09 v1.2h LaTeX Kernel (Math Setup)] % \iffalse % % @@ -593,6 +593,13 @@ %\def\;{\mskip\thickmuskip} %\def\!{\mskip-\thinmuskip} % +% \end{macrocode} +% \changes{v1.2h}{2020/11/09}{\cs{negmedspace} and \cs{negthickspace} +% have been only in amsmath, so we need to undefine for rollback (gh/423)} +% \begin{macrocode} +%\let\negmedspace\@undefined +%\let\negthickspace\@undefined +% %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} diff --git a/macros/latex/base/ltmiscen.dtx b/macros/latex/base/ltmiscen.dtx index 9acbcccd68..cf7f3c836b 100644 --- a/macros/latex/base/ltmiscen.dtx +++ b/macros/latex/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2020/10/23 v1.1w LaTeX Kernel (Misc. Environments)] + [2020/12/18 v1.1x LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -277,17 +277,6 @@ % \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} @@ -395,8 +384,6 @@ % \endgroup % \deadcycles\z@\@@end} % -%\let\@kernel@after@enddocument\@undefined -%\let\@kernel@after@enddocument@afterlastpage\@undefined %\let\@enddocument@kernel@warnings\@undefined % %\EndIncludeInRelease diff --git a/macros/latex/base/ltnews.pdf b/macros/latex/base/ltnews.pdf index 902ff811d9..7da22f913b 100644 Binary files a/macros/latex/base/ltnews.pdf and b/macros/latex/base/ltnews.pdf differ diff --git a/macros/latex/base/ltnews01.pdf b/macros/latex/base/ltnews01.pdf index 8752885008..54c09ea91b 100644 Binary files a/macros/latex/base/ltnews01.pdf and b/macros/latex/base/ltnews01.pdf differ diff --git a/macros/latex/base/ltnews02.pdf b/macros/latex/base/ltnews02.pdf index a4dff175fa..cfbebec582 100644 Binary files a/macros/latex/base/ltnews02.pdf and b/macros/latex/base/ltnews02.pdf differ diff --git a/macros/latex/base/ltnews03.pdf b/macros/latex/base/ltnews03.pdf index b5cfd1312b..83b8cba6a6 100644 Binary files a/macros/latex/base/ltnews03.pdf and b/macros/latex/base/ltnews03.pdf differ diff --git a/macros/latex/base/ltnews04.pdf b/macros/latex/base/ltnews04.pdf index eff5873f9a..82f78370d2 100644 Binary files a/macros/latex/base/ltnews04.pdf and b/macros/latex/base/ltnews04.pdf differ diff --git a/macros/latex/base/ltnews05.pdf b/macros/latex/base/ltnews05.pdf index f963a2945a..a3a3ba2608 100644 Binary files a/macros/latex/base/ltnews05.pdf and b/macros/latex/base/ltnews05.pdf differ diff --git a/macros/latex/base/ltnews06.pdf b/macros/latex/base/ltnews06.pdf index ce4e6027fd..f08f189840 100644 Binary files a/macros/latex/base/ltnews06.pdf and b/macros/latex/base/ltnews06.pdf differ diff --git a/macros/latex/base/ltnews07.pdf b/macros/latex/base/ltnews07.pdf index 29e99ec882..c44afe8b77 100644 Binary files a/macros/latex/base/ltnews07.pdf and b/macros/latex/base/ltnews07.pdf differ diff --git a/macros/latex/base/ltnews08.pdf b/macros/latex/base/ltnews08.pdf index 9a29dfdc01..575c90644e 100644 Binary files a/macros/latex/base/ltnews08.pdf and b/macros/latex/base/ltnews08.pdf differ diff --git a/macros/latex/base/ltnews09.pdf b/macros/latex/base/ltnews09.pdf index 3792d6944e..938671e92b 100644 Binary files a/macros/latex/base/ltnews09.pdf and b/macros/latex/base/ltnews09.pdf differ diff --git a/macros/latex/base/ltnews10.pdf b/macros/latex/base/ltnews10.pdf index 08f4794fb0..1b065aff91 100644 Binary files a/macros/latex/base/ltnews10.pdf and b/macros/latex/base/ltnews10.pdf differ diff --git a/macros/latex/base/ltnews11.pdf b/macros/latex/base/ltnews11.pdf index 47d305bb00..b5dbd3f722 100644 Binary files a/macros/latex/base/ltnews11.pdf and b/macros/latex/base/ltnews11.pdf differ diff --git a/macros/latex/base/ltnews12.pdf b/macros/latex/base/ltnews12.pdf index 353e08f72f..103e8b18e3 100644 Binary files a/macros/latex/base/ltnews12.pdf and b/macros/latex/base/ltnews12.pdf differ diff --git a/macros/latex/base/ltnews13.pdf b/macros/latex/base/ltnews13.pdf index 9f04262286..0041691329 100644 Binary files a/macros/latex/base/ltnews13.pdf and b/macros/latex/base/ltnews13.pdf differ diff --git a/macros/latex/base/ltnews14.pdf b/macros/latex/base/ltnews14.pdf index 07bf87f377..2bc925c555 100644 Binary files a/macros/latex/base/ltnews14.pdf and b/macros/latex/base/ltnews14.pdf differ diff --git a/macros/latex/base/ltnews15.pdf b/macros/latex/base/ltnews15.pdf index 48d7b278e4..820600a8df 100644 Binary files a/macros/latex/base/ltnews15.pdf and b/macros/latex/base/ltnews15.pdf differ diff --git a/macros/latex/base/ltnews16.pdf b/macros/latex/base/ltnews16.pdf index 86bce9ff9b..3c4336dd45 100644 Binary files a/macros/latex/base/ltnews16.pdf and b/macros/latex/base/ltnews16.pdf differ diff --git a/macros/latex/base/ltnews17.pdf b/macros/latex/base/ltnews17.pdf index 4c4edcce1d..cecb7a07dc 100644 Binary files a/macros/latex/base/ltnews17.pdf and b/macros/latex/base/ltnews17.pdf differ diff --git a/macros/latex/base/ltnews18.pdf b/macros/latex/base/ltnews18.pdf index dbad7935b3..494f0fa0ec 100644 Binary files a/macros/latex/base/ltnews18.pdf and b/macros/latex/base/ltnews18.pdf differ diff --git a/macros/latex/base/ltnews19.pdf b/macros/latex/base/ltnews19.pdf index 254e795808..2c4a3b518a 100644 Binary files a/macros/latex/base/ltnews19.pdf and b/macros/latex/base/ltnews19.pdf differ diff --git a/macros/latex/base/ltnews20.pdf b/macros/latex/base/ltnews20.pdf index 96ec4b6137..b1e5c67560 100644 Binary files a/macros/latex/base/ltnews20.pdf and b/macros/latex/base/ltnews20.pdf differ diff --git a/macros/latex/base/ltnews21.pdf b/macros/latex/base/ltnews21.pdf index 5829c7a022..eb0264792c 100644 Binary files a/macros/latex/base/ltnews21.pdf and b/macros/latex/base/ltnews21.pdf differ diff --git a/macros/latex/base/ltnews22.pdf b/macros/latex/base/ltnews22.pdf index 8a6b871ce8..ddfb6d3d3a 100644 Binary files a/macros/latex/base/ltnews22.pdf and b/macros/latex/base/ltnews22.pdf differ diff --git a/macros/latex/base/ltnews23.pdf b/macros/latex/base/ltnews23.pdf index 518555e784..a32e1efbb4 100644 Binary files a/macros/latex/base/ltnews23.pdf and b/macros/latex/base/ltnews23.pdf differ diff --git a/macros/latex/base/ltnews24.pdf b/macros/latex/base/ltnews24.pdf index 11210010a2..6dc47bb3de 100644 Binary files a/macros/latex/base/ltnews24.pdf and b/macros/latex/base/ltnews24.pdf differ diff --git a/macros/latex/base/ltnews25.pdf b/macros/latex/base/ltnews25.pdf index 4965241eec..82908a28f2 100644 Binary files a/macros/latex/base/ltnews25.pdf and b/macros/latex/base/ltnews25.pdf differ diff --git a/macros/latex/base/ltnews26.pdf b/macros/latex/base/ltnews26.pdf index 9af3fd445a..604db55709 100644 Binary files a/macros/latex/base/ltnews26.pdf and b/macros/latex/base/ltnews26.pdf differ diff --git a/macros/latex/base/ltnews27.pdf b/macros/latex/base/ltnews27.pdf index 1359bc7efc..472ea7679f 100644 Binary files a/macros/latex/base/ltnews27.pdf and b/macros/latex/base/ltnews27.pdf differ diff --git a/macros/latex/base/ltnews28.pdf b/macros/latex/base/ltnews28.pdf index f5cb87308b..14ef2d02dd 100644 Binary files a/macros/latex/base/ltnews28.pdf and b/macros/latex/base/ltnews28.pdf differ diff --git a/macros/latex/base/ltnews29.pdf b/macros/latex/base/ltnews29.pdf index 5d618bc87e..e8197be1b3 100644 Binary files a/macros/latex/base/ltnews29.pdf and b/macros/latex/base/ltnews29.pdf differ diff --git a/macros/latex/base/ltnews30.pdf b/macros/latex/base/ltnews30.pdf index 35846d4fc9..920d022e99 100644 Binary files a/macros/latex/base/ltnews30.pdf and b/macros/latex/base/ltnews30.pdf differ diff --git a/macros/latex/base/ltnews31.pdf b/macros/latex/base/ltnews31.pdf index f0778f9d30..6a62e97123 100644 Binary files a/macros/latex/base/ltnews31.pdf and b/macros/latex/base/ltnews31.pdf differ diff --git a/macros/latex/base/ltnews32.pdf b/macros/latex/base/ltnews32.pdf index aed46fe573..93536d352a 100644 Binary files a/macros/latex/base/ltnews32.pdf and b/macros/latex/base/ltnews32.pdf differ diff --git a/macros/latex/base/ltshipout-code.pdf b/macros/latex/base/ltshipout-code.pdf index c5cfd30a88..f95e0ebf75 100644 Binary files a/macros/latex/base/ltshipout-code.pdf and b/macros/latex/base/ltshipout-code.pdf differ diff --git a/macros/latex/base/ltshipout-doc.pdf b/macros/latex/base/ltshipout-doc.pdf index 6a4b41f60e..074774312a 100644 Binary files a/macros/latex/base/ltshipout-doc.pdf and b/macros/latex/base/ltshipout-doc.pdf differ diff --git a/macros/latex/base/ltshipout.dtx b/macros/latex/base/ltshipout.dtx index 8f0422c887..e226f753f3 100644 --- a/macros/latex/base/ltshipout.dtx +++ b/macros/latex/base/ltshipout.dtx @@ -31,8 +31,8 @@ %%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v1.0c} -\providecommand\ltshipoutdate{2020/09/27} +\providecommand\ltshipoutversion{v1.0d} +\providecommand\ltshipoutdate{2020/11/24} % \end{macrocode} % %<*driver> @@ -1376,9 +1376,11 @@ % % % \begin{macro}{\AtBeginDvi} -% +% If we roll forward from an earlier kernel \cs{AtBeginDvi} is +% defined so we better not use \cs{cs_new_protected:Npn} here. +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} % \begin{macrocode} -\cs_new_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} +\cs_set_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} % \end{macrocode} % \end{macro} % @@ -1448,7 +1450,17 @@ % \begin{macrocode} %\IncludeInRelease{0000/00/00}% % {\shipout}{The hook management (shipout)}% -%\expandafter\let\expandafter\shipout\csname tex_shipout:D\endcsname +% +% \end{macrocode} +% If we roll forward then \cs{tex\_shipout:D} may not be defined in +% which case \cs{shipout} does have it original definition and so +% we must not \cs{let} it to something else which is \cs{relax}! +% \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} +% \begin{macrocode} +%\ifcsname tex_shipout:D\endcsname +%\expandafter\let\expandafter\shipout +% \csname tex_shipout:D\endcsname +%\fi % %\let \ShipoutBox\@undefined %\let \ReadonlyShipoutCounter \@undefined diff --git a/macros/latex/base/ltvers.dtx b/macros/latex/base/ltvers.dtx index dd69d5a6e3..c2ec2ffde3 100644 --- a/macros/latex/base/ltvers.dtx +++ b/macros/latex/base/ltvers.dtx @@ -115,7 +115,7 @@ {2020-10-01} % %<*2ekernel> -\def\patch@level{2} +\def\patch@level{3} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/macros/latex/base/ltx3info.pdf b/macros/latex/base/ltx3info.pdf index 620a9b2c6f..070c822a17 100644 Binary files a/macros/latex/base/ltx3info.pdf and b/macros/latex/base/ltx3info.pdf differ diff --git a/macros/latex/base/ltxdoc.pdf b/macros/latex/base/ltxdoc.pdf index 5080c0e0bc..e5d6fb99cf 100644 Binary files a/macros/latex/base/ltxdoc.pdf and b/macros/latex/base/ltxdoc.pdf differ diff --git a/macros/latex/base/makeindx.pdf b/macros/latex/base/makeindx.pdf index 97b26b4e72..7993372c01 100644 Binary files a/macros/latex/base/makeindx.pdf and b/macros/latex/base/makeindx.pdf differ diff --git a/macros/latex/base/manual.pdf b/macros/latex/base/manual.pdf index 0958c15eb6..50811f5d4c 100644 Binary files a/macros/latex/base/manual.pdf and b/macros/latex/base/manual.pdf differ diff --git a/macros/latex/base/modguide.pdf b/macros/latex/base/modguide.pdf index 7dafc9125a..5f51237557 100644 Binary files a/macros/latex/base/modguide.pdf and b/macros/latex/base/modguide.pdf differ diff --git a/macros/latex/base/nfssfont.pdf b/macros/latex/base/nfssfont.pdf index 8292894e71..8f189189d9 100644 Binary files a/macros/latex/base/nfssfont.pdf and b/macros/latex/base/nfssfont.pdf differ diff --git a/macros/latex/base/proc.pdf b/macros/latex/base/proc.pdf index a046c4fbfa..35ba9262e0 100644 Binary files a/macros/latex/base/proc.pdf and b/macros/latex/base/proc.pdf differ diff --git a/macros/latex/base/slides.pdf b/macros/latex/base/slides.pdf index 37779f807a..b4d275289c 100644 Binary files a/macros/latex/base/slides.pdf and b/macros/latex/base/slides.pdf differ diff --git a/macros/latex/base/slifonts.pdf b/macros/latex/base/slifonts.pdf index 67f44b6017..39952e8a88 100644 Binary files a/macros/latex/base/slifonts.pdf and b/macros/latex/base/slifonts.pdf differ diff --git a/macros/latex/base/source2e.pdf b/macros/latex/base/source2e.pdf index bc06f27f18..106d83f723 100644 Binary files a/macros/latex/base/source2e.pdf and b/macros/latex/base/source2e.pdf differ diff --git a/macros/latex/base/source2edoc.cls b/macros/latex/base/source2edoc.cls index 5b6700039c..e06108230d 100644 --- a/macros/latex/base/source2edoc.cls +++ b/macros/latex/base/source2edoc.cls @@ -2,7 +2,7 @@ % This class is buggy and needs fixing \ProvidesClass{source2edoc} - [2020/08/16 v0.1 Quick hack to typeset source2.tex + [2020/12/02 v0.2 Quick hack to typeset source2.tex (not usable for anything else and buggy -- will vanish again)!] \LoadClass{l3doc} @@ -14,8 +14,43 @@ -% l3doc's def are buggy (already fixed there but not distributed yet) + \ExplSyntaxOn + +% in 2e we have a lot of functions that have no ``user-level'' documentation so we disable +% a bogus backref in that case. Over time the sources should be clean up to have such documentation. + +\cs_set_protected:Npn \__codedoc_print_documented: + { + \seq_gset_filter:NNn \g__codedoc_nested_names_seq + \g__codedoc_nested_names_seq + { ! \__codedoc_if_macro_internal_p:n {##1} } + \seq_if_empty:NF \g__codedoc_nested_names_seq + { +% This is a crude change: we grab the first name + \__codedoc_get_hyper_target:xN + { \seq_item:Nn \g__codedoc_nested_names_seq { 1 } } + \l__codedoc_tmpa_tl +% ... and check if it has a reference + \cs_if_exist:cT{ r@\l__codedoc_tmpa_tl } +% If it does we show it, if not we don't. + { + \int_set:Nn \l__codedoc_tmpa_int + { \seq_count:N \g__codedoc_nested_names_seq } + \int_compare:nNnTF \l__codedoc_tmpa_int = 1 {~This~} {~These~} + \bool_if:NTF \l__codedoc_macro_var_bool {variable} {function} + \int_compare:nNnTF \l__codedoc_tmpa_int = 1 {~is~} {s~are~} + documented~on~page~ + \exp_args:Nx \pageref { \l__codedoc_tmpa_tl } . + } + } + \seq_gclear:N \g__codedoc_nested_names_seq + } + + + +% some l3doc's def are buggy (already fixed there but not distributed yet) + \RenewDocumentCommand \DocInclude { m } { \relax\clearpage diff --git a/macros/latex/base/syntonly.pdf b/macros/latex/base/syntonly.pdf index c13cc82d80..1493490c91 100644 Binary files a/macros/latex/base/syntonly.pdf and b/macros/latex/base/syntonly.pdf differ diff --git a/macros/latex/base/tlc2.pdf b/macros/latex/base/tlc2.pdf index 03eec97dc7..0c08e372a3 100644 Binary files a/macros/latex/base/tlc2.pdf and b/macros/latex/base/tlc2.pdf differ diff --git a/macros/latex/base/tulm.pdf b/macros/latex/base/tulm.pdf index e67d8d3522..d480c33dff 100644 Binary files a/macros/latex/base/tulm.pdf and b/macros/latex/base/tulm.pdf differ diff --git a/macros/latex/base/usrguide.pdf b/macros/latex/base/usrguide.pdf index 96de459ec3..51412a147a 100644 Binary files a/macros/latex/base/usrguide.pdf and b/macros/latex/base/usrguide.pdf differ diff --git a/macros/latex/base/utf8ienc.pdf b/macros/latex/base/utf8ienc.pdf index e97c6a4527..00da2138cd 100644 Binary files a/macros/latex/base/utf8ienc.pdf and b/macros/latex/base/utf8ienc.pdf differ diff --git a/macros/latex/base/webcomp.pdf b/macros/latex/base/webcomp.pdf index a6b1e79980..1c36db0c61 100644 Binary files a/macros/latex/base/webcomp.pdf and b/macros/latex/base/webcomp.pdf differ -- cgit v1.2.3