From bea33e16f382ecf8188f0b613d553f8367f8d0d3 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 9 Jun 2023 20:19:52 +0000 Subject: latex2e (9jun23) git-svn-id: svn://tug.org/texlive/trunk@67314 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/base/alltt.dtx | 2 +- Master/texmf-dist/source/latex/base/alltt.ins | 4 +- Master/texmf-dist/source/latex/base/classes.dtx | 11 +- Master/texmf-dist/source/latex/base/classes.ins | 4 +- Master/texmf-dist/source/latex/base/cmextra.ins | 4 +- Master/texmf-dist/source/latex/base/cmfonts.fdd | 6 +- Master/texmf-dist/source/latex/base/cmfonts.ins | 4 +- Master/texmf-dist/source/latex/base/doc.dtx | 248 +- Master/texmf-dist/source/latex/base/docstrip.dtx | 2 +- Master/texmf-dist/source/latex/base/docstrip.ins | 4 +- Master/texmf-dist/source/latex/base/ec.ins | 4 +- Master/texmf-dist/source/latex/base/exscale.dtx | 2 +- Master/texmf-dist/source/latex/base/exscale.ins | 4 +- Master/texmf-dist/source/latex/base/fix-cm.dtx | 2 +- Master/texmf-dist/source/latex/base/fix-cm.ins | 4 +- Master/texmf-dist/source/latex/base/fontdef.dtx | 2 +- Master/texmf-dist/source/latex/base/format.ins | 8 +- Master/texmf-dist/source/latex/base/graphpap.dtx | 2 +- Master/texmf-dist/source/latex/base/graphpap.ins | 4 +- Master/texmf-dist/source/latex/base/ifthen.dtx | 2 +- Master/texmf-dist/source/latex/base/ifthen.ins | 4 +- Master/texmf-dist/source/latex/base/inputenc.dtx | 2 +- Master/texmf-dist/source/latex/base/inputenc.ins | 4 +- Master/texmf-dist/source/latex/base/latex209.dtx | 2 +- Master/texmf-dist/source/latex/base/latex209.ins | 4 +- .../texmf-dist/source/latex/base/latexrelease.dtx | 13 +- .../texmf-dist/source/latex/base/latexrelease.ins | 4 +- Master/texmf-dist/source/latex/base/latexsym.dtx | 2 +- Master/texmf-dist/source/latex/base/latexsym.ins | 6 +- Master/texmf-dist/source/latex/base/letter.dtx | 2 +- Master/texmf-dist/source/latex/base/letter.ins | 4 +- Master/texmf-dist/source/latex/base/ltalloc.dtx | 2 +- Master/texmf-dist/source/latex/base/ltbibl.dtx | 2 +- Master/texmf-dist/source/latex/base/ltboxes.dtx | 2 +- Master/texmf-dist/source/latex/base/ltclass.dtx | 46 +- Master/texmf-dist/source/latex/base/ltcmd.dtx | 157 +- Master/texmf-dist/source/latex/base/ltcmdhooks.dtx | 424 ++- Master/texmf-dist/source/latex/base/ltcntrl.dtx | 2 +- Master/texmf-dist/source/latex/base/ltcounts.dtx | 2 +- Master/texmf-dist/source/latex/base/ltdefns.dtx | 228 +- Master/texmf-dist/source/latex/base/ltdirchk.dtx | 2 +- Master/texmf-dist/source/latex/base/lterror.dtx | 2 +- Master/texmf-dist/source/latex/base/ltexpl.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfilehook.dtx | 12 +- Master/texmf-dist/source/latex/base/ltfiles.dtx | 78 +- Master/texmf-dist/source/latex/base/ltfinal.dtx | 98 +- Master/texmf-dist/source/latex/base/ltfloat.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfntcmd.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfssaxes.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfssbas.dtx | 15 +- Master/texmf-dist/source/latex/base/ltfsscmp.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfssdcl.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfssini.dtx | 2 +- Master/texmf-dist/source/latex/base/ltfsstrc.dtx | 2 +- Master/texmf-dist/source/latex/base/lthooks.dtx | 2823 +++++++++++++++++--- Master/texmf-dist/source/latex/base/lthyphen.dtx | 2 +- Master/texmf-dist/source/latex/base/ltidxglo.dtx | 2 +- Master/texmf-dist/source/latex/base/ltkeys.dtx | 2 +- Master/texmf-dist/source/latex/base/ltlength.dtx | 2 +- Master/texmf-dist/source/latex/base/ltlists.dtx | 9 +- Master/texmf-dist/source/latex/base/ltlogos.dtx | 2 +- Master/texmf-dist/source/latex/base/ltluatex.dtx | 6 +- Master/texmf-dist/source/latex/base/ltmarks.dtx | 5 +- Master/texmf-dist/source/latex/base/ltmath.dtx | 25 +- Master/texmf-dist/source/latex/base/ltmeta.dtx | 5 +- Master/texmf-dist/source/latex/base/ltmiscen.dtx | 12 +- Master/texmf-dist/source/latex/base/ltoutenc.dtx | 2 +- Master/texmf-dist/source/latex/base/ltoutenc.ins | 4 +- Master/texmf-dist/source/latex/base/ltoutput.dtx | 10 +- Master/texmf-dist/source/latex/base/ltpage.dtx | 2 +- Master/texmf-dist/source/latex/base/ltpageno.dtx | 2 +- Master/texmf-dist/source/latex/base/ltpar.dtx | 2 +- Master/texmf-dist/source/latex/base/ltpara.dtx | 71 +- Master/texmf-dist/source/latex/base/ltpictur.dtx | 2 +- Master/texmf-dist/source/latex/base/ltplain.dtx | 56 +- Master/texmf-dist/source/latex/base/ltsect.dtx | 2 +- Master/texmf-dist/source/latex/base/ltshipout.dtx | 55 +- Master/texmf-dist/source/latex/base/ltspace.dtx | 7 +- Master/texmf-dist/source/latex/base/lttab.dtx | 2 +- Master/texmf-dist/source/latex/base/lttextcomp.dtx | 2 +- Master/texmf-dist/source/latex/base/ltthm.dtx | 2 +- Master/texmf-dist/source/latex/base/ltvers.dtx | 33 +- Master/texmf-dist/source/latex/base/ltxdoc.dtx | 16 +- Master/texmf-dist/source/latex/base/ltxref.dtx | 95 +- Master/texmf-dist/source/latex/base/makeindx.dtx | 2 +- Master/texmf-dist/source/latex/base/makeindx.ins | 4 +- Master/texmf-dist/source/latex/base/newdc.ins | 4 +- Master/texmf-dist/source/latex/base/newlfont.dtx | 2 +- Master/texmf-dist/source/latex/base/nfssfont.dtx | 2 +- Master/texmf-dist/source/latex/base/nfssfont.ins | 4 +- Master/texmf-dist/source/latex/base/olddc.ins | 4 +- Master/texmf-dist/source/latex/base/oldlfont.dtx | 2 +- Master/texmf-dist/source/latex/base/preload.dtx | 2 +- Master/texmf-dist/source/latex/base/proc.dtx | 2 +- Master/texmf-dist/source/latex/base/proc.ins | 4 +- Master/texmf-dist/source/latex/base/slides.dtx | 2 +- Master/texmf-dist/source/latex/base/slides.ins | 8 +- Master/texmf-dist/source/latex/base/slifonts.fdd | 2 +- Master/texmf-dist/source/latex/base/syntonly.dtx | 2 +- Master/texmf-dist/source/latex/base/syntonly.ins | 4 +- Master/texmf-dist/source/latex/base/tulm.fdd | 2 +- Master/texmf-dist/source/latex/base/tulm.ins | 4 +- Master/texmf-dist/source/latex/base/unpack.ins | 2 +- Master/texmf-dist/source/latex/base/utf8ienc.dtx | 2 +- 104 files changed, 3988 insertions(+), 790 deletions(-) (limited to 'Master/texmf-dist/source/latex/base') diff --git a/Master/texmf-dist/source/latex/base/alltt.dtx b/Master/texmf-dist/source/latex/base/alltt.dtx index 908fe924001..548b91bcea8 100644 --- a/Master/texmf-dist/source/latex/base/alltt.dtx +++ b/Master/texmf-dist/source/latex/base/alltt.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/alltt.ins b/Master/texmf-dist/source/latex/base/alltt.ins index f46404bcf4d..3f40ddc0f0d 100644 --- a/Master/texmf-dist/source/latex/base/alltt.ins +++ b/Master/texmf-dist/source/latex/base/alltt.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/classes.dtx b/Master/texmf-dist/source/latex/base/classes.dtx index 188679d4d94..58690e83759 100644 --- a/Master/texmf-dist/source/latex/base/classes.dtx +++ b/Master/texmf-dist/source/latex/base/classes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -53,7 +53,7 @@ %<*driver> \ProvidesFile{classes.drv} % - [2022/07/02 v1.4n + [2023/05/17 v1.4n % Standard LaTeX document class] %<10pt|11pt|12pt> Standard LaTeX file (size option)] % \end{macrocode} @@ -3688,9 +3688,8 @@ % % A |\caption| command in a `figure' environment writes % -% |\contentsline{figure}{\numberline{|\meta{num}|}{|% +% |\contentsline{figure}{\numberline{|\meta{num}|}{|^^A % \meta{caption}|}}{|\meta{page}|}| -% % on the .\file{lof} file, where \meta{num} is the number produced % by |\thefigure| and \meta{caption} is the figure caption. It % works similarly for a `table' environment. @@ -3707,8 +3706,8 @@ % \meta{title}|}{|\meta{page}|}| % % \begin{description} -% \item[\meta{level}] An entry is produced only if\meta{ level} -% $<=$ value of the \Lcount{tocdepth} counter. Note, +% \item[\meta{level}] An entry is produced only if \meta{level} +% $\leq$ value of the \Lcount{tocdepth} counter. Note, % |\chapter| is level 0, |\section| is level 1, etc. % \item[\meta{indent}] The indentation from the outer left margin % of the start of the contents line. diff --git a/Master/texmf-dist/source/latex/base/classes.ins b/Master/texmf-dist/source/latex/base/classes.ins index 1f7b3316911..50a51ea666c 100644 --- a/Master/texmf-dist/source/latex/base/classes.ins +++ b/Master/texmf-dist/source/latex/base/classes.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/cmextra.ins b/Master/texmf-dist/source/latex/base/cmextra.ins index a2befb3aefb..0fa45183fc9 100644 --- a/Master/texmf-dist/source/latex/base/cmextra.ins +++ b/Master/texmf-dist/source/latex/base/cmextra.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/cmfonts.fdd b/Master/texmf-dist/source/latex/base/cmfonts.fdd index 477085eaeff..af898e47b24 100644 --- a/Master/texmf-dist/source/latex/base/cmfonts.fdd +++ b/Master/texmf-dist/source/latex/base/cmfonts.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -67,7 +67,7 @@ %<*driver, > \ProvidesFile{cmfonts.drv} % - [2022/07/10 v2.5l Standard LaTeX font definitions] + [2023/04/13 v2.5m Standard LaTeX font definitions] % %<*driver> \documentclass{ltxdoc} @@ -1048,8 +1048,10 @@ % \end{macrocode} % % \changes{v2.5j}{2019/12/16}{Provide substitutions for cmtt/bx/sl} +% \changes{v2.5m}{2023/04/13}{Add missing substitution for U/cmtt/bx/sl} % \begin{macrocode} %<+OT1cmtt>\DeclareFontShape{OT1}{cmtt}{bx}{sl} +%<+Ucmtt>\DeclareFontShape{U}{cmtt}{bx}{sl} %<-nowarn> {<->sub*cmtt/m/n}{} %<+nowarn> {<->ssub*cmtt/m/n}{} %<+OT1cmtt>\DeclareFontShape{OT1}{cmtt}{bx}{ui} diff --git a/Master/texmf-dist/source/latex/base/cmfonts.ins b/Master/texmf-dist/source/latex/base/cmfonts.ins index 55af4759c57..af5ac7e5f86 100644 --- a/Master/texmf-dist/source/latex/base/cmfonts.ins +++ b/Master/texmf-dist/source/latex/base/cmfonts.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/doc.dtx b/Master/texmf-dist/source/latex/base/doc.dtx index d137038d634..75e04cc299c 100644 --- a/Master/texmf-dist/source/latex/base/doc.dtx +++ b/Master/texmf-dist/source/latex/base/doc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright 1993-2022 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2023 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -45,7 +45,7 @@ %<+package> %<+package>\ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2022/07/03 v3.0k +%<+package|shortvrb> [2022/11/13 v3.0m %<+package|shortvrb> Standard LaTeX documentation package V3 (FMi)] %\catcode`\<=12 % @@ -82,6 +82,8 @@ % \changes{v1.9a}{1993/12/02}{Upgrade for LaTeX2e} % \changes{v1.9d}{1993/12/20}{Protected changes entry.} % \changes{v1.0p}{1994/05/21}{Use new error commands} +% \changes{v3.0m}{2022/11/13}{Redefinitions of \cs{verb} removed as +% no longer needed (gh/953)} % % % \hyphenation{make-index} @@ -1208,7 +1210,7 @@ % not to exceed this limit when describing the change. The actual % entry consists of the \meta{version}, the |\actualchar|, the current % macro name, a colon, the |\levelchar|, and, finally, the \meta{text}. -% The result is a glossaryentry for the \meta{version}, with the name of +% The result is a glossary entry for the \meta{version}, with the name of % the current macro as subitem. Outside the |macro| environment, the % text |\generalname| is used instead of the macro name. When % referring to macros in change descriptions it is conventional to use @@ -1216,6 +1218,13 @@ % and using up valuable characters in the entry with old \prg{makeindex} % versions. % +% Note that in the history listing, the entry is shown with the page number +% that corresponds to its place in the source, e.g., general changes put at the +% very beginning of the file will show up with page number ``1'', change entries +% placed elsewhere might have different numbers (not necessarily always +% very useful unless you are careful). +% +% % \changes{v1.7a}{1992/02/26}{Description of \cs{RecordChanges} etc. % added % to interface section.} \DescribeInterfaceMacro\RecordChanges To cause the @@ -1824,8 +1833,8 @@ % July 1989. % \bibitem{art:docstrip} \textsc{Frank Mittelbach, Denys Duchier and % Johannes Braams}. -% \newblock \texttt{docstrip.dtx} (to appear). -% \newblock The file is part of the DOC package. +% \newblock \texttt{docstrip.dtx}. +% \newblock The file is part of core \LaTeX{}. % \bibitem{book:Raspe} \textsc{R. E. Raspe} (*1737, \dag 1797). % \newblock Baron Münchhausens narrative of his marvelous % travels and campaigns in Russia. @@ -2686,12 +2695,16 @@ % first lines are copied literally from \texttt{latex.tex}. % \changes{v1.7i}{1992/07/12}{Added \cs{@@par} to clear possible % \cs{parshape}.} +% \changes{v3.0m}{2022/11/13}{Redefinitions of \cs{@verbatim} changed +% to match the kernel definition (gh/953)} % \begin{macrocode} -\def\@verbatim{\trivlist \item[]\if@minipage\else\vskip\parskip\fi - \leftskip\@totalleftmargin\rightskip\z@ - \parindent\z@\parfillskip\@flushglue\parskip\z@ - \@@par - \@tempswafalse +\def\@verbatim{\trivlist \item\relax + \if@minipage\else\vskip\parskip\fi + \leftskip\@totalleftmargin\rightskip\z@ + \parindent\z@\parfillskip\@flushglue\parskip\z@ + \language\l@nohyphenation + \@@par + \@tempswafalse % \end{macrocode} % |\@verbatim| sets |^^M|, the end of line character, to % be equal to |\par|. This control sequence is redefined @@ -2699,8 +2712,13 @@ % \changes{v1.7c}{1992/03/24}{Added \cs{interlinepenalty} to % \cs{par} from verbatim.sty} % \begin{macrocode} - \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par - \penalty\interlinepenalty + \def\par{% + \if@tempswa + \leavevmode \null \@@par\penalty\interlinepenalty + \else + \@tempswatrue + \ifhmode\@@par\penalty\interlinepenalty\fi + \fi % \end{macrocode} % We add a control sequence |\check@percent| to the definition % of |\par| whose task it is to check for a percent character. @@ -2713,9 +2731,10 @@ % \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, % which handles more ligatures.} % \begin{macrocode} - \obeylines - \let\do\do@noligs \verbatim@nolig@list - \let\do\@makeother \dospecials} + \let\do\@makeother \dospecials + \obeylines \verbatim@font \@noligs + \everypar \expandafter{\the\everypar \unpenalty}% +} % \end{macrocode} % \end{macro} % @@ -2744,83 +2763,12 @@ % \end{macrocode} % \end{macro} % -% \begin{imacro}{\verb} -% \changes{v1.7a}{1992/02/27}{Now warns about newlines (from -% newdoc with `@noligs added).} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX \cs{verb}} -% We re-define |\verb| to check for newlines in its argument since a -% missing delimiter is difficult to detect in \DOC{} source. -% The code is the same as in \texttt{latex.tex} of September 19, 1993. -% Perhaps there should be a font-changing -% hook rather than just using |\ttfamily|, but if so it probably should be -% different from |\MacroFont| since that normally includes |\small| -% and would look wrong inline. -% \changes{v1.7a}{1992/02/28}{Added math mode check (from verbatim.sty)} -% \begin{macrocode} -\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi - \bgroup \let\do\do@noligs \verbatim@nolig@list - \ttfamily \verb@eol@error \let\do\@makeother \dospecials - \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}} -% \end{macrocode} -% \end{imacro} -% -% \begin{macro}{\verb@balance@group} -% \begin{macro}{\verb@egroup} -% \begin{macro}{\verb@eol@error} -% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb@err} to -% \cs{verb@eol@error}, as in new LaTeX verbatim.} -% \begin{macrocode} -\let\verb@balance@group\@empty -% \end{macrocode} -% -% \begin{macrocode} -\def\verb@egroup{\global\let\verb@balance@group\@empty\egroup} -% \end{macrocode} -% -% \begin{macrocode} -\begingroup - \obeylines% - \gdef\verb@eol@error{\obeylines% - \def^^M{\verb@egroup\@latex@error{% - \noexpand\verb command ended by end of line}\@ehc}}% -\endgroup -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@sverb} -% \changes{v1.7a}{1992/02/27}{Added for \cs{verb} change.} -% \changes{v1.7a}{1992/02/28}{Now same as in verbatim.sty.} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, -% which has better error trapping.} -% See \cite{art:verbatim} for commentary. -% \changes{v2.1j}{2019/11/03}{Use the kernel definition, no change needed (gh/205)} -% \begin{macrocode} -%\def\@sverb#1{% -% \catcode`#1\active \lccode`\~`#1% -% \gdef\verb@balance@group{\verb@egroup -% \@latex@error{Illegal use of \noexpand\verb command}\@ehc}% -% \aftergroup\verb@balance@group -% \lowercase{\let~\verb@egroup}} -% \end{macrocode} -% \end{macro} -% % -% \begin{macro}{\verbatim@nolig@list} -% \begin{macro}{\do@noligs} -% These macros replace the old |\@noligs| mechanism by an -% extensible version to allow more ligatures to be added. -% \begin{macrocode} -\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-} -\def\do@noligs#1{% - \catcode`#1\active - \begingroup - \lccode`\~=`#1\relax - \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}} -% \end{macrocode} -% \end{macro} -% \end{macro} +% In the early versions of the package it also redefined \cs{verb} +% because that didn't include the useful test for \enquote{newline} in +% the verbatim text. This is nowadays part of \LaTeX{} so we do not +% redefine it any longer (the original code is still kept in the file +% after \cs{endinput} to keep the long history intact). % % \begin{tcounter}{\macro@cnt} % \label{page:macro} The \env{macro} environment is implemented as @@ -3147,9 +3095,6 @@ % % \begin{macro}{\short@macro} % -% \fmi{this needs cleaning up too, the results in the index are -% currently wrong for cases like `\cs{ }' and the like.} -% % \changes{v1.5c}{1989/04/27}{Corrected bad bug by putting the % scan@allowedfalse macro before printing % the argument.} @@ -3164,17 +3109,14 @@ % done by the |\ifnot@excluded| macro which assumes that the % macro name is saved in |\macro@namepart|. The character % mustn't be stored with a special category code or exclusion from -% the index won't work, so we employ the case-changing trick used -% elsewhere. Since the argument might be an active character, -% |\string| is used to normalize it. +% the index won't work, so we we use \cs{string} to normalize it +% the same way it is done in \cs{DoNotIndex}, i.e. everything ends up catcode 12 +% except for the space character. % \changes{v2.0e}{1998/12/28}{Correctly use the case-changing trick.} +% \changes{v3.0l}{2022/11/03}{No longer using the case-changing trick.} % \begin{macrocode} -\begingroup -\catcode`\&=12 -\gdef\short@macro#1{\begingroup - \uccode`\&=\expandafter`\string#1% - \uppercase{\def\x{\def\macro@namepart{&}}}% - \expandafter\endgroup\x +\def\short@macro#1{% + \edef\macro@namepart{\string#1}% % \end{macrocode} % Any indexing is then delegated to % |\maybe@index@short@macro|. Depending on the actual character seen, @@ -3197,7 +3139,6 @@ % cross-referencing is globally disabled. % \begin{macrocode} \scan@allowedtrue } -\endgroup % \end{macrocode} % \end{macro} % @@ -3441,7 +3382,6 @@ \def \ShowIndexingState { \__doc_trace:x{Show~ doc~ indexing~ state:} \seq_show:N \l__doc_donotindex_seq -% \tl_analysis_show:N\l__doc_donotindex_seq \prop_show:N \g__doc_idxtype_prop } % \end{macrocode} @@ -3637,10 +3577,12 @@ % \begin{macro}{\maybe@index@short@macro} % \begin{macro}{\__doc_maybe_index_short:o} % Single character macros are handled similarly but there the -% indexing is done by \cs{SpecialShortIndex}. +% indexing is done by \cs{SpecialShortIndex} and it is simpler +% because we know that the argument contains a string token not letters. +% \changes{v3.0l}{2022/11/03}{We know the argument expands to a single string token} % \begin{macrocode} \cs_new:Npn \__doc_maybe_index_short:o #1 { - \exp_args:Nf \__doc_maybe_index_aux:nN { \tl_to_str:o {#1} } + \exp_args:No \__doc_maybe_index_aux:nN #1 \SpecialShortIndex } \cs_set_eq:NN \maybe@index@short@macro \__doc_maybe_index_short:o @@ -3715,7 +3657,12 @@ {\cs_to_str:N \^^M } {\def\reserved@a{ \string \space \actualchar } \def\reserved@b { \space } \let\reserved@c \@empty } - { } {\def\reserved@a{ \string \space \actualchar } +% \end{macrocode} +% With the fix for +% \verb*=\ = we now have to look for a real space to handle that command sequence. +% \changes{v3.0l}{2022/11/03}{look for the right token} +% \begin{macrocode} + { ~ } {\def\reserved@a{ \string \space \actualchar } \def\reserved@b { \space } \let\reserved@c \@empty } {\c_left_brace_str} { \def\reserved@a{ \bgroup \actualchar } @@ -6256,6 +6203,89 @@ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% \section{Code no longer used} +% +% \begin{imacro}{\verb} +% \changes{v1.7a}{1992/02/27}{Now warns about newlines (from +% newdoc with `@noligs added).} +% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX \cs{verb}} +% We re-define |\verb| to check for newlines in its argument since a +% missing delimiter is difficult to detect in \DOC{} source. +% The code is the same as in \texttt{latex.tex} of September 19, 1993. +% Perhaps there should be a font-changing +% hook rather than just using |\ttfamily|, but if so it probably should be +% different from |\MacroFont| since that normally includes |\small| +% and would look wrong inline. +% \changes{v1.7a}{1992/02/28}{Added math mode check (from verbatim.sty)} +% \begin{macrocode} +%\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi +% \bgroup \let\do\do@noligs \verbatim@nolig@list +% \ttfamily \verb@eol@error \let\do\@makeother \dospecials +% \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}} +% \end{macrocode} +% \end{imacro} +% +% \begin{macro}{\verb@balance@group} +% \begin{macro}{\verb@egroup} +% \begin{macro}{\verb@eol@error} +% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb@err} to +% \cs{verb@eol@error}, as in new LaTeX verbatim.} +% \begin{macrocode} +%\let\verb@balance@group\@empty +% \end{macrocode} +% +% \begin{macrocode} +%\def\verb@egroup{\global\let\verb@balance@group\@empty\egroup} +% \end{macrocode} +% +% \begin{macrocode} +%\begingroup +% \obeylines% +% \gdef\verb@eol@error{\obeylines% +% \def^^M{\verb@egroup\@latex@error{% +% \noexpand\verb command ended by end of line}\@ehc}}% +%\endgroup +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@sverb} +% \changes{v1.7a}{1992/02/27}{Added for \cs{verb} change.} +% \changes{v1.7a}{1992/02/28}{Now same as in verbatim.sty.} +% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, +% which has better error trapping.} +% See \cite{art:verbatim} for commentary. +% \changes{v2.1j}{2019/11/03}{Use the kernel definition, no change needed (gh/205)} +% \begin{macrocode} +%\def\@sverb#1{% +% \catcode`#1\active \lccode`\~`#1% +% \gdef\verb@balance@group{\verb@egroup +% \@latex@error{Illegal use of \noexpand\verb command}\@ehc}% +% \aftergroup\verb@balance@group +% \lowercase{\let~\verb@egroup}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\verbatim@nolig@list} +% \begin{macro}{\do@noligs} +% These macros replace the old |\@noligs| mechanism by an +% extensible version to allow more ligatures to be added. +% \begin{macrocode} +%\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-} +%\def\do@noligs#1{% +% \catcode`#1\active +% \begingroup +% \lccode`\~`#1\relax +% \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}} +% \end{macrocode} +% \end{macro} +% \end{macro} + ^^A Needed for emacs ^^A diff --git a/Master/texmf-dist/source/latex/base/docstrip.dtx b/Master/texmf-dist/source/latex/base/docstrip.dtx index de20073c481..be373499e6b 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.dtx +++ b/Master/texmf-dist/source/latex/base/docstrip.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/docstrip.ins b/Master/texmf-dist/source/latex/base/docstrip.ins index e2187594a44..79d4c429ddd 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.ins +++ b/Master/texmf-dist/source/latex/base/docstrip.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -52,7 +52,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/ec.ins b/Master/texmf-dist/source/latex/base/ec.ins index 47823e7edf2..15a7c3848cf 100644 --- a/Master/texmf-dist/source/latex/base/ec.ins +++ b/Master/texmf-dist/source/latex/base/ec.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/exscale.dtx b/Master/texmf-dist/source/latex/base/exscale.dtx index bc884c4db07..89890a41981 100644 --- a/Master/texmf-dist/source/latex/base/exscale.dtx +++ b/Master/texmf-dist/source/latex/base/exscale.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/exscale.ins b/Master/texmf-dist/source/latex/base/exscale.ins index d202aad7cf3..ae75460ee53 100644 --- a/Master/texmf-dist/source/latex/base/exscale.ins +++ b/Master/texmf-dist/source/latex/base/exscale.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/fix-cm.dtx b/Master/texmf-dist/source/latex/base/fix-cm.dtx index 5f8983ed345..9e39cd192b9 100644 --- a/Master/texmf-dist/source/latex/base/fix-cm.dtx +++ b/Master/texmf-dist/source/latex/base/fix-cm.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/fix-cm.ins b/Master/texmf-dist/source/latex/base/fix-cm.ins index b688cd66cfa..68c67924123 100644 --- a/Master/texmf-dist/source/latex/base/fix-cm.ins +++ b/Master/texmf-dist/source/latex/base/fix-cm.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/fontdef.dtx b/Master/texmf-dist/source/latex/base/fontdef.dtx index 06af8feefd3..5e88e550791 100644 --- a/Master/texmf-dist/source/latex/base/fontdef.dtx +++ b/Master/texmf-dist/source/latex/base/fontdef.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/format.ins b/Master/texmf-dist/source/latex/base/format.ins index 369f01a7c53..74cd78ff4a8 100644 --- a/Master/texmf-dist/source/latex/base/format.ins +++ b/Master/texmf-dist/source/latex/base/format.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -88,7 +88,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2015-2022 +Copyright (C) 2015-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -123,7 +123,7 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/graphpap.dtx b/Master/texmf-dist/source/latex/base/graphpap.dtx index 78bb688f83d..6b7bc8b8229 100644 --- a/Master/texmf-dist/source/latex/base/graphpap.dtx +++ b/Master/texmf-dist/source/latex/base/graphpap.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/graphpap.ins b/Master/texmf-dist/source/latex/base/graphpap.ins index d82cbd66706..43ba83aae3c 100644 --- a/Master/texmf-dist/source/latex/base/graphpap.ins +++ b/Master/texmf-dist/source/latex/base/graphpap.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/ifthen.dtx b/Master/texmf-dist/source/latex/base/ifthen.dtx index d36042990d4..aefc4a76660 100644 --- a/Master/texmf-dist/source/latex/base/ifthen.dtx +++ b/Master/texmf-dist/source/latex/base/ifthen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ifthen.ins b/Master/texmf-dist/source/latex/base/ifthen.ins index 88047e94f05..697a4a38b3f 100644 --- a/Master/texmf-dist/source/latex/base/ifthen.ins +++ b/Master/texmf-dist/source/latex/base/ifthen.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/inputenc.dtx b/Master/texmf-dist/source/latex/base/inputenc.dtx index e056f8ffd78..02956a8c07b 100644 --- a/Master/texmf-dist/source/latex/base/inputenc.dtx +++ b/Master/texmf-dist/source/latex/base/inputenc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/inputenc.ins b/Master/texmf-dist/source/latex/base/inputenc.ins index adacf9efce8..38578270709 100644 --- a/Master/texmf-dist/source/latex/base/inputenc.ins +++ b/Master/texmf-dist/source/latex/base/inputenc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/latex209.dtx b/Master/texmf-dist/source/latex/base/latex209.dtx index 768f7237a58..b84564bb55f 100644 --- a/Master/texmf-dist/source/latex/base/latex209.dtx +++ b/Master/texmf-dist/source/latex/base/latex209.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/latex209.ins b/Master/texmf-dist/source/latex/base/latex209.ins index f530347a3cf..0c90fa36ea7 100644 --- a/Master/texmf-dist/source/latex/base/latex209.ins +++ b/Master/texmf-dist/source/latex/base/latex209.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/latexrelease.dtx b/Master/texmf-dist/source/latex/base/latexrelease.dtx index 294007553d3..4abde253e16 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.dtx +++ b/Master/texmf-dist/source/latex/base/latexrelease.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -40,7 +40,7 @@ %<*latexrelease> % \fi % \ProvidesFile{latexrelease.dtx} - [2022/02/28 v1.0o LaTeX release emulation and tests + [2022/11/14 v1.0p LaTeX release emulation and tests (including releases up to \latexreleaseversion)] % \iffalse % @@ -746,8 +746,12 @@ of this package available from CTAN} % % Finally, redirect the error thrown by \cs{NewHook} to nowhere so it % can be safely reused (the hook isn't redeclared if it already exists). +% The same happens for \cs{NewMarkClass}. +% \changes{v1.0p}{2022/11/14} +% {Silence \cs{NewMarkClass} in rollback (gh/955)} % \begin{macrocode} \msg_redirect_name:nnn { hooks } { exists } { none } +\msg_redirect_name:nnn { mark } { class-already-defined }{ none } % \end{macrocode} % % Now a one-off for |ltcmd.dtx|: we need to make \cs{NewDocumentCommand} @@ -799,9 +803,12 @@ of this package available from CTAN} \tl_clear:N \l_@@_restores_tl % \end{macrocode} % -% And restore the hook error message. +% And restore the silenced error messages. +% \changes{v1.0p}{2022/11/14} +% {Unsilence \cs{NewMarkClass} error message after rollback (gh/955)} % \begin{macrocode} \msg_redirect_name:nnn { hooks } { exists } { } +\msg_redirect_name:nnn { mark } { class-already-defined } { } % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/latexrelease.ins b/Master/texmf-dist/source/latex/base/latexrelease.ins index b5e97a94798..61315f8e078 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.ins +++ b/Master/texmf-dist/source/latex/base/latexrelease.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/latexsym.dtx b/Master/texmf-dist/source/latex/base/latexsym.dtx index 62fb097c0d2..e4e1559e277 100644 --- a/Master/texmf-dist/source/latex/base/latexsym.dtx +++ b/Master/texmf-dist/source/latex/base/latexsym.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/latexsym.ins b/Master/texmf-dist/source/latex/base/latexsym.ins index 468afddd678..12d658bca98 100644 --- a/Master/texmf-dist/source/latex/base/latexsym.ins +++ b/Master/texmf-dist/source/latex/base/latexsym.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -87,7 +87,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/letter.dtx b/Master/texmf-dist/source/latex/base/letter.dtx index 4052c260c86..3e3c36d3d06 100644 --- a/Master/texmf-dist/source/latex/base/letter.dtx +++ b/Master/texmf-dist/source/latex/base/letter.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/letter.ins b/Master/texmf-dist/source/latex/base/letter.ins index c078dc59ce9..c522f39e595 100644 --- a/Master/texmf-dist/source/latex/base/letter.ins +++ b/Master/texmf-dist/source/latex/base/letter.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/ltalloc.dtx b/Master/texmf-dist/source/latex/base/ltalloc.dtx index 4530d4b07ba..c3498fb9c70 100644 --- a/Master/texmf-dist/source/latex/base/ltalloc.dtx +++ b/Master/texmf-dist/source/latex/base/ltalloc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltbibl.dtx b/Master/texmf-dist/source/latex/base/ltbibl.dtx index 4c219657b87..8e34ca685ae 100644 --- a/Master/texmf-dist/source/latex/base/ltbibl.dtx +++ b/Master/texmf-dist/source/latex/base/ltbibl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltboxes.dtx b/Master/texmf-dist/source/latex/base/ltboxes.dtx index b82f5bdb8e2..ff1717caa97 100644 --- a/Master/texmf-dist/source/latex/base/ltboxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltboxes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltclass.dtx b/Master/texmf-dist/source/latex/base/ltclass.dtx index a525b6f573e..bb521485085 100644 --- a/Master/texmf-dist/source/latex/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex/base/ltclass.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2022/10/22 v1.5e LaTeX Kernel (Class & Package Interface)] + [2023/04/14 v1.5h LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -324,6 +324,7 @@ % % \DescribeMacro\IfPackageAtLeastTF % \DescribeMacro\IfClassAtLeastTF +% \DescribeMacro\IfFileAtLeastTF % \DescribeMacro\@ifpackagelater % \DescribeMacro\@ifclasslater % \changes{v1.1i}{2013/07/07}{Correctly describe how the date in @@ -890,12 +891,14 @@ % % \begin{macro}{\IfPackageAtLeastTF} % \begin{macro}{\IfClassAtLeastTF} +% \begin{macro}{\IfFileAtLeastTF} % \begin{macro}{\IfFormatAtLeastTF} % |\IfFormatAtLeastTF{YYYY/MM/DD}{|\meta{true % code}|}{|\meta{false code}|}| % Test if the format is later or equal to the given date. % \changes{v1.3k}{2020/04/07}{Macro added; also in rollback (gh/168)} % \changes{v1.4e}{2021/07/19}{Drop \cs{@onlypreamble}} +% \changes{v1.5g}{2023/03/28}{Added \cs{IfFileAtLeastTF} (gh/1015)} % \begin{macrocode} % %<*2ekernel|latexrelease> @@ -904,6 +907,7 @@ \def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} \let\IfPackageAtLeastTF\@ifpackagelater \let\IfClassAtLeastTF\@ifclasslater +\def\IfFileAtLeastTF#1{\expandafter\@ifl@t@r\csname ver@#1\endcsname} % \end{macrocode} % For rollback pretend it was available since the beginning of dawn. % \begin{macrocode} @@ -914,12 +918,14 @@ %\def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} %\let\IfPackageAtLeastTF\@ifpackagelater %\let\IfClassAtLeastTF\@ifclasslater +%\def\IfFileAtLeastTF#1{\expandafter\@ifl@t@r\csname ver@#1\endcsname} %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@ifl@ter} % \changes{v1.4e}{2021/07/19}{Drop \cs{@onlypreamble}} @@ -2133,13 +2139,28 @@ % {Reset \cs{CurrentOption}} % \changes{v1.3d}{2019/10/18}{Initialize \cs{...-h@@k} only when loading % the package or class (gh/198)} +% \changes{v1.5h}{2023/04/14}{Define \cs{load@onefilewithoptions} when +% in \pkg{latexrelease} (gh/992)} % \begin{macrocode} % %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% % {\@onefilewithoptions}{Hooks and unused options issue}% +% \end{macrocode} +% +% Here this macro is called \cs{@onefilewithoptions}, but further +% ahead in this file it is renamed to \cs{load@onefilewithoptions}, +% and \cs{@onefilewithoptions} becomes a wrapper around this, used for +% bookkeeping when rolling back. Therefore, when in +% \pkg{latexrelease}, we need to define \cs{load@onefilewithoptions} +% instead, thus the extra guarded \cs{def} line below: +% \begin{macrocode} +%<*2ekernel> \def\@onefilewithoptions#1[#2][#3]#4{% +% +%\def\load@onefilewithoptions#1[#2][#3]#4{% % \end{macrocode} +% % We have to sanitise file names, so that something like % \begin{verbatim} % \usepackage{some/local/path/array} @@ -2813,6 +2834,7 @@ % unknown option. % \changes{v1.3h}{2020/01/28}{Allow spaces in option string and display % only unknown options not the whole option list (gh/256)} +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} % \begin{macrocode} \def\filec@ntents@opt[#1]{% \edef\@fortmp{\zap@space#1 \@empty}% @@ -2821,7 +2843,7 @@ \csname filec@ntents@\reserved@a\endcsname \else \@latex@error{Unknown filecontents option \reserved@a}% - {Valid options are force (or overwrite), nosearch, noheader}% + {Valid options are force (or overwrite), nosearch, noheader, nowarn}% \fi}% \filec@ntents } @@ -2849,6 +2871,18 @@ \let\filec@ntents@checkdir\@empty \def\filec@ntents@where{exists on the system} % \end{macrocode} +% Option \texttt{nowarn} does not show any warning on the terminal +% but still writes it to the \texttt{.log}. +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} +% \begin{macrocode} +\def\filec@ntents@nowarn{% + \let\filec@ntents@warning\@latex@note@no@line +} +% \end{macrocode} +% By default we show terminal warnings. +% \begin{macrocode} +\let\filec@ntents@warning\@latex@warning@no@line +% \end{macrocode} % % \begin{macrocode} \begingroup% @@ -2925,6 +2959,8 @@ % on the terminal. % \changes{v1.3g}{2020/01/27}{Fix typo in error message} % \changes{v1.3j}{2020/02/20}{Fix missing quotes around file name (gh/284)} +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} +% \changes{v1.5f}{2022/11/16}{Do not show "current dir" in message (gh/917)} % \begin{macrocode} \ch@ck7\reserved@c\write\relax% \if@filesw% % Foul ... trying to overwrite \jobname! @@ -2932,8 +2968,8 @@ write to the file you are reading from!\MessageBreak% Data is written to screen instead.}% \else% - \@latex@warning@no@line% - {Writing or overwriting file `\@currdir\@curr@file'}% + \filec@ntents@warning% + {Writing or overwriting file `\@curr@file'}% \immediate\openout\reserved@c\q@curr@file\relax% \fi% \fi% diff --git a/Master/texmf-dist/source/latex/base/ltcmd.dtx b/Master/texmf-dist/source/latex/base/ltcmd.dtx index 14d6756f5c2..d6322ff3ee8 100644 --- a/Master/texmf-dist/source/latex/base/ltcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltcmd.dtx @@ -1,8 +1,8 @@ % \iffalse meta-comment % % Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle -% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project -% Copyright (C) 2009-2022 +% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX Project +% Copyright (C) 2009-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -34,8 +34,8 @@ %%% From File: ltcmd.dtx % % \begin{macrocode} -\def\ltcmdversion{v1.1a} -\def\ltcmddate{2022-08-16} +\def\ltcmdversion{v1.1e} +\def\ltcmddate{2023-05-26} % \end{macrocode} % %<*driver> @@ -725,6 +725,9 @@ { \@@_environment_or_command: } } % \end{macrocode} +% +% \changes{v1.1e}{2023/05/26} +% {Use simpler variant \cs{cs_generate_from_arg_count:NNno}} % To construct \cs{@@_tmp:w}, first go through the arguments % found and the corresponding defaults, building a token list with % |{#|\meta{arg number}|}| for arguments found in the input (whose @@ -738,10 +741,10 @@ \int_zero:N \l_@@_current_arg_int \@@_tl_mapthread_function:NNN \l_@@_args_tl \l_@@_defaults_tl \@@_defaults_def:nn - \cs_generate_from_arg_count:NNVo \@@_tmp:w \cs_set:Npn + \cs_generate_from_arg_count:NNno \@@_tmp:w \cs_set:Npn \l_@@_current_arg_int \l_@@_tmpa_tl } -\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo } +\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNno } \cs_new_protected:Npn \@@_defaults_def:nn { \int_incr:N \l_@@_current_arg_int @@ -2123,8 +2126,8 @@ % and possibly another auxiliary % \cs{\meta{cmd}\textvisiblespace\textvisiblespace}, if the command % has both long and short arguments. Then, its signature also has -% several specific bits that are unique to that command; this is in contrast to -% non-expandable commands, which use a common set of parsing functions. +% several specific bits that are unique to that command; this is in contrast +% to non-expandable commands, which use a common set of parsing functions. % % We start by copying the basics, then call % \cs{@@_copy_expandable_signature:NnNNNNnnn} to parse the signature @@ -2132,7 +2135,24 @@ % then we call \cs{@@_copy_expandable:NnNNNNnnn} that will copy the % top-level definition of the command, with the proper internal % renames. +% % \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_copy:NN}% +% {Support~\NewCommandCopy~in~ltcmd} +%\EndIncludeInRelease +% \end{macrocode} +% +% \changes{v1.1c}{2023/03/12} +% {Distinguish (non-expandable) document commands starting with +% \cs{@@_start_expandable:nNNNNn}} +% There's one variant: a command begins with \cs{@@_start_expandable:nNNNNn} +% may still be un-expandable/protected if it's defined by +% \cs{NewDocumentCommand} and friends, with empty or only m-type arguments. +% +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_copy_expandable:nnNN}% +% {Distinguish~non-expandable~document~commands} \cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4 { \cs_set_eq:cc { #1 ~ code } { #2 ~ code } @@ -2140,9 +2160,36 @@ \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl } \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults } \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2} - \cs_set_nopar:Npx #3 + \token_if_protected_macro:NTF #4 + { \cs_set_protected_nopar:Npx }{ \cs_set_nopar:Npx } + #3 { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} } } +%\EndIncludeInRelease +%\IncludeInRelease{2021/11/15}{\@@_copy_expandable:nnNN}% +% {Support~\NewCommandCopy~in~ltcmd} +%\cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4 +% { +% \cs_set_eq:cc { #1 ~ code } { #2 ~ code } +% \@@_set_eq_if_exist:cc { #1 ~ } { #2 ~ } +% \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl } +% \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults } +% \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2} +% \cs_set_nopar:Npx #3 +% { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} } +% } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_copy_expandable:nnNN}% +% {Support~\NewCommandCopy~in~ltcmd} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2021/11/15}{\@@_copy:NN (part 2)}% +% {Support~\NewCommandCopy~in~ltcmd} +% \end{macrocode} +% +% \begin{macrocode} \cs_new:Npn \@@_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9 { \exp_not:N #1 \exp_not:n { {#2} } @@ -2355,7 +2402,7 @@ % worth it. % \begin{macrocode} %\EndIncludeInRelease -%\IncludeInRelease{2020/10/01}{\@@_copy:NN}% +%\IncludeInRelease{2020/10/01}{\@@_copy:NN (part 2)}% % {Support~\NewCommandCopy~in~ltcmd} %\EndIncludeInRelease % \end{macrocode} @@ -2401,21 +2448,64 @@ % \@@_show_command:NnNNwN, % \@@_show_expandable:N, % \@@_show_expandable:NnNNNNnN, -% \@@_show_command_aux:nNNn, +% \@@_show_command_aux:NnNNn, % \@@_show_environment:N, +% \@@_show:x, % } % These commands just expand the command once to reveal its innards, % then pass the type of command, the control sequence, the signature, -% and the code macro to \cs{@@_show_command_aux:nNNn}. +% and the code macro to \cs{@@_show_command_aux:NnNNn}. % \begin{macrocode} \cs_new_protected:Npn \@@_show_command:N #1 { \exp_after:wN \@@_show_command:NnNNwN #1 \q_@@ #1 } \cs_new_protected:Npn \@@_show_command:NnNNwN #1 #2 #3 #4 #5 \q_@@ #6 - { \@@_show_command_aux:nNNn { document~command } #6 #4 {#2} } + { + \@@_show_command_aux:NnNNn \tl_show:x + { document~command } #6 #4 {#2} + } \cs_new_protected:Npn \@@_show_expandable:N #1 { \exp_after:wN \@@_show_expandable:NnNNNNnN #1 #1 } +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_show:N}% +% {Support~\ShowCommand~in~ltcmd} +%\EndIncludeInRelease +% \end{macrocode} +% +% \changes{v1.1c}{2023/03/12} +% {Distinguish (non-expandable) document commands starting with +% \cs{@@_start_expandable:nNNNNn}} +% There's one variant: a command begins with \cs{@@_start_expandable:nNNNNn} +% may still be un-expandable/protected if it's defined by +% \cs{NewDocumentCommand} and friends, with empty or only m-type arguments. +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_show_expandable:NnNNNNnN}% +% {Distinguish~non-expandable~document~commands} \cs_new_protected:Npn \@@_show_expandable:NnNNNNnN #1 #2 #3 #4 #5 #6 #7 #8 - { \@@_show_command_aux:nNNn { expandable~document~command } #8 #5 {#2} } + { + \exp_args:NNe \@@_show_command_aux:NnNNn \tl_show:x + { \token_if_protected_macro:NF #8 { expandable~ } document~command } + #8 #5 {#2} + } +%\EndIncludeInRelease +%\IncludeInRelease{2021/11/15}{\@@_show_expandable:NnNNNNnN}% +% {Support~\ShowCommand~in~ltcmd} +%\cs_new_protected:Npn \@@_show_expandable:NnNNNNnN #1 #2 #3 #4 #5 #6 #7 #8 +% { +% \@@_show_command_aux:NnNNn \tl_show:x +% { expandable~document~command } #8 #5 {#2} +% } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_show_expandable:NnNNNNnN}% +% {Support~\ShowCommand~in~ltcmd} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2021/11/15}{\@@_show:N (part 2)}% +% {Support~\ShowCommand~in~ltcmd} % \end{macrocode} % % Now just print everything in the required format. The auxiliary @@ -2423,27 +2513,31 @@ % \cs{l_@@_tmpa_tl}, so we ust use that here: % \changes{v1.0j}{2021/13/31} % {Make \cs{ShowCommand} stop for interaction} +% \changes{v1.1b}{2022/11/30} +% {Don't stop for the \cs{begin} part of an environment} % \begin{macrocode} -\cs_new_protected:Npn \@@_show_command_aux:nNNn #1 #2 #3 #4 +\cs_new_protected:Npn \@@_show_command_aux:NnNNn #1 #2 #3 #4 #5 { - \@@_split_signature:n {#4} - \tl_show:x + \@@_split_signature:n {#5} + #1 { - \token_to_str:N #2 = #1: \iow_newline: + \token_to_str:N #3 = #2: \iow_newline: \tl_use:N \l_@@_tmpa_tl - -> \cs_replacement_spec:N #3 + -> \cs_replacement_spec:N #4 } } % \end{macrocode} % % We can reuse most of the above to show an environment, except that % we need to ensure that the proper \cs[no-index]{environment~\ldots} -% are passed to \cs{@@_show_command_aux:nNNn}. Additionally, when +% are passed to \cs{@@_show_command_aux:NnNNn}. Additionally, when % |\ShowCommand\foo| is used (if |foo| is an environment), we show % |\endfoo| as well, and when |\ShowCommand\endfoo| is used, change % that to |\ShowCommand\foo| and do the same. % \changes{v1.0j}{2021/13/31} % {Make \cs{ShowCommand} stop for interaction} +% \changes{v1.1b}{2022/11/30} +% {Don't stop for the \cs{begin} part of an environment} % \begin{macrocode} \cs_new_protected:Npn \@@_show_environment:N #1 { @@ -2459,12 +2553,14 @@ { \use:x { - \@@_show_command_aux:nNNn { document~environment } + \@@_show_command_aux:NnNNn \@@_show:x { document~environment } { \exp_not:N \begin {#3} } \exp_not:c { environment~ #3 ~ code } {#2} } } +\cs_new_protected:Npn \@@_show:x #1 + { \iow_term:x { > ~ #1 . \iow_newline: } } \cs_new_protected:Npn \@@_show_environment_end:N #1 { \exp_args:NNx \@@_check_end:Nn \l_@@_tmpa_tl { \cs_to_str:N #1 } @@ -2473,10 +2569,15 @@ % \end{macrocode} % % And, of course, add \cs{__kernel_cmd_if_xparse:NTF} and -% \cs{@@_show:N} to \cs{@showcommandlisthook}: +% \cs{@@_show:N} to \cs{@showcommandlisthook} and to +% \cs{@showenvironmentlisthook} (\cs{@@_show:N} takes care of the +% environment case as well, so both entries are identical): +% \changes{v1.1b}{2022-11-29}{Add \cs{@showenvironmentlisthook}} % \begin{macrocode} \tl_gput_right:Nn \@showcommandlisthook { { \__kernel_cmd_if_xparse:NTF \@@_show:N } } +\tl_gput_right:Nn \@showenvironmentlisthook + { { \__kernel_cmd_if_xparse:NTF \@@_show:N } } % \end{macrocode} % \end{macro} % @@ -2657,7 +2758,7 @@ % \begin{macrocode} %\EndIncludeInRelease % -%\IncludeInRelease{2020/10/01}{\@@_show:N}% +%\IncludeInRelease{2020/10/01}{\@@_show:N (part 2)}% % {Support~\ShowCommand~in~ltcmd} %\EndIncludeInRelease % \end{macrocode} @@ -3200,6 +3301,10 @@ % \begin{macro}{\@@_grab_v_long:w} % \begin{macro}{\@@_grab_v_aux:w} % \begin{macro}{\@@_grab_v_group_end:} +% Firstly, it is necessary to change \cs{tex_endlinechar:D} so that +% newlines in different catcode regimes (e.g., \cs{ExplSyntaxOn}) are +% not misinterpreted as spaces. +% \changes{v1.1d}{2023/04/13}{Set \cs{tex_endlinechar:D} earlier (gh/876).} % The opening delimiter is the first non-space token, and is never % read verbatim. This is required by consistency with the case where % the preceding argument was optional and absent: then \TeX{} has @@ -3233,6 +3338,7 @@ \tl_set:Nn \l_@@_signature_tl {#1} \group_begin: \tex_escapechar:D = 92 \scan_stop: + \tex_endlinechar:D = `\^^M \scan_stop: \tl_clear:N \l_@@_v_arg_tl \peek_remove_spaces:n { @@ -3250,8 +3356,8 @@ } \cs_new_protected:Npn \@@_grab_v_group_end: { - \exp_args:NNNo - \group_end: + \exp_args:NNNo + \group_end: \tl_set:Nn \l_@@_v_arg_tl { \l_@@_v_arg_tl } } % \end{macrocode} @@ -3396,7 +3502,6 @@ { \cs_set_eq:NN \do \char_set_catcode_other:N \dospecials - \tex_endlinechar:D = `\^^M \scan_stop: \bool_if:NTF \l_@@_long_bool { \char_set_catcode_other:n { \tex_endlinechar:D } } { \char_set_catcode_parameter:n { \tex_endlinechar:D } } diff --git a/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx index ccb5a35a712..27907af6798 100644 --- a/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx +++ b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltcmdhooks.dtx (C) Copyright 2020-2021 -%% Frank Mittelbach, Phelype Oleinik, LaTeX Team +%% File: ltcmdhooks.dtx +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, Phelype Oleinik, The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -13,8 +14,8 @@ % %%% From File: ltcmdhooks.dtx % -\def\ltcmdhooksversion{v1.0f} -\def\ltcmdhooksdate{2021/10/20} +\def\ltcmdhooksversion{v1.0h} +\def\ltcmdhooksdate{2023/05/21} % % % @@ -51,20 +52,32 @@ % % This file implements generic hooks for (arbitrary) commands. % In theory every command \tn[no-index]{\meta{name}} offers now two -% associated hooks to which code can be added using \tn{AddToHook} -% or \tn{AddToHookNext}.\footnote{In practice this is not supported +% associated hooks to which code can be added using +% \tn{AddToHook},\!\footnote{In this documentation, when something is +% being said about \tn{AddToHook}, the same will be valid for +% \tn{AddToHookWithArguments}, unless that particular paragraph is +% highlighting the differences between both. The same is true for +% the other hook-related functions and their +% \texttt{\ldots WithArguments} counterparts.} +% \tn{AddToHookNext}, \tn{AddToHookWithArguments}, and +% \tn{AddToHookNextWithArguments}.\footnote{In practice this is not +% supported % for all types of commands, see section~\ref{sec:look-ahead} for % the restrictions that apply and what happens if one tries to use -% this with commands for which this is not supported.} These are +% this with commands for which this is not supported.} These are: % \begin{description} % \item[\hook{cmd/\meta{name}/before}] % -% This hook is executed at the very start of the command -% execution after its arguments (if any) are parsed. The hook -% \meta{code} is wrapped in the command inside a call to -% \cs{UseHook}|{cmd/|\meta{name}|/before}|, so the arguments -% passed to the command are \emph{not} available in the hook -% \meta{code}. +% This hook is executed at the very start of the command, right +% after its arguments (if any) are parsed. The hook \meta{code} +% runs in the command inside a call to \cs{UseHookWithArguments}. +% Any code added to this hook using \tn{AddToHookWithArguments} +% or \tn{AddToHookNextWithArguments} can access the command's +% arguments using |#1|, |#2|, etc., up to the number of arguments +% of the command. If \tn{AddToHook} or \tn{AddToHookNext} are +% used, the arguments cannot be accessed (see the \pkg{lthooks} +% documentation\footnote{\texttt{texdoc lthooks-doc}} on hooks +% with arguments). % % \item[\hook{cmd/\meta{name}/after}] % @@ -74,9 +87,12 @@ % \end{description} % % The hooks are not physically present before -% \verb=\begin{document}= (i.e., using a command in the preamble -% will never execute them) and if nobody has declared any code for -% them, then they are not added to the command code ever. For +% \verb=\begin{document}=\footnote{More specifically, they are +% inserted in the commands after the \hook{begindocument} hook, so +% they are also not present while \LaTeX{} is reading the +% \texttt{.aux} file.} (i.e., using a command in the preamble +% will never execute the hook) and if nobody has declared any code +% for them, then they are not added to the command code ever. For % example, if we have the following definition %\begin{verbatim} % \newcommand\foo[2]{Code #1 for #2!} @@ -90,23 +106,27 @@ %\end{verbatim} % then, after |\begin{document}| the definition of \cs[no-index]{foo} will be: %\begin{verbatim} -% \renewcommand\foo[2]{\UseHook{cmd/foo/before}Code #1 for #2!} +% \renewcommand\foo[2]{% +% \UseHookWithArguments{cmd/foo/before}{2}{#1}{#2}% +% Code #1 for #2!} %\end{verbatim} % and similarly \verb=\AddToHook{cmd/foo/after}{}= % alters the definition to %\begin{verbatim} -% \renewcommand\foo[2]{Code #1 for #2!\UseHook{cmd/foo/after}} +% \renewcommand\foo[2]{% +% Code #1 for #2!% +% \UseHookWithArguments{cmd/foo/after}{2}{#1}{#2}} %\end{verbatim} % % In other words, the mechanism is similar to what \pkg{etoolbox} % offers with \tn{pretocmd} and \tn{apptocmd} with the important -% differences +% differences % \begin{itemize} % \item % % that code can be prepended or appended (i.e., added to the % hooks) even if the command itself is not defined, because the -% defining package has not yet been loaded +% defining package has not yet been loaded; % % \item % @@ -197,6 +217,7 @@ % % % \section{Package Author Interface} +% \label{sec:pkg-author} % % The \hook{cmd} hooks are, by default, available for all commands % that can be patched to add the hooks. For some commands, however, @@ -206,9 +227,10 @@ % % If you are a package author and you want to add the hooks to your % own commands in the proper position you can define the command and -% manually add the \cs{UseHook} calls inside the command in the proper -% positions, and manually define the hooks with \cs{NewHook} or -% \cs{NewReversedHook}. When the hooks are explicitly defined, +% manually add the \cs{UseHookWithArguments} calls inside the command in +% the proper positions, and manually define the hooks with +% \cs{NewHookWithArguments} or \cs{NewReversedHookWithArguments}. +% When the hooks are explicitly defined, % patching is not attempted so you can make sure your command works % properly. For example, an (admittedly not really useful) command % that typesets its contents in a framed box with width optionally @@ -230,26 +252,27 @@ % \begin{verbatim} % \newcommand\fancybox{\@ifnextchar({\@fancybox}{\@fancybox(5cm)}} % \def\@fancybox(#1)#2{\fbox{% -% \UseHook{cmd/fancybox/before}% -% \parbox{#1}{#2}% -% \UseHook{cmd/fancybox/after}}} -% \NewHook{cmd/fancybox/before} -% \NewReversedHook{cmd/fancybox/after} +% \UseHookWithArguments{cmd/fancybox/before}{2}{#1}{#2}% +% \parbox{#1}{#2}% +% \UseHookWithArguments{cmd/fancybox/after}{2}{#1}{#2}}} +% \NewHookWithArguments{cmd/fancybox/before}{2} +% \NewReversedHookWithArguments{cmd/fancybox/after}{2} % \end{verbatim} % then the hooks will be executed where they should and no patching % will be attempted. It is important that the hooks are declared with -% \cs{NewHook} or \cs{NewReversedHook}, otherwise the command hook +% \cs{NewHookWithArguments} or \cs{NewReversedHookWithArguments}, +% otherwise the command hook % code will try to patch the command. Note also that the call to -% |\UseHook{cmd/fancybox/before}| does not need to be in the -% definition of \cs[no-index]{fancybox}, but anywhere it makes sense +% |\UseHookWithArguments{cmd/fancybox/before}| does not need to be in +% the definition of \cs[no-index]{fancybox}, but anywhere it makes sense % to insert it (in this case in the internal % \cs[no-index]{@fancybox}). % % Alternatively, if for whatever reason your command does not support % the generic hooks provided here, you can disable a hook with -% \cs{DisableHook}\footnote{Please use \cs{DisableHook} if at all, only -% on hooks that you \enquote{own}, i.e., for commands that your -% package or class defines and not second guess +% \cs{DisableGenericHook}\footnote{Please use \cs{DisableGenericHook} if +% at all, only on hooks that you \enquote{own}, i.e., for commands +% your package or class defines and not second guess % whether or not hooks of other packages should get disabled!}, so % that when someone tries to add code to it they will get an error. % Or if you don't want the error, you can simply declare the hook with @@ -270,6 +293,55 @@ % If you do that then both hooks automatically work and are patched % into the right places. % +% \subsection{Arguments and redefining commands} +% \label{sec:redef-warn} +% +% The code in \pkg{ltcmdhooks} does its best to find out how many +% arguments a given command has, and to insert the appropriate call to +% \cs{UseHookWithArguments}, so that the arguments seen by the hook are +% exactly those grabbed by the command (the hook, after all, is a macro +% call, so the arguments have to be placed in the right order, or they +% won't match). +% +% When using the package writer interface, as discussed in +% section~\ref{sec:pkg-author}, to change the position of the hooks in +% your commands, you are also free to change how the hook code in your +% command sees its arguments. When a \hook{cmd} hook is declared with +% \cs{NewHook} (or \cs{NewHookWithArguments} or other variations of +% that), it loses its \enquote{generic} nature and works as a regular +% hook. This means that you may choose to declare it without +% arguments regardless if the command takes arguments or not, or +% declare it with arguments, even if the command takes none. +% +% However, this flexibility should not be abused. When using a +% nonstandard configuration for the hook arguments, think reasonably: +% a user will expect that the argument \verb|#1| in the hook corresponds +% to the argument's first argument, and so on. Any other configuration +% is likely to cause confusion and, if used, will have to be well +% documented. +% +% This flexibility, however, allows you to \enquote{correct} the +% arguments for the hooks. For example, \LaTeX's \cs{refstepcounter} +% has a single argument, the name of the counter. The \pkg{cleveref} +% package adds an optional argument to \cs{refstepcounter}, making the +% name of the counter argument \verb|#2|. If the author of +% \pkg{cleveref} wanted, for whatever reason, to add hooks to +% \cs{refstepcounter}, to preserve compatibility he could write +% something along the lines of: +% \begin{verbatim} +% \NewHookWithArguments{cmd/refstepcounter/before}{1} +% \renewcommand\refstepcounter[2][]{% +% \UseHookWithArguments{cmd/refstepcounter/before}{1}{#2}% +% } +% \end{verbatim} +% so that the mandatory argument, which is arg \verb|#2| in the +% definition, would still be seen as \verb|#1| in the hook code. +% +% Another possibility would be to place the optional argument as the +% second argument for the hook, so that people looking for it would be +% able to use it. In either case, it would have to be well documented +% to cause as little confusion as possible. +% % \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } % % @@ -366,10 +438,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\c_@@_hash_tl} -% A constant token list that contains two parameter tokens. +% \begin{macro}{\c_@@_hash_tl,\c_@@_hashes_tl} +% Two constant token lists that contain one and two parameter tokens. +% \changes{v1.0g}{2023/04/06} +% {Rename to \cs{c_@@_hashes_tl} and add \cs{c_@@_hash_tl} (hook-args).} % \begin{macrocode} -\tl_const:Nn \c_@@_hash_tl { # # } +\tl_const:Nn \c_@@_hash_tl { # } +\tl_const:Nn \c_@@_hashes_tl { # # } % \end{macrocode} % \end{macro} % @@ -702,7 +777,7 @@ % % \changes{v1.0f}{2021/10/20} % {Correct patching by expansion+redefinition when the macro -% contains a parameter tokens (gh/697).} +% contains a parameter token (gh/697).} % Patching with expansion+redefinition is trickier than it looks like % at first glance. Suppose the simple definition: % \begin{verbatim} @@ -756,6 +831,8 @@ % parameter token, so that this case can be handled like the previous % one. % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_patch_expand_redefine:NNnn} +% {cmd~hooks~with~args} \cs_new_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4 { \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } @@ -779,14 +856,14 @@ % should be identical to the \meta{parameter text} used when % originally defining that macro. % \item[\cs{l_@@_replace_text_tl}] will contain braced pairs of -% \cs{c_@@_hash_tl}\meta{num} to feed to the macro when expanded. +% \cs{c_@@_hashes_tl}\meta{num} to feed to the macro when expanded. % This token list as well as the previous will have the first item % surrounded by |[|\ldots|]| in the case of an optional argument. % \end{description} % -% The use of \cs{c_@@_hash_tl} here is to differentiate actual +% The use of \cs{c_@@_hashes_tl} here is to differentiate actual % parameters in the macro from parameter tokens in the original -% definition of the macro. Later on, \cs{c_@@_hash_tl} is either +% definition of the macro. Later on, \cs{c_@@_hashes_tl} is either % replaced by actual parameter tokens, or expanded into them. % \begin{macrocode} \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } @@ -795,7 +872,7 @@ % We'll first check if the command has any parameter token in its % definition (feeding it empty arguments), and set \cs{@@_exp_not:n} % accordingly. \cs{@@_exp_not:n} will be used later to either leave -% \cs{c_@@_hash_tl} or expand it, and also to remember the result of +% \cs{c_@@_hashes_tl} or expand it, and also to remember the result of % \cs{@@_if_has_hash:nTF} to avoid testing twice (the test can be % rather slow). % \begin{macrocode} @@ -814,20 +891,22 @@ % \end{macrocode} % Here we'll conditionally add |[|\ldots|]| around the first % parameter: +% \changes{v1.0g}{2023/04/06} +% {Rename to \cs{c_@@_hashes_tl} (hook-args).} % \begin{macrocode} \bool_if:NTF #1 - { \@@_tmp:w \tl_set:Nx { [ \c_@@_hash_tl 1 ] } } - { \@@_tmp:w \tl_set:Nx { { \c_@@_hash_tl 1 } } } + { \@@_tmp:w \tl_set:Nx { [ \c_@@_hashes_tl 1 ] } } + { \@@_tmp:w \tl_set:Nx { { \c_@@_hashes_tl 1 } } } % \end{macrocode} % Then, for every parameter from the second, just add it normally: % \begin{macrocode} \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } - { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hash_tl ##1 } } } + { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hashes_tl ##1 } } } % \end{macrocode} % Now, if the command has any parameter token in its definition % (then \cs{@@_exp_not:n} is \cs{exp_not:n}), call % \cs{@@_double_hashes:n} to double them, and replace every -% \cs{c_@@_hash_tl} by |#|: +% \cs{c_@@_hashes_tl} by |#|: % \begin{macrocode} \tl_set:Nx \l_@@_replace_text_tl { \exp_not:N #2 \exp_not:V \l_@@_replace_text_tl } @@ -875,22 +954,110 @@ { \exp_not:N \@@_make_prefixes:w \cs_prefix_spec:N #2 / / } } % \end{macrocode} -% Finally, call \cs{@@_redefine_with_hooks:Nnnn} with the macro being +% Here we redefine the hook to have the right number of arguments. +% Disabling the hook, undefining the \verb|parameter| token list then +% calling \cs{@@_make_usable:nn} are enough to redefine the hook to +% the extent we want. Code stored in the hook and other metadata +% about it are not lost in the process. +% \changes{v1.0h}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} + \@@_disable:n { cmd / #3 / #4 } + \cs_undefine:c { c_@@_cmd / #3 / #4_parameter_tl } + \@@_make_usable:nn { cmd / #3 / #4 } { \l_@@_patch_num_args_int } +% \end{macrocode} +% Now call \cs{@@_redefine_with_hooks:Nnnn} with the macro being % redefined in |#1|, then \cs{UseHook}|{cmd//before}| in |#2| or % \cs{UseHook}|{cmd//after}| in |#3| (one is always empty), and % in |#4| the \meta{replacement text} of the macro. % \begin{macrocode} - \use:x + \use:e { \@@_redefine_with_hooks:Nnnn \exp_not:N #2 \str_if_eq:nnTF {#4} { after } { \use_ii_i:nn } { \use:nn } - { { \@@_exp_not:NN \exp_not:N \UseHook { cmd / #3 / #4 } } } + { { + \@@_exp_not:NN \exp_not:N \UseHookWithArguments + { cmd / #3 / #4 } { \int_use:N \l_@@_patch_num_args_int } + \@@_braced_parameter:n { cmd / #3 / #4 } + } } { { } } { \@@_exp_not:NN \exp_not:V \l_@@_replace_text_tl } } +% \end{macrocode} +% Finally, update the hook code. +% \begin{macrocode} + \@@_update_hook_code:n { cmd / #3 / #4 } } +%\EndIncludeInRelease +%\IncludeInRelease{2021/06/01}{\@@_patch_expand_redefine:NNnn} +% {cmd~hooks~with~args} +%\cs_gset_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4 +% { +% \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } +% \int_set:Nn \l_@@_patch_num_args_int +% { +% \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2 +% \bool_if:NT #1 { -1 } +% } +% \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } +% { +% \tl_set:Nx \l_@@_tmpa_tl { \bool_if:NTF #1 { [ ] } { { } } } +% \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } +% { \tl_put_right:Nn \l_@@_tmpa_tl { { } } } +% \exp_args:NNo \exp_args:No \@@_if_has_hash:nTF +% { \exp_after:wN #2 \l_@@_tmpa_tl } +% { \cs_set_eq:NN \@@_exp_not:n \exp_not:n } +% { \cs_set_eq:NN \@@_exp_not:n \use:n } +% \cs_set_protected:Npn \@@_tmp:w ##1 ##2 +% { +% ##1 \l_@@_param_text_tl { \use:n ##2 } +% ##1 \l_@@_replace_text_tl { \@@_exp_not:n {##2} } +% } +% \bool_if:NTF #1 +% { \@@_tmp:w \tl_set:Nx { [ \c_@@_hash_tl 1 ] } } +% { \@@_tmp:w \tl_set:Nx { { \c_@@_hash_tl 1 } } } +% \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } +% { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hash_tl ##1 } } } +% \tl_set:Nx \l_@@_replace_text_tl +% { \exp_not:N #2 \exp_not:V \l_@@_replace_text_tl } +% \tl_set:Nx \l_@@_replace_text_tl +% { +% \token_if_eq_meaning:NNTF \@@_exp_not:n \exp_not:n +% { \exp_args:NNV \exp_args:No \@@_double_hashes:n } +% { \exp_args:NV \exp_not:o } +% \l_@@_replace_text_tl +% } +% \cs_set_eq:NN \@@_def_cmd:w \tex_gdef:D +% \cs_set_eq:NN \@@_exp_not:NN \prg_do_nothing: +% } +% { +% \tl_clear:N \l_@@_param_text_tl +% \tl_set_eq:NN \l_@@_replace_text_tl #2 +% \cs_set_eq:NN \@@_def_cmd:w \tex_xdef:D +% \cs_set:Npn \@@_exp_not:NN ##1 { \exp_not:N ##1 \exp_not:N } +% } +% \group_begin: +% \int_set:Nn \tex_escapechar:D { `\/ } +% \use:x +% { +% \group_end: +% \tl_set:Nx \exp_not:N \l_@@_patch_prefixes_tl +% { \exp_not:N \@@_make_prefixes:w \cs_prefix_spec:N #2 / / } +% } +% \use:x +% { +% \@@_redefine_with_hooks:Nnnn \exp_not:N #2 +% \str_if_eq:nnTF {#4} { after } +% { \use_ii_i:nn } +% { \use:nn } +% { { \@@_exp_not:NN \exp_not:N \UseHook { cmd / #3 / #4 } } } +% { { } } +% { \@@_exp_not:NN \exp_not:V \l_@@_replace_text_tl } +% } +% } +%\EndIncludeInRelease % \end{macrocode} % % Now that all the needed tools are ready, without further ado we'll @@ -973,7 +1140,7 @@ % } % \cs{@@_double_hashes:n} loops through the token list |#1| and % duplicates any catcode~6 token, and expands tokens \cs{ifx}-equal to -% \cs{c_@@_hash_tl}, and leaves all other tokens \cs{notexpanded} with +% \cs{c_@@_hashes_tl}, and leaves all other tokens \cs{notexpanded} with % \cs{exp_not:N}. Unfortunately pairs of explicit catcode~1 and % catcode~2 character tokens are normalised to |{|$_1$ and |}|$_1$ % because it's not feasible to expandably detect the character code @@ -1000,26 +1167,32 @@ % \end{macrocode} % % \cs{@@_double_hashes_output:N} checks for the end of the token list, -% then checks if the token is \cs{c_@@_hash_tl}, and if so just leaves +% then checks if the token is \cs{c_@@_hashes_tl}, and if so just leaves % it. +% \changes{v1.0g}{2023/04/06} +% {Add case for \cs{c_@@_hashes_tl} (hook-args).} % \begin{macrocode} \cs_new:Npn \@@_double_hashes_output:N #1 { \if_meaning:w \q_@@_recursion_tail #1 \@@_double_hashes_stop:w \fi: - \if_meaning:w \c_@@_hash_tl #1 + \if:w ? + \if_meaning:w \c_@@_hash_tl #1 ! \fi: + \if_meaning:w \c_@@_hashes_tl #1 ! \fi: + ? + \else: % \end{macrocode} % (this \cs{use_i:nnnn} uses \cs{fi:} and consumes \cs{use:n}, the % whole \cs{if_catcode:w} block, and the \cs{exp_not:N}, leaving just -% |#1| which is \cs{c_@@_hash_tl}.) +% |#1| which is \cs{c_@@_hashes_tl}.) % \begin{macrocode} \use_i:nnnn \fi: \use:n { % \end{macrocode} -% If |#1| is not \cs{c_@@_hash_tl}, then check if its catcode is~6, +% If |#1| is not \cs{c_@@_hashes_tl}, then check if its catcode is~6, % and if so, leave it doubled in \cs{exp_not:n} and consume the % following |\exp_not:N #1|. % \begin{macrocode} @@ -1080,10 +1253,10 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_retokenize_patch:Nnn #1 #2 #3 { - \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning } \str_if_eq:eeTF { \cs_argument_spec:N #1 } { } { \@@_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} } { + \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning } % \end{macrocode} % % Otherwise, we start the actual patching by retokenization job. The @@ -1144,6 +1317,8 @@ % \cs{@@_cmd_if_scanable:NnTF} and \cs{@@_patch_retokenize:Nnnn} if % the former returns \meta{true}, plus some debug messages. % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_try_patch_with_catcodes:Nnnnw} +% {cmd~hooks~with~args} \cs_new_protected:Npn \@@_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4 { \quark_if_recursion_tail_stop_do:nn {#4} { \use:n } @@ -1152,7 +1327,7 @@ { \@@_patch_debug:x { ++~macro~can~be~retokenized~cleanly } \@@_patch_debug:x { ==~retokenizing~macro~now } - \@@_patch_retokenize:Nnnn #1 {#2} {#3} {#4} + \@@_patch_retokenize:Nnnn #1 { cmd / #2 / #3 } {#3} {#4} \use_i_delimit_by_q_recursion_stop:nw \use_none:n } { @@ -1160,6 +1335,26 @@ \@@_try_patch_with_catcodes:Nnnnw #1 {#2} {#3} } } +%\EndIncludeInRelease +%\IncludeInRelease{2021/06/01}{\@@_try_patch_with_catcodes:Nnnnw} +% {cmd~hooks~with~args} +%\cs_gset_protected:Npn \@@_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4 +% { +% \quark_if_recursion_tail_stop_do:nn {#4} { \use:n } +% \@@_patch_debug:x { ++~trying~to~patch~by~retokenization } +% \@@_cmd_if_scanable:NnTF {#1} {#4} +% { +% \@@_patch_debug:x { ++~macro~can~be~retokenized~cleanly } +% \@@_patch_debug:x { ==~retokenizing~macro~now } +% \@@_patch_retokenize:Nnnn #1 {#2} {#3} {#4} +% \use_i_delimit_by_q_recursion_stop:nw \use_none:n +% } +% { +% \@@_patch_debug:x { --~macro~cannot~be~retokenized~cleanly } +% \@@_try_patch_with_catcodes:Nnnnw #1 {#2} {#3} +% } +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -1267,15 +1462,86 @@ % \end{macro} % % +% \begin{macro}{\@@_guess_arg_count:NN} +% \begin{macro}{\@@_guess_arg_count:wN} +% \begin{macro}{\@@_guess_arg_count:nw} +% Looks at the parameter text of a macro, and counts the parameters +% by looking at the number after a \verb|#|, and checking if they are +% sequential. This macro assumes that all parameters are marked with +% hashes, and not other characters, and that there is no +% \enquote{trick parameter}. +% \changes{v1.0h}{2023/05/21} +% {Macro added (cmd-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_guess_arg_count:NN} +% {cmd~hooks~with~args} +\cs_new_protected:Npn \@@_guess_arg_count:NN #1 + { + \exp_after:wN \@@_guess_arg_count:wN + \token_to_meaning:N #1 \s_@@_mark + } +\exp_last_unbraced:NNNNo +\cs_new_protected:Npx \@@_guess_arg_count:wN + #1 { \tl_to_str:n { macro: } } #2 \s_@@_mark #3 + { + \int_set:Nn #3 + { + \exp_not:N \@@_guess_arg_count:nw { 0 } #2 + \c_hash_str 0 \s_@@_mark + } + } +\use:e + { \cs_new:Npn \exp_not:N \@@_guess_arg_count:nw #1 #2 \c_hash_str #3 } + { + \int_compare:nNnTF { #1 + 1 } = {#3} + { \@@_guess_arg_count:nw {#3} } + { #1 \@@_use_none_delimit_by_s_mark:w } + } +%\EndIncludeInRelease +%\IncludeInRelease{2021/06/01}{\@@_guess_arg_count:NN} +% {cmd~hooks~with~args} +%\cs_undefine:N \@@_guess_arg_count:NN +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % % \begin{macro}{\@@_patch_retokenize:Nnnn} % Then, if \cs{@@_cmd_if_scanable:NnTF} returned true, we can go on % and patch the command. % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_patch_retokenize:Nnnn} +% {cmd~hooks~with~args} \cs_new_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4 { +% Here, when patching by retokenization, we can only guess the number +% of arguments of the macro. +% \changes{v1.0h}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} + \@@_guess_arg_count:NN #1 \l_@@_patch_num_args_int % \end{macrocode} -% Start off by making some things \tn{relax} to avoid lots of +% +% Then we redefine the hook to have the right number of arguments. +% Disabling the hook, undefining the \verb|parameter| token list then +% calling \cs{@@_make_usable:nn} are enough to redefine the hook to +% the extent we want. Code stored in the hook and other metadata +% about it are not lost in the process. +% \begin{macrocode} + \@@_disable:n {#2} + \cs_undefine:c { c_@@_#2_parameter_tl } + \@@_make_usable:nn {#2} { \l_@@_patch_num_args_int } + \tl_set:Ne \l_@@_tmpa_tl + { \exp_args:Ne \tl_to_str:n { \@@_braced_parameter:n {#2} } } + \use:x + { + \str_replace_all:Nnn \exp_not:N \l_@@_tmpa_tl + { #### } { \c_hash_str } + } +% \end{macrocode} +% Then, make make some things \tn{relax} to avoid lots of % \tn{noexpand} below. % \begin{macrocode} \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop: @@ -1301,10 +1567,18 @@ ####1 \def \kerneltmpDoNotUse ####2 { \str_if_eq:nnT {#3} { before } - { \token_to_str:N \UseHook { cmd / #2 / #3 } } + { + \token_to_str:N \UseHookWithArguments {#2} + { \int_use:N \l_@@_patch_num_args_int } + \l_@@_tmpa_tl + } ####3 \str_if_eq:nnT {#3} { after } - { \token_to_str:N \UseHook { cmd / #2 / #3 } } + { + \token_to_str:N \UseHookWithArguments {#2} + { \int_use:N \l_@@_patch_num_args_int } + \l_@@_tmpa_tl + } } } % \end{macrocode} @@ -1328,7 +1602,39 @@ % {Make patching of commands a global operation (gh/674)} % \begin{macrocode} \cs_gset_eq:NN #1 \kerneltmpDoNotUse +% \end{macrocode} +% Finally, update the hook code. +% \begin{macrocode} + \@@_update_hook_code:n {#2} } +%\EndIncludeInRelease +%\IncludeInRelease{2021/06/01}{\@@_patch_retokenize:Nnnn} +% {cmd~hooks~with~args} +%\cs_gset_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4 +% { +% \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop: +% \cs_set_eq:NN \@@_tmp:w \scan_stop: +% \use:x +% { +% \cs_set:Npn \@@_tmp:w +% ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s_@@_mark +% { +% ####1 \def \kerneltmpDoNotUse ####2 +% { +% \str_if_eq:nnT {#3} { before } +% { \token_to_str:N \UseHook { cmd / #2 / #3 } } +% ####3 +% \str_if_eq:nnT {#3} { after } +% { \token_to_str:N \UseHook { cmd / #2 / #3 } } +% } +% } +% \tl_set:Nx \exp_not:N \l_@@_tmpa_tl +% { \exp_not:N \@@_tmp:w \token_to_meaning:N #1 \s_@@_mark } +% } +% \tl_rescan:nV { #4 \@@_patch_required_catcodes: } \l_@@_tmpa_tl +% \cs_gset_eq:NN #1 \kerneltmpDoNotUse +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/base/ltcntrl.dtx b/Master/texmf-dist/source/latex/base/ltcntrl.dtx index 5ebe256c75d..52dcdbf9837 100644 --- a/Master/texmf-dist/source/latex/base/ltcntrl.dtx +++ b/Master/texmf-dist/source/latex/base/ltcntrl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltcounts.dtx b/Master/texmf-dist/source/latex/base/ltcounts.dtx index ffe2265ac39..69025fa479f 100644 --- a/Master/texmf-dist/source/latex/base/ltcounts.dtx +++ b/Master/texmf-dist/source/latex/base/ltcounts.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltdefns.dtx b/Master/texmf-dist/source/latex/base/ltdefns.dtx index bd820e7cf21..209c4e0fbab 100644 --- a/Master/texmf-dist/source/latex/base/ltdefns.dtx +++ b/Master/texmf-dist/source/latex/base/ltdefns.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2022/05/22 v1.5r LaTeX Kernel (definition commands)] + [2022/11/24 v1.5s LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -784,7 +784,9 @@ % not take arguments. (but may contain |\par|s) % % Make sure that an attempt to define a `graf' or `group' environment -% fails. +% fails by temporarily letting the undefined \verb=\...= (begin code) to +% the definition of \verb=\end...= and as a result we get an error if that +% has a definition. % \begin{macrocode} \long\def\@newenv#1#2#3#4{% \@ifundefined{#1}% @@ -1641,6 +1643,7 @@ % \end{macrocode} % % \begin{macro}{\declare@commandcopy} +% \begin{macro}{\declare@commandcopy@do} % Start by checking if the command is already defined. The proper action is % taken by each specific command above. If all's good, then % \cs{robust@command@act} is called with the proper arguments as described @@ -1650,11 +1653,14 @@ \long\def\declare@commandcopy#1#2#3#4{% \edef\reserved@a{\@expl@cs@to@str@@N#3}% \@ifundefined\reserved@a{#1}{#2}% - {\robust@command@act - \@declarecommandcopylisthook#4% - \declare@commandcopy@let{#3#4}}} + {\declare@commandcopy@do{#3}{#4}}} +\long\def\declare@commandcopy@do#1#2{% + \robust@command@act + \@declarecommandcopylisthook#2% + \declare@commandcopy@let{#1#2}} % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\@declarecommandcopylisthook} % The initial definition of \cs{@declarecommandcopylisthook} contains the @@ -1694,6 +1700,64 @@ % \end{macro} % % +% \begin{macrocode} +% +%\IncludeInRelease{2023-06-01}{\DeclareEnvironmentCopy} +% {Add \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macro}{\NewEnvironmentCopy} +% \begin{macro}{\RenewEnvironmentCopy} +% \begin{macro}{\DeclareEnvironmentCopy} +% If \verb=\#1= or \verb=\end#1= already exist one gets an error +% message talking about the problematical command (not the +% environment). +% The remainder of the \LaTeX{} run is probably badly +% broken and it is unlikely that continuing it gives +% reasonable results. +% \changes{v1.5s}{2022/11/24}{Add \cs{NewEnvironmentCopy}, +% \cs{RenewEnvironmentCopy}, and \cs{DeclareEnvironmentCopy} (gh/963)} +% \begin{macrocode} +\def\NewEnvironmentCopy{% + \declare@environmentcopy + {\@firstofone}% + {\@firstoftwo\@notdefinable}} +\def\RenewEnvironmentCopy{% + \declare@environmentcopy + {\@latex@error{Environment \reserved@a\space undefined}\@ehc + \@firstofone}% + {\@firstofone}} +\def\DeclareEnvironmentCopy{% + \declare@environmentcopy + {\@firstofone}% + {\@firstofone}} +\long\def\declare@environmentcopy#1#2#3#4{% + \edef\reserved@a{\@ifundefined{#3}{end#3}{#3}}% + \@ifundefined\reserved@a + {\def\reserved@a{#3}#1}% + {\def\reserved@a{#3}#2}% + {\ExpandArgs{cc}\declare@commandcopy@do{#3}{#4}% + \ExpandArgs{cc}\declare@commandcopy@do{end#3}{end#4}}} +% \end{macrocode} +% +% Now the rollback code. +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000-00-00}{\DeclareEnvironmentCopy} +% {Undefine \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}% +%\let\NewEnvironmentCopy\@undefined +%\let\RenewEnvironmentCopy\@undefined +%\let\DeclareEnvironmentCopy\@undefined +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% % \subsubsection{Showing robust commands} % % \begin{macro}{\ShowCommand} @@ -1747,7 +1811,6 @@ % \end{macrocode} % \end{macro} % -% % \begin{macrocode} % %\IncludeInRelease{2020-10-01}{\@if@DeclareRobustCommand} @@ -1836,6 +1899,7 @@ % % \begin{macro}{\@show@DeclareRobustCommand} % \begin{macro}{\show@kernel@robust@command} +% \begin{macro}{\@show@macro} % Showing the command is pretty simple. This command prints the top-level % expansion as \TeX's \cs{show} would, but with |robust macro:| rather than % just |macro:|, then a blank line and then \cs{show} the inner command. @@ -1863,12 +1927,14 @@ \robust@command@chk@safe#1% {\@if@newcommand#1% {\@show@newcommand}% - {\show}}% - {\show}% + {\@show@macro}}% + {\@show@macro}% #1} +\let\@show@macro\show % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \end{macro} % @@ -1931,7 +1997,7 @@ \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}% \expandafter\@show@newcommand@aux \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname - \expandafter{#1}} + \expandafter{#1}\@show@tokens} % \end{macrocode} % % For a macro defined with, say, |\newcommand\foo[1][opt]{bar}|, it will @@ -1946,20 +2012,28 @@ % \end{verbatim} % If the command was defined with \cs{DeclareRobustCommand}, then another pair % of lines show the top-level expansion \verb*|\protect \foo |. -% -% The extra gymnastics with \cs{showtokens} ensures that \cs{showtokens} -% itself, and the internals of this macro aren't showed in the context lines. % \begin{macrocode} -\long\def\@show@newcommand@aux#1#2{% +\long\def\@show@newcommand@aux#1#2#3{% \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:}% - \edef\reserved@a{% - default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% - \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}% - \showtokens\expandafter\expandafter\expandafter{\expandafter\reserved@a}} + #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% + \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}} % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\@show@tokens} +% This macro prints the contents of the token list (macro) |#1| using +% \cs{showtokens}. The \cs{expandafter} gymnastics ensures that +% \cs{showtokens} itself, and the internals of this macro aren't +% showed in the context lines. +% \begin{macrocode} +\long\def\@show@tokens#1{% + \edef\reserved@a{#1}% + \showtokens\expandafter + \expandafter\expandafter{\expandafter\reserved@a}} +% \end{macrocode} +% \end{macro} +% % Now the rollback code. % \begin{macrocode} % @@ -1985,6 +2059,124 @@ % \end{macro} % % +% \subsubsection{Showing environments} +% +% \begin{macro}{\ShowEnvironment} +% \changes{v1.5s}{2022/11/24}{Added \cs{ShowEnvironment}} +% +% \begin{macrocode} +% +%\IncludeInRelease{2023-06-01}{\ShowEnvironment} +% {Add \ShowEnvironment}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \cs{ShowEnvironment} is quite similar to \cs{ShowCommand}. We will +% pass the environment \meta{env} around as the macro +% \cs[no-index]{env}, because \cs{robust@command@act} expects a single +% token. +% \begin{macrocode} +\def\ShowEnvironment#1{% + \expandafter\@show@environment\csname #1\endcsname} +\long\def\@show@environment#1{% + \robust@command@act + \@showenvironmentlisthook#1% + \@show@normalenv#1} +% \end{macrocode} +% +% \begin{macro}{\@showenvironmentlisthook} +% This is similar to \cs{@showcommandlisthook}, but uses the dedicated +% versions for environments. +% \begin{macrocode} +\def\@showenvironmentlisthook{% + {\@if@DeclareRobustCommand \@show@DeclareRobustCommand@env}% + {\@if@newcommand \@show@newcommand@env}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@show@newcommand@env} +% \begin{macro}{\@show@DeclareRobustCommand@env} +% These are similar to the command versions below, except they say +% \enquote{environment} and call \cs{@show@environment@end} to print +% the \cs{end} part. +% \begin{macrocode} +\long\def\@show@newcommand@env#1{% + \@show@environment@begin#1% + \expandafter\@show@newcommand@aux + \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname + \expandafter{#1}\@show@typeout + \@show@environment@end#1} +\long\def\@show@DeclareRobustCommand@env#1{% + \@show@environment@begin#1% + \begingroup + \let\@show@tokens\@show@typeout + \let\@show@macro\@show@nonstop + \expandafter\show@kernel@robust@command + \csname\@expl@cs@to@str@@N#1 \endcsname + \endgroup + \@show@environment@end#1} +\long\def\@show@environment@begin#1{% + \typeout{> \string\begin{\@expl@cs@to@str@@N#1}=environment:}% + \typeout{\@expl@cs@argument@spec@@N#1->% + \@expl@cs@replacement@spec@@N#1.^^J}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@show@normalenv} +% \begin{macro}{\@show@environment@end} +% A \enquote{normal} environment is straightforward. +% \cs{@show@environment@end} needs to check if the \cs{end} part is +% defined and show it accordingly, otherwise the output would show +% gibberish. +% \begin{macrocode} +\long\def\@show@normalenv#1{% + \@show@environment@begin#1% + \@show@environment@end#1} +\long\def\@show@environment@end#1{% + \expandafter\@show@environment@end@aux + \csname end\@expl@cs@to@str@@N#1\endcsname#1} +\long\def\@show@environment@end@aux#1#2{% + \@show@tokens{\string\end{\@expl@cs@to@str@@N#2}% + \ifx\relax#1=undefined% + \else:^^J\@expl@cs@argument@spec@@N#1->% + \@expl@cs@replacement@spec@@N#1% + \fi}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@show@nonstop} +% \begin{macro}{\@show@typeout} +% And here some auxiliaries: +% \begin{description} +% \item[\cs{@show@nonstop}] same output as \cs{show}, but doesn't +% stop for interaction; +% \item[\cs{@show@typeout}] same output as \cs{showtokens}, but +% doesn't stop for interaction. +% \end{description} +% \begin{macrocode} +\def\@show@nonstop#1{% + \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:^^J% + \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1.}} +\def\@show@typeout#1{\typeout{> #1.^^J}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Now the rollback code. +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000-00-00}{\ShowEnvironment} +% {Undefine \ShowEnvironment}% +%\let\ShowEnvironment\@undefined +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% % \subsection{Internal defining commands} % % These commands are used internally to define other \LaTeX{} diff --git a/Master/texmf-dist/source/latex/base/ltdirchk.dtx b/Master/texmf-dist/source/latex/base/ltdirchk.dtx index 16a2ed9e681..6e029297544 100644 --- a/Master/texmf-dist/source/latex/base/ltdirchk.dtx +++ b/Master/texmf-dist/source/latex/base/ltdirchk.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/lterror.dtx b/Master/texmf-dist/source/latex/base/lterror.dtx index b302a9a74c0..77672168ce1 100644 --- a/Master/texmf-dist/source/latex/base/lterror.dtx +++ b/Master/texmf-dist/source/latex/base/lterror.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltexpl.dtx b/Master/texmf-dist/source/latex/base/ltexpl.dtx index aab189bec28..92e6de52cb6 100644 --- a/Master/texmf-dist/source/latex/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex/base/ltexpl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfilehook.dtx b/Master/texmf-dist/source/latex/base/ltfilehook.dtx index c8503de8916..e10a5416e58 100644 --- a/Master/texmf-dist/source/latex/base/ltfilehook.dtx +++ b/Master/texmf-dist/source/latex/base/ltfilehook.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2020-2022 -% Frank Mittelbach, Phelype Oleinik & LaTeX Team +% Copyright (C) 2020-2023 +% Frank Mittelbach, Phelype Oleinik and The LaTeX Project % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: ltfilehook.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v1.0n} -\providecommand\ltfilehookdate{2022/08/18} +\providecommand\ltfilehookversion{v1.0o} +\providecommand\ltfilehookdate{2023/04/02} % \end{macrocode} % %<*driver> @@ -1229,8 +1229,10 @@ % This auxiliary compares \cs{\meta{filename}} with % \cs{csname\cs{endcsname}} to check if the empty |.tex| file was % requested. +% \changes{v1.0o}{2023/04/02} +% {Make \cs{@set@curr@file@aux} \cs{long} gh/942} % \begin{macrocode} -\def\@set@curr@file@aux#1{% +\long\def\@set@curr@file@aux#1{% \expandafter\ifx\csname\endcsname#1% .tex\else\string#1\fi} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltfiles.dtx b/Master/texmf-dist/source/latex/base/ltfiles.dtx index d99dfdcd48f..3bac7ea0b22 100644 --- a/Master/texmf-dist/source/latex/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex/base/ltfiles.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2022/05/27 v1.2r LaTeX Kernel (File Handling)] + [2023/05/17 v1.2t LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -417,6 +417,16 @@ \ignorespaces} % \end{macrocode} % +% Provide a global definition for \cs{do} as well, so that it is +% already defined in the preamble and not late as +% \verb=\begin{document}= overwriting some definition given by the +% unsuspecting user in the preamble. +% \changes{v1.2s}{2023/01/05}{\cs{do} now with default definition in +% the kernel (gh/975)} +% \begin{macrocode} +\let\do\noexpand +% \end{macrocode} +% % The \hook{begindocument} hook already existed in the kernel since % 1994 under the name \cs{atbegindocumenthook} the % additional ones are originally from the \pkg{etoolbox} @@ -1192,6 +1202,9 @@ % \changes{v1.0t}{1995/05/25}{(CAR) added \cs{long}} % \changes{v1.2d}{2019/10/26}{quote on openin} % \changes{v1.2k}{2021/03/12}{Allow unbalanced conditionals (gh/530)} +% \changes{v1.2t}{2023/05/15}{Use \pkg{expl3} file existence test} +% \begin{macro}{\IfFileExists@} +% \changes{v1.2t}{2023/05/15}{Macro added} % Argument |#1| is |\@curr@file| so catcode 12 string with no quotes. % % The original definition picked up arguments |#2| and |#3| in a @@ -1201,23 +1214,35 @@ % \cs{secondoftwo}. However, that changes how |#| is interpreted % and so we can't do that nowaways without invalidating a lot of % code. Therefore the somewhat curious construction near the end. +% +% Earlier versions used |\openin| here, but this led to two +% code paths, one in \pkg{expl3} and one here. To avoid that, +% and as the \pkg{expl3} approach works by expansion, we use +% that here. As we need the file name to include the path, +% the actual \pkg{expl3} function used is not the file existence +% test! % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2021/06/01}% -% {\IfFileExists@}{manage unbalanced conditionals} +%\IncludeInRelease{2023/05/01}% +% {\IfFileExists@}{IfFileExists} \long\def \IfFileExists@#1#2#3{% - \openin\@inputcheck"#1" % - \ifeof\@inputcheck - \ifx\input@path\@undefined - \let\reserved@a\@secondoftwo + \edef\@filef@und{\IfFileExists@@{#1}}% +% \end{macrocode} +% The \pkg{expl3} function regards an empty argument as nothing at all, +% but the \LaTeXe{} convention is that this is equal to the special +% \texttt{.tex} file. +% \begin{macrocode} + \ifx\@filef@und\@empty + \if\relax\detokenize{#1}\relax + \let\reserved@a\@firstoftwo + \def\@filef@und{".tex" }% \else - \def\reserved@a{\@iffileonpath{#1}}% + \let\reserved@a\@secondoftwo \fi \else - \closein\@inputcheck - \edef\@filef@und{"#1" }% \let\reserved@a\@firstoftwo + \edef\@filef@und{"\@filef@und" }% \fi % \end{macrocode} % This is just there so that any |#| inside |#2| or |#3| needs @@ -1226,10 +1251,35 @@ \expandafter\def\expandafter\reserved@a \expandafter{\reserved@a{#2}{#3}}% \reserved@a} +\ExplSyntaxOn +\cs_new_eq:NN \IfFileExists@@ \file_full_name:n +\ExplSyntaxOff % %\EndIncludeInRelease +%\IncludeInRelease{2021/06/01}% +% {\IfFileExists@}{IfFileExists} +% +%\long\def \IfFileExists@#1#2#3{% +% \openin\@inputcheck"#1" % +% \ifeof\@inputcheck +% \ifx\input@path\@undefined +% \let\reserved@a\@secondoftwo +% \else +% \def\reserved@a{\@iffileonpath{#1}}% +% \fi +% \else +% \closein\@inputcheck +% \edef\@filef@und{"#1" }% +% \let\reserved@a\@firstoftwo +% \fi +% \expandafter\def\expandafter\reserved@a +% \expandafter{\reserved@a{#2}{#3}}% +%\reserved@a} +%\let\IfFileExists@@\@undefined +%\EndIncludeInRelease +% %\IncludeInRelease{2019/10/01}% -% {\IfFileExists@}{manage unbalanced conditionals} +% {\IfFileExists@}{IfFileExists} % %\long\def \IfFileExists@#1#2#3{% % \openin\@inputcheck"#1" % @@ -1247,7 +1297,7 @@ % \reserved@a} %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\IfFileExists@}{manage unbalanced conditionals} +% {\IfFileExists@}{IfFileExists} % %\let\IfFileExists@\@undefined % @@ -1256,7 +1306,7 @@ %<*2ekernel> % \end{macrocode} % \end{macro} -% +% \end{macro} % % % diff --git a/Master/texmf-dist/source/latex/base/ltfinal.dtx b/Master/texmf-dist/source/latex/base/ltfinal.dtx index a19ffa83052..2652f6ce44e 100644 --- a/Master/texmf-dist/source/latex/base/ltfinal.dtx +++ b/Master/texmf-dist/source/latex/base/ltfinal.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2022/11/30 v2.2y LaTeX Kernel (Final Settings)] + [2023/05/30 v2.3c LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -1062,6 +1062,24 @@ \fi % End of reset block for 8-bit engines % \end{macrocode} % +% \begin{macro}{\BCPdata} +% \changes{v2.3a}{2023/04/16}{Command added} +% A stub for use by \pkg{babel}, \pkg{polyglossia}, etc. +% \begin{macrocode} +\ExplSyntaxOn +\newcommand*\BCPdata[1]{ + \str_case:nn {#1} + { + { language } { en } + { region } { US } + { script } { Latn } + { tag } { en-US } + } +} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\MakeUppercase} % \begin{macro}{\MakeLowercase} % \begin{macro}{\MakeTitlecase} @@ -1069,6 +1087,9 @@ % \begin{macro}{\AddToNoCaseChangeList} % \begin{macro}{\CaseSwitch} % \begin{macro}{\DeclareCaseChangeEquivalent} +% \begin{macro}{\DeclareLowercaseMapping} +% \begin{macro}{\DeclareTitlecaseMapping} +% \begin{macro}{\DeclareUppercaseMapping} % \begin{macro}{\@uclclist} % % @@ -1088,6 +1109,7 @@ % \changes{v2.2x}{2022/10/26}{Introduce optional argument for case-changing commands} % \changes{v2.2x}{2022/10/26}{Make case changing commands language-aware} % \changes{v2.2x}{2022/10/26}{Auto-detect \pkg{babel} locale} +% \changes{v2.3a}{2023/04/11}{Use new generic mechanism to detect locale} % Wrappers around the L3 case changing functions. % |\protected| to make them mostly safe as replacements for |uppercase| % and |\lowercase|. @@ -1121,33 +1143,24 @@ { \cs_set_nopar:Npn \reserved@a { } \tl_if_blank:nTF {#2} - { \@@text@case@aux@ } - { \keys_set:nn { __kernel } {#2} } - \use:c { text_ #1 case:Vn } \reserved@a {#3} - } -\cs_new_protected:Npn \@@text@case@aux@ { } -\tl_gput_right:Nn \@kernel@after@begindocument - { - \@ifpackageloaded { babel } { - \@ifpackagelater { babel } { 2020-01-15 } + \str_set:Nx \reserved@a + { \BCPdata { casing } } + \str_if_empty:NT \reserved@a { - \cs_gset_protected:Npn \@@text@case@aux@ - { - \str_set:Nx \reserved@a - { \localeinfo* { tag.bcp47 } } - } + \str_set:Nx \reserved@a + { \BCPdata { language } } } - { } } - { } + { \keys_set:nn { __kernel } {#2} } + \use:c { text_ #1 case:Vn } \reserved@a {#3} } -\exp_args_generate:n { cnx } % \end{macrocode} % The odd use of \emph{three} spaces here is needed as \pkg{ltcmd} uses the % name with one and two spaces to give a `friendly' error message for a runaway % argument: that means we can't use it here. % \begin{macrocode} +\exp_args_generate:n { cnx } \cs_set_protected:Npn \reserved@a #1 { \cs_generate_variant:cn { text_ \str_lowercase:n {#1} case:nn } { V } @@ -1161,36 +1174,35 @@ \reserved@a { Title } % \end{macrocode} % \changes{v2.2y}{2022/11/30}{Set \cs{oe}/\cs{OE} equal to act as a marker for \pkg{babel}} +% \changes{v2.2z}{2023/03/28}{Use groups for gh/1021} % Currently, \pkg{babel} uses the equivalence of \cs{oe} and \cs{OE} to force casing of % some material, most notably in \cs{today}. To enable that to work, we have to set those % commands equal even though the current case changing code does not work using this % approach. % \begin{macrocode} \cs_new_protected:cpn { MakeLowercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@OE \OE + {{ \let \OE \oe \@@text@case@aux { lower } {#1} {#2} - \let \OE \kernel@saved@OE - } + }} \cs_new_protected:cpn { MakeUppercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@oe \oe + {{ \let \oe \OE \@@text@case@aux { upper } {#1} {#2} - \let \oe \kernel@saved@oe - } + }} \cs_new_protected:cpn { MakeTitlecase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@oe \oe + {{ \let \oe \OE \@@text@case@aux { title } {#1} {#2} - \let \oe \kernel@saved@oe - } + }} % \end{macrocode} % % \changes{v2.2u}{2022/06/02}{Add \cs{NoCaseChange}} % \changes{v2.2u}{2022/06/30}{Add \cs{AddToNoCaseChangeList}} +% \changes{v2.3b}{2023/04/19}{Add \cs{DeclareLowercaseMapping}, +% \cs{DeclareTitlecaseMapping} and \cs{DeclareUppercaseMapping}} +% \changes{v2.3c}{2023/05/30}{Fix a typo in implementation of +% \cs{DeclareLowercaseMapping}, etc.} % |\NoCaseChange| protects its argument from the case change functions. % % |\AddToNoCaseChangeList| Allows new commands to protect their arguments, eg @@ -1204,6 +1216,27 @@ \cs_new_eq:NN \CaseSwitch \text_case_switch:nnnn \cs_new_eq:NN \DeclareCaseChangeEquivalent \text_declare_case_equivalent:Nn +\NewDocumentCommand \DeclareLowercaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_lowercase_mapping:nn } + { \text_declare_lowercase_mapping:nnn {#1} } + {#2} {#3} + } +\NewDocumentCommand \DeclareTitlecaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_titlecase_mapping:nn } + { \text_declare_titlecase_mapping:nnn {#1} } + {#2} {#3} + } +\NewDocumentCommand \DeclareUppercaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_uppercase_mapping:nn } + { \text_declare_uppercase_mapping:nnn {#1} } + {#2} {#3} + } \ExplSyntaxOff % \end{macrocode} % @@ -1222,6 +1255,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \changes{v1.0h}{1994/05/13}{Added output enc stuff} % \changes{v1.0i}{1994/05/16}{moved output enc stuff to lfonts} diff --git a/Master/texmf-dist/source/latex/base/ltfloat.dtx b/Master/texmf-dist/source/latex/base/ltfloat.dtx index 8b5b92759a2..72478245483 100644 --- a/Master/texmf-dist/source/latex/base/ltfloat.dtx +++ b/Master/texmf-dist/source/latex/base/ltfloat.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx index 64064abcb53..bb6dbfe75ca 100644 --- a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx index 843e8b544c5..9e68b38654e 100644 --- a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfssbas.dtx b/Master/texmf-dist/source/latex/base/ltfssbas.dtx index cc43622a4bc..fda3d1ca4b0 100644 --- a/Master/texmf-dist/source/latex/base/ltfssbas.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssbas.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2022/07/04 v3.2k LaTeX Kernel (NFSS Basic Macros)] + [2023/04/01 v3.2l LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -1050,11 +1050,22 @@ % {\cs{def} $\to$ \cs{edef} for \cs{math@version}.} % \changes{v1.2g}{1990/02/16}{\cs{@nomath} added.} % \changes{v2.1a}{1994/01/17}{New math font setup} +% \changes{v3.2l}{2023/04/01}{Reset frozen mathversion gh/1028} % \begin{macrocode} \DeclareRobustCommand\mathversion[1] {\@nomath\mathversion \expandafter\ifx\csname mv@#1\endcsname\relax \@latex@error{Math version `#1' is not defined}\@eha\else +% \end{macrocode} +% If there has been a frozen math version reset locally. See GH 1028. +% \begin{macrocode} + \ifcsname mv@\math@version @frozen\endcsname + \expandafter\let + \csname mv@\math@version @frozen\expandafter\endcsname + \csname mv@\math@version\endcsname + \fi +% \end{macrocode} +% \begin{macrocode} \edef\math@version{#1}% % \end{macrocode} % We need to force a math font setup both now and at the point diff --git a/Master/texmf-dist/source/latex/base/ltfsscmp.dtx b/Master/texmf-dist/source/latex/base/ltfsscmp.dtx index 09f43a0d941..7bdfe2fd3ee 100644 --- a/Master/texmf-dist/source/latex/base/ltfsscmp.dtx +++ b/Master/texmf-dist/source/latex/base/ltfsscmp.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfssdcl.dtx b/Master/texmf-dist/source/latex/base/ltfssdcl.dtx index 49041605e99..c3a743d249d 100644 --- a/Master/texmf-dist/source/latex/base/ltfssdcl.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssdcl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfssini.dtx b/Master/texmf-dist/source/latex/base/ltfssini.dtx index 12e3b6289be..7b43f0228b7 100644 --- a/Master/texmf-dist/source/latex/base/ltfssini.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssini.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx index 699fd2c5943..be0e6c68cf6 100644 --- a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx +++ b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/lthooks.dtx b/Master/texmf-dist/source/latex/base/lthooks.dtx index cfa1454775d..3807d25c44b 100644 --- a/Master/texmf-dist/source/latex/base/lthooks.dtx +++ b/Master/texmf-dist/source/latex/base/lthooks.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2020-2022 -% Frank Mittelbach, Phelype Oleinik & LaTeX Team +% Copyright (C) 2020-2023 +% Frank Mittelbach, Phelype Oleinik, The LaTeX Project % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: lthooks.dtx % % \begin{macrocode} -\def\lthooksversion{v1.0v} -\def\lthooksdate{2022/06/15} +\def\lthooksversion{v1.1e} +\def\lthooksdate{2023/06/06} % \end{macrocode} % %<*driver> @@ -148,7 +148,6 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % -% % \begin{function}{\NewMirroredHookPair} % \begin{syntax} % \cs{NewMirroredHookPair} \Arg{hook-1} \Arg{hook-2} @@ -156,7 +155,45 @@ % A shorthand for % \cs{NewHook}\Arg{hook-1}\cs{NewReversedHook}\Arg{hook-2}. % -% The \meta{hooks} can be specified using the dot-syntax to denote +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% +% \begin{function}{\NewHookWithArguments} +% \begin{syntax} +% \cs{NewHookWithArguments} \Arg{hook} \Arg{number} +% \end{syntax} +% Creates a new \meta{hook} whose code takes \meta{number} arguments, +% and otherwise works exactly like \cs{NewHook}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\NewReversedHookWithArguments} +% \begin{syntax} +% \cs{NewReversedHookWithArguments} \Arg{hook} \Arg{number} +% \end{syntax} +% Like \cs{NewReversedHook}, but creates a hook whose code takes +% \meta{number} arguments. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\NewMirroredHookPairWithArguments} +% \begin{syntax} +% \cs{NewMirroredHookPairWithArguments} \Arg{hook-1} \Arg{hook-2} \Arg{number} +% \end{syntax} +% A shorthand for +% \cs{NewHookWithArguments}\Arg{hook-1}\Arg{number}\\ +% \cs{NewReversedHookWithArguments}\Arg{hook-2}\Arg{number}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote % the current package name. See section~\ref{sec:default-label}. % \end{function} % @@ -173,9 +210,9 @@ % \begin{syntax} % \cs{DisableGenericHook} \Arg{hook} % \end{syntax} -% After this declaration\footnotemark{} the \meta{hook} is no longer usable: Any -% attempt to add further code to it will result in an error and any -% use, e.g., via \cs{UseHook}, will simply do nothing. +% After this declaration\footnotemark{} the \meta{hook} is no longer +% usable: Any further attempt to add code to it will result in an +% error and any use, e.g., via \cs{UseHook}, will simply do nothing. % % This is intended to be used with generic command hooks (see % \texttt{ltcmdhooks-doc}) as depending on the definition of the @@ -215,7 +252,7 @@ % \begin{syntax} % \cs{UseHook} \Arg{hook} % \end{syntax} -% Execute the hook code inside a command or environment. +% Execute the code stored in the \meta{hook}. % % Before \verb=\begin{document}= the fast execution code for a hook % is not set up, so in order to use a hook there it is explicitly @@ -227,14 +264,30 @@ % A leading |.| is treated literally. % \end{function} % +% \begin{function}{\UseHookWithArguments} +% \begin{syntax} +% \cs{UseHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} +% \end{syntax} +% Execute the code stored in the \meta{hook} and pass the arguments +% \Arg{arg_1} through \Arg{arg_n} to the \meta{hook}. Otherwise, it +% works exactly like \cs{UseHook}. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% % \begin{function}{\UseOneTimeHook} % \begin{syntax} % \cs{UseOneTimeHook} \Arg{hook} % \end{syntax} % Some hooks are only used (and can be only used) in one place, for % example, those in \verb=\begin{document}= or -% \verb=\end{document}=. Once we have passed that point adding to -% the hook through a defined \cs[no-index]{\meta{addto-cmd}} command (e.g., +% \verb=\end{document}=. From that point onwards, adding to the hook +% through a defined \cs[no-index]{\meta{addto-cmd}} command (e.g., % \cs{AddToHook} or \cs{AtBeginDocument}, etc.\@) would have no % effect (as would the use of such a command inside the hook code % itself). It is therefore customary to redefine @@ -250,15 +303,30 @@ % section~\ref{sec:default-label} for details. % % Using \cs{UseOneTimeHook} several times with the same -% \Arg{hook} means that it only executes the first time it is used. +% \Arg{hook} means that it only executes the first time it is used. % For example, if it is used in a command that can be called several times -% then the hook executes during only the \emph{first} invocation of that +% then the hook executes during only the \emph{first} invocation of that % command; this allows its use as an \enquote{initialization hook}. % % Mixing \cs{UseHook} and \cs{UseOneTimeHook} for the same % \Arg{hook} should be avoided, but if this is done then neither will execute % after the first \cs{UseOneTimeHook}. +% \end{function} % +% \begin{function}{\UseOneTimeHookWithArguments} +% \begin{syntax} +% \cs{UseOneTimeHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} +% \end{syntax} +% Works exactly like \cs{UseOneTimeHook}, but passes arguments +% \Arg{arg_1} through \Arg{arg_n} to the \meta{hook}. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. +% +% It should be noted that after a one-time hook is used, it is no +% longer possible to use \cs{AddToHookWithArguments} or similar with +% that hook. \cs{AddToHook} continues to work as normal. +% Section~\ref{sec:hook-args} explains hooks with arguments. % \end{function} % % @@ -294,6 +362,34 @@ % See section~\ref{sec:default-label}. % \end{function} % +% \begin{function}{\AddToHookWithArguments} +% \begin{syntax} +% \cs{AddToHookWithArguments} \Arg{hook}\oarg{label}\Arg{code} +% \end{syntax} +% Works exactly like \cs{AddToHook}, except that the \meta{code} can +% access the arguments passed to the hook using \verb|#1|, \verb|#2|, +% \ldots, \verb|#n| (up to the number of arguments declared for the +% hook). If the \meta{code} should contain \emph{parameter tokens} +% (\verb|#|) that are not supposed to be understood as the arguments +% of the hook, such tokens should be doubled. For example, with +% \cs{AddToHook} one can write: +%\begin{verbatim} +% \AddToHook{myhook}{\def\foo#1{Hello, #1!}} +%\end{verbatim} +% but to achieve the same with \cs{AddToHookWithArguments}, one should +% write: +%\begin{verbatim} +% \AddToHookWithArguments{myhook}{\def\foo##1{Hello, ##1!}} +%\end{verbatim} +% because in the latter case, \verb|#1| refers to the first argument +% of the hook \hook{myhook}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% % \begin{function}{\RemoveFromHook} % \begin{syntax} % \cs{RemoveFromHook} \Arg{hook}\oarg{label} @@ -403,6 +499,19 @@ % \end{function}\footnotetext{There is % no mechanism to reorder such code chunks (or delete them).} % +% \begin{function}{\AddToHookNextWithArguments} +% \begin{syntax} +% \cs{AddToHookNextWithArguments} \Arg{hook}\Arg{code} +% \end{syntax} +% Works exactly like \cs{AddToHookNext}, but the \meta{code} can +% contain references to the arguments of the \meta{hook} as described +% for \cs{AddToHookWithArguments} above. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% % % % \begin{function}{\ClearHookNext} @@ -511,10 +620,10 @@ % package's hooks, so the dot-syntax doesn't make much sense. % % 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 +% the code in logical parts, but still use the main package name as the % \meta{label}, then the \meta{default label} can be set using -% \cs{SetDefaultHookLabel} or -% \cs{PushDefaultHookLabel}\verb={..}=\,\ldots\cs{PopDefaultHookLabel}. +% \cs{PushDefaultHookLabel}\verb={...}=\,\ldots\cs{PopDefaultHookLabel} +% or \cs{SetDefaultHookLabel}\verb={...}=. % % \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel} % \begin{syntax} @@ -906,8 +1015,11 @@ % section even in \texttt{expl3} packages, but the choice is yours. % % -% \begin{function} -% {\hook_new:n,\hook_new_reversed:n,\hook_new_pair:nn} +% \begin{function}{ +% \hook_new:n, +% \hook_new_reversed:n, +% \hook_new_pair:nn +% } % \begin{syntax} % \cs{hook_new:n} \Arg{hook} % \cs{hook_new_reversed:n} \Arg{hook} @@ -923,6 +1035,27 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % +% \begin{function}{ +% \hook_new_with_args:nn, +% \hook_new_reversed_with_args:nn, +% \hook_new_pair_with_args:nnn +% } +% \begin{syntax} +% \cs{hook_new_with_args:nn} \Arg{hook} \Arg{number} +% \cs{hook_new_reversed_with_args:nn} \Arg{hook} \Arg{number} +% \cs{hook_new_pair_with_args:nnn} \Arg{hook-1} \Arg{hook-2} \Arg{number} +% \end{syntax} +% Creates a new \meta{hook} with normal or reverse ordering of code +% chunks, that takes \meta{number} arguments from the input stream +% when it is used. \cs{hook_new_pair_with_args:nn} creates a pair of +% such hooks with \Arg{hook-2} being a reversed hook. +% If a hook name is already taken, an error is raised and the hook +% is not created. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% % % % \begin{function}{\hook_disable_generic:n} @@ -958,37 +1091,62 @@ % % % -% \begin{function}{\hook_use:n} +% \begin{function}{\hook_use:n,\hook_use:nnw} % \begin{syntax} % \cs{hook_use:n} \Arg{hook} +% \cs{hook_use:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % Executes the \Arg{hook} code followed (if set up) by the code for next % invocation only, then empties that next invocation code. +% \cs{hook_use:nnw} should be used for hooks declared with arguments, +% and should be followed by as many brace groups as the declared +% number of arguments. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\hook_use_once:n} +% \begin{function}{\hook_use_once:n,\hook_use_once:nnw} % \begin{syntax} % \cs{hook_use_once:n} \Arg{hook} +% \cs{hook_use_once:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % 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. +% \cs{hook_use_once:nnw} should be used for hooks declared with arguments, +% and should be followed by as many brace groups as the declared +% number of arguments. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\hook_gput_code:nnn} +% \begin{function}{ +% \hook_gput_code:nnn, +% \hook_gput_code_with_args:nnn +% } % \begin{syntax} % \cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code} +% \cs{hook_gput_code_with_args:nnn} \Arg{hook} \Arg{label} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} to the \meta{hook} labeled % \meta{label}. If the label already exists the \meta{code} is % appended to the already existing code. % +% If \cs{hook_gput_code_with_args:nnn} is used, the \meta{code} +% can access the arguments passed to \cs{hook_use:nnw} +% (or~\cs{hook_use_once:nnw}) with \verb|#1|, \verb|#2|, \ldots, +% \verb|#n| (up to the number of arguments declared for the hook). +% In that case, if an actual parameter token should be added to the +% code, it should be doubled. +% % If code is added to an external \meta{hook} (of the kernel or % another package) then the convention is to use the package name % as the \meta{label} not some internal module name or some other @@ -999,18 +1157,26 @@ % See section~\ref{sec:default-label}. % \end{function} % -% \begin{function} -% {\hook_gput_next_code:nn} +% \begin{function}{ +% \hook_gput_next_code:nn, +% \hook_gput_next_code_with_args:nn, +% } % \begin{syntax} % \cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} for use only in the next invocation of the % \meta{hook}. Once used it is gone. % +% If \cs{hook_gput_next_code_with_args:nn} is used, the \meta{code} +% can access the arguments passed to \cs{hook_use:nnw} +% (or~\cs{hook_use_once:nnw}) with \verb|#1|, \verb|#2|, \ldots, +% \verb|#n| (up to the number of arguments declared for the hook). +% In that case, if an actual parameter token should be added to the +% code, it should be doubled. +% % This is simpler than \cs{hook_gput_code:nnn}, the code is simply % appended to the hook in the order of declaration at the very end, % i.e., after all standard code for the hook got executed. -% % Thus if one needs to undo what the standard does one has to do % that as part of \meta{code}. % @@ -1019,8 +1185,7 @@ % \end{function} % % -% \begin{function} -% {\hook_gclear_next_code:n} +% \begin{function}{\hook_gclear_next_code:n} % \begin{syntax} % \cs{hook_gclear_next_code:n} \Arg{hook} % \end{syntax} @@ -1240,7 +1405,7 @@ % \begin{itshape}\begin{color}{blue} ... % \end{itshape}\end{color} %\end{verbatim} -% and an error message that \verb=\begin{color}= ended by +% and an error message saying that \verb=\begin{color}= was ended by % \verb=\end{itshape}=. % With \hook{env/quote/after} declared as a reversed hook the % execution order is reversed and so all environments are closed in @@ -1377,9 +1542,9 @@ % you typically do not know what kind of variable parts may come up % in real documents. % -% For example, \pkg{babel} may want to provide hooks such as -% \hook{babel/\meta{language}/afterextras}. Language support in -% \pkg{babel} is often done through external language +% For example, \pkg{babel} provides hooks such as +% \hook{babel/\meta{language}/afterextras}. However, language +% support in \pkg{babel} is often done through external language % packages. Thus doing the activation for all languages inside the % core \pkg{babel} code is not a viable approach. Instead it needs % to be done by each language package (or by the user who wants to @@ -1396,6 +1561,125 @@ % conciderably. % % +% \subsection{Hooks with arguments} +% \label{sec:hook-args} +% +% Sometimes it is necessary to pass contextual information to a hook, +% and, for one reason or another, it is not feasible to store such +% information in macros. To serve this purpose, hooks can be +% declared with arguments, so that the programmer can pass along the +% data necessary for the code in the hook to function properly. +% +% A hook with arguments works mostly like a regular hook, and most +% commands that work for regular hooks, also work for hooks that take +% arguments. The differences are when the hook is declared +% (\cs{NewHookWithArguments} is used instead of \cs{NewHook}), then +% code can be added with both \cs{AddToHook} and +% \cs{AddToHookWithArguments}, and when the hook is used +% (\cs{UseHookWithArguments} instead of \cs{UseHook}). +% +% \medskip +% +% A hook with arguments must be declared as such (before it is first +% used, as all regular hooks) using +% \cs{NewHookWithArguments}\Arg{hook}\Arg{number}. All code added to +% that hook can then use \verb|#1| to access the first argument, +% \verb|#2| to access the second, and so forth up to the number of +% arguments declared. However, it is still possible to add code with +% references to the arguments of a hook that was not yet declared +% (we will discuss that later). At their core, hooks are macros, so +% \TeX's limit of 9~arguments applies, and a low-level \TeX{} error +% is raised if you try to reference an argument number that doesn't +% exist. +% +% \medskip +% +% To use a hook with arguments, just write +% \cs{UseHookWithArguments}\Arg{hook}\Arg{number} followed by a +% braced list of the arguments. For example, if the hook \hook{test} +% takes three arguments, write: +%\begin{verbatim} +% \UseHookWithArguments{test}{3}{arg-1}{arg-2}{arg-3} +%\end{verbatim} +% then, in the \meta{code} of the hook, all instances of \verb|#1| +% will be replaced by \verb|arg-1|, \verb|#2| by \verb|arg-2| and so +% on. If, at the point of usage, the programmer provides more +% arguments than the hook is declared to take, the excess arguments +% are simply ignored by the hook. Behaviour is +% unpredictable\footnote +% {The hook \emph{will} take the declared number of arguments, and +% what will happen depends on what was grabbed, and what the hook +% code does with its arguments.} +% if too few arguments are provided. If the hook isn't declared, +% \meta{number} arguments are removed from the input stream. +% +% \medskip +% +% Adding code to a hook with arguments can be done with +% \cs{AddToHookWithArguments} as well as with the regular +% \cs{AddToHook}, to achieve different outcomes. The main difference +% when it comes to adding code to a hook, in this case, is firstly +% the possibility of accessing a hook's arguments, of course, and +% second, how parameter tokens (\verb|#|$_6$) are treated. +% +% Using \cs{AddToHook} in a hook that takes arguments will work as it +% does for all other hooks. This allows a package developer to add +% arguments to a hook that otherwise had none without having to worry +% about compatibility. This means that, for example: +%\begin{verbatim} +% \AddToHook{test}{\def\foo#1{Hello, #1!}} +%\end{verbatim} +% will define the same macro \cs[no-index]{foo} regardless if the +% hook \hook{test} takes arguments or not. +% +% Using \cs{AddToHookWithArguments} allows the \meta{code} added to +% access the arguments of the hook with \verb|#1|, \verb|#2|, and so +% forth, up to the number of the arguments declared in the hook. +% This means that if one wants to add a \verb|#|$_6$ to the +% \meta{code} that token must be doubled in the input. The same +% definition from above, using \cs{AddToHookWithArguments}, needs to +% be rewritten: +%\begin{verbatim} +% \AddToHookWithArguments{test}{\def\foo##1{Hello, ##1!}} +%\end{verbatim} +% +% Extending the above example to use the hook arguments, we could +% rewrite something like (now from declaration to usage, to get the +% whole picture): +%\begin{verbatim} +% \NewHookWithArguments{test}{1} +% \AddToHookWithArguments{test}{% +% \typeout{Defining foo with "#1"} +% \def\foo##1{Hello, ##1! Some text after: #1}% +% } +% \UseHook{test}{Howdy!} +% \ShowCommand\foo +%\end{verbatim} +% Running the code above prints in the terminal: +%\begin{verbatim} +% Defining foo with "Howdy!" +% > \foo=macro: +% #1->Hello, #1! Some text after: Howdy!. +%\end{verbatim} +% Note how \verb|##1| in the call to \cs{AddToHookWithArguments} +% became \verb|#1|, and the \verb|#1| was replaced by the argument +% passed to the hook. Should the hook be used again, with a +% different argument, the definition would naturally change. +% +% \bigskip +% +% It is possible to add code referencing a hook's arguments before +% such hook is declared and the number of hooks is fixed. However, +% if some code is added to the hook, that references more arguments +% than will be declared for the hook, there will be a low-level +% \TeX{} error about an \enquote{Illegal parameter number} at the +% time the hook is declared, which will be hard to track down because +% at that point \TeX{} can't know whence the offending code came +% from. Thus it is important that package writers explicitly +% document how many arguments (if any) each hook can take, so users +% of those packages know how many arguments can be referenced, and +% equally important, what each argument means. +% % \subsection{Private \LaTeX{} kernel hooks} % % There are a few places where it is absolutely essential for @@ -1461,7 +1745,7 @@ % 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 +% This way one can add 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 another package's code. When using the @@ -1746,10 +2030,10 @@ % % \subsection{Hooks provided by \cs{end}\texttt{\{document\}}} % -% \LaTeXe{} always provided \cs{AtEndDocument} to add code to the -% execution of \verb=\end{document}= just in front of the code that +% \LaTeXe{} has always provided \cs{AtEndDocument} to add code to the +% \verb=\end{document}=, just in front of the code that % is normally executed there. While this was a big improvement over -% the situation in \LaTeX\,2.09 it was not flexible enough for a +% the situation in \LaTeX\,2.09, it was not flexible enough for a % number of use cases and so packages, such as \pkg{etoolbox}, % \pkg{atveryend} and others patched \cs{enddocument} to add % additional points where code could be hooked into. @@ -2095,13 +2379,37 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x} +% \begin{macro}{\c_@@_empty_tl} +% \begin{macro}{\c_@@_nine_parameters_tl} +% An empty token list, and one containing nine parameters. +% \changes{v1.1a}{2023/04/06} +% {Add auxiliary token lists (hook-args).} +% \begin{macrocode} +\tl_const:Nn \c_@@_empty_tl { } +\tl_const:Nn \c_@@_nine_parameters_tl { #1#2#3#4#5#6#7#8#9 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{ +% \tl_gremove_once:Nx, +% \tl_show:x, +% \tl_log:x, +% \tl_set:Ne, +% \cs_replacement_spec:c, +% \prop_put:Nne, +% \str_count:e +% } % Some variants of \pkg{expl3} functions. % \fmiinline{should probably be moved to expl3} % \begin{macrocode} \cs_generate_variant:Nn \tl_gremove_once:Nn { Nx } \cs_generate_variant:Nn \tl_show:n { x } \cs_generate_variant:Nn \tl_log:n { x } +\cs_generate_variant:Nn \tl_set:Nn { Ne } +\cs_generate_variant:Nn \cs_replacement_spec:N { c } +\cs_generate_variant:Nn \prop_put:Nnn { Nne } +\cs_generate_variant:Nn \str_count:n { e } % \end{macrocode} % \end{macro} % @@ -2112,15 +2420,20 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_clean_to_scan:w} +% \begin{macro}{ +% \@@_use_none_delimit_by_s_mark:w, +% \@@_use_i_delimit_by_s_mark:nw +% } % Removes tokens until the next \cs{s_@@_mark}. +% \changes{v1.1a}{2023/04/06} +% {Use standard naming scheme (hook-args).} % \begin{macrocode} -\cs_new:Npn \@@_clean_to_scan:w #1 \s_@@_mark { } +\cs_new:Npn \@@_use_none_delimit_by_s_mark:w #1 \s_@@_mark { } +\cs_new:Npn \@@_use_i_delimit_by_s_mark:nw #1 #2 \s_@@_mark {#1} % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_set:Nn,\@@_tl_set:Nx, -% \@@_tl_set:cn,\@@_tl_set:cx} +% \begin{macro}{\@@_tl_set:cn} % 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:} @@ -2130,44 +2443,43 @@ % copied because in \pkg{expl3} they use % \cs[no-index]{__kernel_tl_(g)set:Nx}, which is also patched by % \pkg{l3debug}. -% \changes{v1.0h}{2021/01/07}{Manually define some \pkg{l3tl} commands +% \changes{v1.0h}{2021/01/07}{Manually define some \pkg{l3tl} commands % to work around \pkg{expl3} changes} +% \changes{v1.1a}{2023/04/06} +% {Clean-up unused variants (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_tl_set:Nn #1#2 - { \cs_set_nopar:Npx #1 { \__kernel_exp_not:w {#2} } } -\cs_new_protected:Npn \@@_tl_set:Nx #1#2 - { \cs_set_nopar:Npx #1 {#2} } -\cs_generate_variant:Nn \@@_tl_set:Nn { c } -\cs_generate_variant:Nn \@@_tl_set:Nx { c } +\cs_new_protected:Npn \@@_tl_set:cn #1#2 + { \cs_set_nopar:cpx {#1} { \__kernel_exp_not:w {#2} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:No,\@@_tl_gset:Nx, +% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:Nx, % \@@_tl_gset:cn,\@@_tl_gset:co,\@@_tl_gset:cx} % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gset:Nn #1#2 { \cs_gset_nopar:Npx #1 { \__kernel_exp_not:w {#2} } } -\cs_new_protected:Npn \@@_tl_gset:No #1#2 - { \cs_gset_nopar:Npx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } } \cs_new_protected:Npn \@@_tl_gset:Nx #1#2 { \cs_gset_nopar:Npx #1 {#2} } -\cs_generate_variant:Nn \@@_tl_gset:Nn { c } -\cs_generate_variant:Nn \@@_tl_gset:No { c } +\cs_generate_variant:Nn \@@_tl_gset:Nn { c, co } \cs_generate_variant:Nn \@@_tl_gset:Nx { c } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gput_right:Nn,\@@_tl_gput_right:No,\@@_tl_gput_right:cn} +% \begin{macro}{ +% \@@_tl_gput_right:Nn, +% \@@_tl_gput_right:Ne, +% \@@_tl_gput_right:cn, +% } % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gput_right:Nn #1#2 { \@@_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } } -\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No, cn } +\cs_generate_variant:Nn \@@_tl_gput_right:Nn { Ne, cn } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gput_left:Nn,\@@_tl_gput_left:No} +% \begin{macro}{\@@_tl_gput_left:Nn} % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gput_left:Nn #1#2 @@ -2175,7 +2487,6 @@ \@@_tl_gset:Nx #1 { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} } } -\cs_generate_variant:Nn \@@_tl_gput_left:Nn { No } % \end{macrocode} % \end{macro} % @@ -2202,7 +2513,11 @@ % % \DescribeMacro{\g_@@_\meta{hook}_code_prop} % \DescribeMacro{\@@\textvisiblespace\meta{hook}} +% \DescribeMacro{\g_@@_\meta{hook}_reversed_tl} +% \DescribeMacro{\g_@@_\meta{hook}_declared_tl} +% \DescribeMacro{\g_@@_\meta{hook}_parameter_tl} % \DescribeMacro{\@@_next\textvisiblespace\meta{hook}} +% \DescribeMacro{\@@_toplevel\textvisiblespace\meta{hook}} % Hooks have a name (called \meta{hook} in the description below) % and for each hook we have to % provide a number of data structures. These are @@ -2232,12 +2547,17 @@ % so that it can be identified. The |-| character is used because % $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed % ones. - +% % \item[{\cs[no-index]{g_@@_\meta{hook}_declared_tl}}] This token -% list serves as marker for the hook being officially declared. Its +% list serves as a marker for the hook being officially declared. Its % existence is tested to raise an error in case another declaration % is attempted. % +% \item[{\cs[no-index]{c_@@_\meta{hook}_parameter_tl}}] This token +% list stores the parameter text for a declared hook (its existence +% almost completely intersects the token list above), which is used +% for managing hooks with arguments. +% % \item[\cs{@@_toplevel\textvisiblespace\meta{hook}}] 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. @@ -2367,45 +2687,92 @@ % \subsubsection{Setting hooks up} % % -% \begin{macro}{\hook_new:n,\@@_new:n} +% \begin{macro}{ +% \hook_new:n, +% \hook_new_with_args:nn +% } +% \begin{macro}{@@_new:nn} % The \cs{hook_new:n} declaration declares a new hook and expects % the hook \meta{name} as its argument, e.g., % \hook{begindocument}. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_with_args:nn} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_new_with_args:nn} +% {Hooks~with~args} \cs_new_protected:Npn \hook_new:n #1 - { \@@_normalize_hook_args:Nn \@@_new:n {#1} } + { \@@_normalize_hook_args:Nn \@@_new:nn {#1} { 0 } } +\cs_new_protected:Npn \hook_new_with_args:nn #1 #2 + { \@@_normalize_hook_args:Nn \@@_new:nn {#1} {#2} } % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Npn \@@_new:n #1 +\cs_new_protected:Npn \@@_new:nn #1 #2 { % \end{macrocode} % We check if the hook was already \emph{explicitly} declared with % \cs{hook_new:n}, and if it already exists we complain, otherwise set % the \enquote{created} flag for the hook so that it errors next time % \cs{hook_new:n} is used. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} \@@_if_declared:nTF {#1} { \msg_error:nnn { hooks } { exists } {#1} } { \tl_new:c { g_@@_#1_declared_tl } - \@@_make_usable:n {#1} + \cs_undefine:c { @@~#1 } + \cs_undefine:c { c_@@_#1_parameter_tl } + \@@_make_usable:nn {#1} {#2} +% \end{macrocode} +% In case there is already code in a hook, but it's undeclared, run +% \cs{@@_update_hook_code:n} to make it ready to be executed (see test +% \texttt{lthooks-034}). +% \changes{v1.1a}{2023/04/06} +% {Update hook code after declaring.} +% \begin{macrocode} + \@@_update_hook_code:n {#1} } } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_new_with_args:nn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \hook_new:n #1 +% { \@@_normalize_hook_args:Nn \@@_new:n {#1} } +%\cs_undefine:N \@@_new:nn +%\cs_gset_protected:Npn \@@_new:n #1 +% { +% \@@_if_declared:nTF {#1} +% { \msg_error:nnn { hooks } { exists } {#1} } +% { +% \tl_new:c { g_@@_#1_declared_tl } +% \@@_make_usable:n {#1} +% } +% } +%\cs_gset_protected:Npn \hook_new_with_args:nn #1 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_make_usable:n} +% \begin{macro}{\@@_make_usable:nn} % % This initializes all hook data structures for the hook but if % used on its own doesn't mark the hook as declared (as % \cs{hook_new:n} does, so a later \cs{hook_new:n} on that hook will % not result in an error. This command is internally used by -% \cs{hook_gput_code:n} when adding code to a generic hook. +% \cs{hook_gput_code:nnn} when adding code to a generic hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_make_usable:n #1 +%\IncludeInRelease{2023/06/01}{\@@_make_usable:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_make_usable:nn #1 #2 { % \end{macrocode} % Now we check if the hook's data structure can be safely created @@ -2414,29 +2781,70 @@ % allocate the necessary data structures for the new hook, % otherwise just do nothing. % \begin{macrocode} - \tl_if_exist:cF { @@~#1 } + \@@_if_usable:nF {#1} { \seq_gput_right:Nn \g_@@_all_seq {#1} % \end{macrocode} +% Here we'll define the \cs[no-index]{c_@@_\meta{hook}_parameter_tl} +% to hold a run of parameters up to the number of arguments of the +% hook (\verb|#2|). +% \begin{macrocode} + \__kernel_cs_parm_from_arg_count:nnF + { \tl_const:cn { c_@@_#1_parameter_tl } } {#2} + { + \msg_error:nnnn { hooks } { too-many-args } {#1} {#2} + \tl_const:cx { c_@@_#1_parameter_tl } + { \exp_not:V \c_@@_nine_parameters_tl } + } +% \end{macrocode} +% After that, use \cs{@@_normalise_cs_args:nn} to correct the number +% of parameters of the macros +% \cs[no-index]{@@_toplevel\textvisiblespace\meta{hook}} and +% \cs[no-index]{@@_next\textvisiblespace\meta{hook}}. We need to be +% able to add +% code with arguments to a hook without prior knowledge of the number +% of arguments of that hook, so \pkg{lthooks} assumes~9 until the +% hook is properly declared and the number of arguments is known. +% \cs{@@_normalise_cs_args:nn} does the normalisation by using the +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} defined just above. +% \begin{macrocode} + \@@_normalise_cs_args:nn { _toplevel } {#1} + \@@_normalise_cs_args:nn { _next } {#1} +% \end{macrocode} % This is only used by the actual code of the current hook, so % declare it normally: % \begin{macrocode} - \tl_new:c { @@~#1 } + \@@_code_gset:nn {#1} { } % \end{macrocode} % Now ensure that the base data structure for the hook exists: % \begin{macrocode} \@@_init_structure:n {#1} % \end{macrocode} +% The call to \cs{@@_normalise_code_pool:n} will correct any improper +% reference to arguments that don't exist in the hook, raising a +% low-level \TeX{} error and doubling the offending parameter tokens. +% It has to be done after \cs{@@_init_structure:n} because it +% operates on \cs[no-index]{g_@@_\meta{hook}_code_prop}. +% \begin{macrocode} + \@@_normalise_code_pool:n {#1} +% \end{macrocode} % The \cs{g_@@_\meta{hook}_labels_clist} holds the sorted list of % labels (once it got sorted). This is used only for debugging. +% These are defined conditionally, in case \cs{@@_make_usable:nn} +% is being used to redefine a hook. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} - \clist_new:c { g_@@_#1_labels_clist } + \clist_if_exist:cF { g_@@_#1_labels_clist } + { + \clist_new:c { g_@@_#1_labels_clist } % \end{macrocode} % Some hooks should reverse the default order of code chunks. To % signal this we have a token list which is empty for normal hooks % and contains a \verb=-= for reversed hooks. % \begin{macrocode} - \tl_new:c { g_@@_#1_reversed_tl } + \tl_new:c { g_@@_#1_reversed_tl } + } % \end{macrocode} % The above is all in L3 convention, but we also provide an % interface to legacy \LaTeXe{} hooks of the form \cs{@...hook}, @@ -2454,9 +2862,28 @@ \@@_include_legacy_code_chunk:n {#1} } } +%\EndIncludeInRelease % \end{macrocode} -% \end{macro} % +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_make_usable:nn} +% {Hooks~with~args} +%\cs_undefine:N \@@_make_usable:nn +%\cs_gset_protected:Npn \@@_make_usable:n #1 +% { +% \tl_if_exist:cF { @@~#1 } +% { +% \seq_gput_right:Nn \g_@@_all_seq {#1} +% \tl_new:c { @@~#1 } +% \@@_init_structure:n {#1} +% \clist_new:c { g_@@_#1_labels_clist } +% \tl_new:c { g_@@_#1_reversed_tl } +% \@@_include_legacy_code_chunk:n {#1} +% } +% } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % % \begin{macro}{\@@_init_structure:n} @@ -2472,49 +2899,124 @@ % \cs{@@_init_structure:n} the first time anything is added to it. % Initializing a hook just with \cs{@@_init_structure:n} will not % make it usable with \cs{hook_use:n}. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_init_structure:n} +% {Hooks~with~args} \cs_new_protected:Npn \@@_init_structure:n #1 { \@@_if_structure_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } - \tl_new:c { @@_toplevel~#1 } - \tl_new:c { @@_next~#1 } + \@@_toplevel_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } } } +%\EndIncludeInRelease % \end{macrocode} -% \end{macro} -% % +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_init_structure:n} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_init_structure:n #1 +% { +% \@@_if_structure_exist:nF {#1} +% { +% \prop_new:c { g_@@_#1_code_prop } +% \tl_new:c { @@_toplevel~#1 } +% \tl_new:c { @@_next~#1 } +% } +% } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\hook_new_reversed:n,\@@_new_reversed:n} +% \begin{macro}{ +% \hook_new_reversed:n, +% \hook_new_reversed_with_args:nn +% } +% \begin{macro}{\@@_new_reversed:nn} % % Declare a new hook. The default ordering of code chunks is % reversed, signaled by setting the token list to a minus sign. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_reversed_with_args:nn} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_new_reversed_with_args:nn} +% {Hooks~with~args} \cs_new_protected:Npn \hook_new_reversed:n #1 - { \@@_normalize_hook_args:Nn \@@_new_reversed:n {#1} } -\cs_new_protected:Npn \@@_new_reversed:n #1 + { \@@_normalize_hook_args:Nn \@@_new_reversed:nn {#1} { 0 } } +\cs_new_protected:Npn \hook_new_reversed_with_args:nn #1 #2 + { \@@_normalize_hook_args:Nn \@@_new_reversed:nn {#1} {#2} } +\cs_new_protected:Npn \@@_new_reversed:nn #1 #2 { - \@@_new:n {#1} + \@@_if_declared:nTF {#1} + { \msg_error:nnn { hooks } { exists } {#1} } + { + \@@_new:nn {#1} {#2} + \tl_gset:cn { g_@@_#1_reversed_tl } { - } + } + } +%\EndIncludeInRelease % \end{macrocode} -% If the hook already exists the above will generate an error -% message, so the next line should be executed (but it is --- too -% bad). +% % \begin{macrocode} - \tl_gset:cn { g_@@_#1_reversed_tl } { - } - } +%\IncludeInRelease{2020/10/01}{\hook_new_reversed_with_args:nn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \hook_new_reversed:n #1 +% { \@@_normalize_hook_args:Nn \@@_new_reversed:n {#1} } +%\cs_undefine:N \@@_new_reversed:nn +%\cs_gset_protected:Npn \@@_new_reversed:n #1 +% { +% \@@_new:n {#1} +% \tl_gset:cn { g_@@_#1_reversed_tl } { - } +% } +%\cs_undefine:N \@@_new_reversed:nn +%\cs_gset_protected:Npn \hook_new_reversed_with_args:nn #1 #2 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} +% \end{macro} % -% -% -% -% \begin{macro}{\hook_new_pair:nn} +% \begin{macro}{\hook_new_pair:nn,\hook_new_pair_with_args:nnn} % A shorthand for declaring a normal and a (matching) reversed hook in one go. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_pair_with_args:nnn} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_new_pair_with_args:nnn} +% {Hooks~with~args} \cs_new_protected:Npn \hook_new_pair:nn #1#2 - { \hook_new:n {#1} \hook_new_reversed:n {#2} } + { \@@_normalize_hook_args:Nnn \@@_new_pair:nnn {#1} {#2} { 0 } } +\cs_new_protected:Npn \hook_new_pair_with_args:nnn #1#2#3 + { \@@_normalize_hook_args:Nnn \@@_new_pair:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \@@_new_pair:nnn #1 #2 #3 + { + \@@_if_declared:nTF {#1} + { \msg_error:nnn { hooks } { exists } {#1} } + { + \@@_if_declared:nTF {#2} + { \msg_error:nnn { hooks } { exists } {#2} } + { + \@@_new:nn {#1} {#3} + \@@_new_reversed:nn {#2} {#3} + } + } + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_new_pair_with_args:nnn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \hook_new_pair:nn #1#2 +% { +% \hook_new:n {#1} +% \hook_new_reversed:n {#2} +% } +%\cs_gset_protected:Npn \hook_new_pair_with_args:nnn #1#2#3 +% { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -2531,6 +3033,8 @@ % \textbf{Warning: this support will vanish in future releases!} % \end{quote} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_include_legacy_code_chunk:n} +% {Hooks~with~args} \cs_new_protected:Npn \@@_include_legacy_code_chunk:n #1 { % \end{macrocode} @@ -2538,15 +3042,27 @@ % needs to be done. % \begin{macrocode} \tl_if_exist:cT { @#1hook } + { % \end{macrocode} % Of course if the legacy hook exists but is empty, there is no need % to add anything under \texttt{legacy} the legacy label. % \begin{macrocode} - { \tl_if_empty:cF { @#1hook } { - \exp_args:Nnnv \@@_hook_gput_code_do:nnn {#1} - { legacy } { @#1hook } +% \end{macrocode} +% Here we set \cs{@@_replacing_args_false:} because no legacy code +% will reference hook arguments. +% \changes{v1.1b}{2023/04/16} +% {\cs{@@_replacing_args_false:} in +% \cs{@@_include_legacy_code_chunk:n}.} +% \begin{macrocode} + \@@_replacing_args_false: + \use:e + { + \@@_hook_gput_code_do:nnn {#1} { legacy } + { \exp_not:v { @#1hook } } + } + \@@_replacing_args_reset: % \end{macrocode} % Once added to the hook, we need to clear it otherwise it might % get added again later if the hook data gets updated. @@ -2555,6 +3071,22 @@ } } } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_include_legacy_code_chunk:n} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_include_legacy_code_chunk:n #1 +% { +% \tl_if_exist:cT { @#1hook } +% { +% \tl_if_empty:cF { @#1hook } +% { +% \exp_args:Nnnv \@@_hook_gput_code_do:nnn +% {#1} { legacy } { @#1hook } +% \@@_tl_gclear:c { @#1hook } +% } +% } +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -2579,8 +3111,8 @@ % if the hook is disabled. % % \begin{macrocode} -%\IncludeInRelease{2021/06/01}% -% {\hook_disable_generic:n}{Disable~hooks} +%\IncludeInRelease{2021/06/01}{\hook_disable_generic:n} +% {Disable~hooks} % \end{macrocode} % % \begin{macrocode} @@ -2595,7 +3127,7 @@ { \bool_lazy_and:nnTF { \tl_if_exist_p:c { g_@@_#1_declared_tl } } - { ! \tl_if_exist_p:c { @@~#1 } } + { ! \cs_if_exist_p:c { @@~#1 } } { \prg_return_true: } { \prg_return_false: } } @@ -2603,8 +3135,8 @@ % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01} -% {\hook_disable_generic:n}{Disable~hooks} +%\IncludeInRelease{2020/10/01}{\hook_disable_generic:n} +% {Disable~hooks} % %\cs_new_protected:Npn \hook_disable_generic:n #1 {} % @@ -2619,9 +3151,11 @@ % The \cs{hook_activate_generic:n} declaration declares a new hook if it % wasn't declared already, in which case it only checks that the % already existing hook is not a reversed hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -%\IncludeInRelease{2021/06/01}% -% {\hook_activate_generic:n}{Providing~hooks} +%\IncludeInRelease{2023/06/01}{\hook_activate_generic:n} +% {Providing~hooks} % \end{macrocode} % % \begin{macrocode} @@ -2646,7 +3180,7 @@ \@@_if_declared:nF {#1} { \tl_new:c { g_@@_#1_declared_tl } - \@@_make_usable:n {#1} + \@@_make_usable:nn {#1} { 0 } \tl_gset:cx { g_@@_#1_reversed_tl } { \@@_if_generic_reversed:nT {#1} { - } } % \end{macrocode} @@ -2660,21 +3194,40 @@ } } % \end{macrocode} -% \end{macro} -% \end{macro} % % \begin{macrocode} %\EndIncludeInRelease % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01} -% {\hook_activate_generic:n}{Providing~hooks} -% -%\cs_new_protected:Npn \hook_activate_generic:n #1 {} -% +%\IncludeInRelease{2021/06/01}{\hook_activate_generic:n} +% {Providing~hooks} +%\cs_gset_protected:Npn \@@_activate_generic:nn #1 #2 +% { +% \@@_if_disabled:nTF {#1} +% { \msg_warning:nnn { hooks } { activate-disabled } {#1} } +% { +% \@@_if_declared:nF {#1} +% { +% \tl_new:c { g_@@_#1_declared_tl } +% \@@_make_usable:n {#1} +% \tl_gset:cx { g_@@_#1_reversed_tl } +% { \@@_if_generic_reversed:nT {#1} { - } } +% \@@_update_hook_code:n {#1} +% } +% } +% } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_activate_generic:n} +% {Providing~hooks} +%\cs_gset_protected:Npn \hook_activate_generic:n #1 { } %\EndIncludeInRelease % \end{macrocode} +% \end{macro} +% \end{macro} % % % \subsection{Parsing a label} @@ -2965,63 +3518,109 @@ % % \subsection{Adding or removing hook code} % -% \begin{macro}{\hook_gput_code:nnn} -% \begin{macro}{\@@_gput_code:nnn,\@@_hook_gput_code_do:nnn} +% \begin{macro}{\hook_gput_code:nnn,\hook_gput_code_with_args:nnn} +% \begin{macro}{ +% \@@_gput_code:nnn, +% \@@_gput_code_store:nnn, +% \@@_hook_gput_code_do:nnn, +% \@@_prop_gput_labeled_cleanup:nnn, +% \@@_prop_gput_labeled_do:Nnnn +% } % % With \cs{hook_gput_code:nnn}\Arg{hook}\Arg{label}\Arg{code} a % chunk of \meta{code} is added to an existing \meta{hook} labeled % with \meta{label}. % \changes{v1.0o}{2021/07/22}{Do not queue removals (gh/625)} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_gput_code_with_args:nnn} (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 - { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +%\IncludeInRelease{2023/06/01}{\hook_gput_code_with_args:nnn} +% {Hooks~with~args} +\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 #3 + { + \@@_replacing_args_false: + \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} {#3} + \@@_replacing_args_reset: + } +\cs_new_protected:Npn \hook_gput_code_with_args:nnn #1 #2 #3 + { + \@@_replacing_args_true: + \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} {#3} + \@@_replacing_args_reset: + } % \end{macrocode} % +% If \cs{AddToHookWithArguments} was used, do some sanity checking, +% and if it's not possible to use arguments at this point, fall back +% to regular \cs{AddToHook} by using \cs{@@_replacing_args_false:}. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3 { + \@@_chk_args_allowed:nn {#1} { AddToHook } % \end{macrocode} -% First check if the code should be executed immediately, rather than +% Then check if the code should be executed immediately, rather than % stored: % \changes{v1.0r}{2021/09/06}{Use dedicated conditional (gh/606)} % \begin{macrocode} \@@_if_execute_immediately:nTF {#1} - {#3} { % \end{macrocode} +% \cs{AddToHookWithArguments} can't be used on one-time hooks (that +% were already used). +% \begin{macrocode} + \@@_if_replacing_args:TF + { + \msg_error:nnnn { hooks } { one-time-args } + {#1} { AddToHook } + } + { } + \use:n + } + { \@@_gput_code_store:nnn {#1} {#2} } + {#3} + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_code_store:nnn #1 #2 #3 + { +% \end{macrocode} % Then check if the hook is usable. % \begin{macrocode} - \@@_if_usable:nTF {#1} + \@@_if_usable:nTF {#1} % \end{macrocode} % If so we simply add (or append) the new code to the property list % holding different chunks for the hook. At \verb=\begin{document}= % this is then sorted into a token list for fast execution. % \begin{macrocode} - { - \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + { + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} % \end{macrocode} % However, if there is an update within the document we need to alter % this execution code which is done by % \cs{@@_update_hook_code:n}. In the preamble this does nothing. % \begin{macrocode} - \@@_update_hook_code:n {#1} - } + \@@_update_hook_code:n {#1} + } % \end{macrocode} % % If the hook is not usable, before giving up, check if it's not % disabled and otherwise try to declare it as a generic hook, if its % name matches one of the valid patterns. % \begin{macrocode} - { - \@@_if_disabled:nTF {#1} - { \msg_error:nnn { hooks } { hook-disabled } {#1} } - { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } - } + { + \@@_if_disabled:nTF {#1} + { \msg_error:nnn { hooks } { hook-disabled } {#1} } + { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } } } % \end{macrocode} % % This macro will unconditionally add a chunk of code to the given hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \cs_new_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 { @@ -3046,42 +3645,172 @@ \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{@@_init_structure:n}. +% If the hook's basic structure does not exist, we need to declare it +% with \cs{@@_init_structure:n}. % \begin{macrocode} \@@_init_structure:n {#1} - \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} +% \end{macrocode} +% Then append to the \verb|_toplevel| container for the hook. +% \begin{macrocode} + \@@_cs_gput_right:nnn { _toplevel } {#1} {#3} } { \msg_error:nnn { hooks } { misused-top-level } {#1} } } { - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +% \end{macrocode} +% When adding to the code pool, we have to double hashes if +% \cs{AddToHook} was used (\verb|replacing_args| is false), so that +% later it is turned into a single parameter token, rather than a +% parameter to the hook macro. +% \begin{macrocode} + \exp_args:Nx \@@_prop_gput_labeled_cleanup:nnn { - \prop_gput:cno { g_@@_#1_code_prop } {#2} - { \l_@@_return_tl #3 } + \@@_if_replacing_args:TF + { \exp_not:n } + { \@@_double_hashes:n } + {#3} } - { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } + {#1} {#2} } } % \end{macrocode} -% \end{macro} -% \end{macro} % -% \begin{macro}{\@@_gput_undeclared_hook:nnn} -% Often it may happen that a package $A$ defines a hook \verb=foo=, -% but package $B$, that adds code to that hook, is loaded before $A$. -% In such case we need to add code to the hook before its declared. +% Adds code to a hook's code pool. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 +\cs_new_protected:Npn \@@_prop_gput_labeled_cleanup:nnn #1 #2 #3 { - \@@_init_structure:n {#1} - \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + \tl_set:Nn \l_@@_return_tl {#1} + \@@_if_replacing_args:TF + { + \@@_if_usable:nT {#2} + { + \@@_set_normalise_fn:nn {#2} + { Invalid~code~added~\msg_line_context: } + \@@_normalise_fn:nn {#3} {#1} + \prop_get:NnN \l_@@_work_prop {#3} \l_@@_return_tl + } + } + { } + \exp_args:NcV \@@_prop_gput_labeled_do:Nnn + { g_@@_#2_code_prop } \l_@@_return_tl {#3} + } +\cs_new_protected:Npn \@@_prop_gput_labeled_do:Nnn #1 #2 #3 + { + \prop_get:NnNTF #1 {#3} \l_@@_return_tl + { \prop_gput:Nno #1 {#3} { \l_@@_return_tl #2 } } + { \prop_gput:Nnn #1 {#3} {#2} } } % \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_try_declaring_generic_hook:nnn, -% \@@_try_declaring_generic_next_hook:nn} +% +% \begin{macrocode} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_gput_code:nnn} +% {Providing~hooks} +%\cs_gset_protected:Npn \hook_gput_code:nnn #1 #2 +% { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +%\cs_gset_protected:Npn \@@_gput_code:nnn #1 #2 #3 +% { +% \@@_if_execute_immediately:nTF {#1} +% {#3} +% { +% \@@_if_usable:nTF {#1} +% { +% \@@_hook_gput_code_do:nnn {#1} {#2} {#3} +% \@@_update_hook_code:n {#1} +% } +% { +% \@@_if_disabled:nTF {#1} +% { \msg_error:nnn { hooks } { hook-disabled } {#1} } +% { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } +% } +% } +% } +%\cs_gset_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 +% { +% \@@_debug:n{\iow_term:x{****~ Add~ to~ +% \@@_if_usable:nF {#1} { undeclared~ } +% hook~ #1~ (#2) +% \on@line\space <-~ \tl_to_str:n{#3}} } +% \str_if_eq:nnTF {#2} { top-level } +% { +% \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } +% { +% \@@_init_structure:n {#1} +% \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} +% } +% { \msg_error:nnn { hooks } { misused-top-level } {#1} } +% } +% { +% \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} } +% } +% } +%\cs_gset_protected:Npn \hook_gput_code_with_args:nnn #1#2#3 { } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_chk_args_allowed:nn} +% This macro checks if it is possible to add code with references to +% a hook's arguments for hook \verb|#1|. It only does something if +% the function being run is \verb|replacing_args|. This macro will +% error if the hook is declared and takes no arguments, then it will +% set \cs{@@_replacing_args_false:} so that the macro which called it +% will add the code normally. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_chk_args_allowed:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_chk_args_allowed:nn #1 #2 + { + \@@_if_replacing_args:TF + { + \@@_if_declared:nT {#1} + { \tl_if_empty:cT { c_@@_#1_parameter_tl } { \use_ii:nn } } + \use_none:n + { + \msg_error:nnnn { hooks } { without-args } {#1} {#2} + \@@_replacing_args_false: + } + } + { } + } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_chk_args_allowed:nn} +% {Hooks~with~args} +%\cs_undefine:N \@@_chk_args_allowed:nn +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_gput_undeclared_hook:nnn} +% Often it may happen that a package $A$ defines a hook \verb=foo=, +% but package $B$, that adds code to that hook, is loaded before $A$. +% In such case we need to add code to the hook before its declared. +% An implicitly declared hook doesn't have arguments (in principle), +% so use \cs{c_false_bool} here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 + { + \@@_init_structure:n {#1} + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_try_declaring_generic_hook:nnn, +% \@@_try_declaring_generic_next_hook:nn} % % These entry-level macros just pass the arguments along to the % common \cs{@@_try_declaring_generic_hook:nNNnn} with the right @@ -3098,24 +3827,43 @@ % \cs{hook_gput_next_code:nn} if the generic hook was declared, or % to \cs{@@_gput_next_do:nn} otherwise. % \changes{v1.0p}{2021/08/25}{Standardise generic hook names (gh/648)} +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn} -% {Standardise~generic~hook~names} +%\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:nnn} +% {Hooks~with~args} \cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 { \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} - \hook_gput_code:nnn + \@@_gput_code:nnn \@@_gput_undeclared_hook:nnn {#1} } \cs_new_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 { \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} - \hook_gput_next_code:nn + \@@_gput_next_code:nn \@@_gput_next_do:nn {#1} } %\EndIncludeInRelease +%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn} +% {Standardise~generic~hook~names} +%\cs_gset_protected:Npn \@@_try_declaring_generic_hook:nnn #1 +% { +% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +% \hook_gput_code:nnn +% \@@_gput_undeclared_hook:nnn +% {#1} +% } +%\cs_gset_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 +% { +% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +% \hook_gput_next_code:nn +% \@@_gput_next_do:nn +% {#1} +% } +%\EndIncludeInRelease %\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:nnn} % {Standardise~generic~hook~names} %\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 @@ -3170,9 +3918,11 @@ % \end{macro} % % \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn}% -% {Standardise~generic~hook~names} +%\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:wn} +% {Hooks~with~args} \prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn #1 / #2 / #3 / #4 \scan_stop: #5 { TF } { @@ -3188,18 +3938,25 @@ % For some commands this will not be possible, in which case % \cs{@@_patch_cmd_or_delay:Nnn} (defined in \texttt{ltcmdhooks}) % will generate an appropriate error message. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} \str_if_eq:nnT {#1} { cmd } - { \@@_try_put_cmd_hook:n {#5} } + { + \@@_try_put_cmd_hook:n {#5} + \@@_make_usable:nn {#5} { 9 } + \use_none:nnn + } % \end{macrocode} % % Declare the hook always even if it can't really be used (error % message generated elsewhere). % -% Here we use \cs{@@_make_usable:n}, so that a \cs{hook_new:n} is still -% possible later. +% Here we use \cs{@@_make_usable:nn}, so that a \cs{hook_new:n} is +% still possible later. Generic hooks (except \hook{cmd} hooks) take +% no arguments, so use zero as the second argument. % \begin{macrocode} - \@@_make_usable:n {#5} + \@@_make_usable:nn {#5} { 0 } } \@@_if_generic_reversed:nT {#5} { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } @@ -3285,6 +4042,37 @@ % \end{macro} % % \begin{macrocode} +%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn} +% {Standardise~generic~hook~names} +%\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +% #1 / #2 / #3 / #4 \scan_stop: #5 { TF } +% { +% \@@_if_generic:nTF {#5} +% { +% \@@_if_usable:nF {#5} +% { +% \str_if_eq:nnT {#1} { cmd } +% { \@@_try_put_cmd_hook:n {#5} } +% \@@_make_usable:n {#5} +% } +% \@@_if_generic_reversed:nT {#5} +% { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } +% \prg_return_true: +% } +% { +% \@@_if_deprecated_generic:nTF {#5} +% { +% \@@_deprecated_generic_warn:n {#5} +% \exp_after:wN \@@_declare_deprecated_generic:NNn +% \exp:w % \exp_end: +% } +% { \prg_return_false: } +% } +% } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} %\IncludeInRelease{2021/06/01}{\@@_try_declaring_generic_hook:wn} % {Support~cmd~hooks} %\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn @@ -3316,7 +4104,7 @@ % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn}% +%\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn} % {Support~cmd~hooks} %\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn % #1 / #2 / #3 / #4 \scan_stop: #5 { TF } @@ -3338,7 +4126,6 @@ % { \prg_return_false: } % } % } -% %\EndIncludeInRelease % \end{macrocode} % \end{macro} @@ -3350,24 +4137,10 @@ % |file/foo.tex/before|). If it is a file-specific hook, then it % executes the \meta{true} branch, otherwise \meta{false}. % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\@@_if_file_hook:w}% +%\IncludeInRelease{2021/11/15}{\@@_if_file_hook:w} % {Standardise~generic~hook~names} -\prg_new_conditional:Npnn \@@_if_file_hook:w - #1 / #2 \s_@@_mark #3 { TF } - { - \@@_if_generic:nTF {#3} - { - \str_if_eq:nnTF {#1} { file } - { \prg_return_true: } - { \prg_return_false: } - } - { \prg_return_false: } - } %\EndIncludeInRelease -% \end{macrocode} -% -% \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\@@_if_file_hook:w}% +%\IncludeInRelease{2020/10/01}{\@@_if_file_hook:w} % {Standardise~generic~hook~names} %\prg_new_conditional:Npnn \@@_if_file_hook:w % #1 / #2 / #3 \s_@@_mark { TF } @@ -3394,7 +4167,7 @@ % \begin{macro}[EXP]{\@@_strip_double_slash:n,\@@_strip_double_slash:w} % % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\@@_file_hook_normalize:n}% +%\IncludeInRelease{2021/11/15}{\@@_file_hook_normalize:n} % {Standardise~generic~hook~names} %\EndIncludeInRelease % \end{macrocode} @@ -3406,7 +4179,7 @@ % like \verb|\def\input@path{{./mypath/}}|, in which case a hook would % have to be \verb|\AddToHook{file/./mypath//file.tex/after}|. % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\@@_file_hook_normalize:n}% +%\IncludeInRelease{2020/10/01}{\@@_file_hook_normalize:n} % {Standardise~generic~hook~names} %\cs_new:Npn \@@_file_hook_normalize:n #1 % { \@@_strip_double_slash:n {#1} } @@ -3453,7 +4226,7 @@ % The generic hooks used when loading a file % \end{description} % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\c_@@_generics_prop}% +%\IncludeInRelease{2021/11/15}{\c_@@_generics_prop} % {Standardise~generic~hook~names} \clist_map_inline:nn { cmd , env , file , package , class , include } { @@ -3482,7 +4255,7 @@ % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\c_@@_generics_prop}% +%\IncludeInRelease{2020/10/01}{\c_@@_generics_prop} % {Standardise~generic~hook~names} %\prop_const_from_keyval:Nn \c_@@_generics_prop % {cmd=,env=,file=,package=,class=,include=} @@ -3496,13 +4269,13 @@ % The following generic hooks are supposed to use reverse ordering % (the |ii| and |iii| names are kept for the deprecation cycle): % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\c_@@_generics_reversed_ii_prop}% +%\IncludeInRelease{2021/11/15}{\c_@@_generics_reversed_ii_prop} % {Standardise~generic~hook~names} %\EndIncludeInRelease % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop}% +%\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop} % {Standardise~generic~hook~names} %\prop_const_from_keyval:Nn \c_@@_generics_reversed_ii_prop {after=,end=} %\prop_const_from_keyval:Nn \c_@@_generics_reversed_iii_prop {after=} @@ -3511,13 +4284,46 @@ % \end{macrocode} % \end{macro} % +% +% \begin{macro}{ +% \c_@@_parameter_cmd/./before_tl,\c_@@_parameter_cmd/./after_tl, +% } +% Token lists defining the number of arguments for a given type of +% generic hook. +% \changes{v1.1d}{2023/05/21} +% {Token lists added (cmd-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\c_@@_parameter_cmd/./before_tl} +% {Hooks~with~args} +% \end{macrocode} +% +% \hook{cmd} hooks are declared with 9 arguments because they have a +% variable number of arguments (depending on the command they are +% attached to), so we use the maximum here. +% \begin{macrocode} +\tl_const:cn { c_@@_parameter_cmd/./before_tl } { #1#2#3#4#5#6#7#8#9 } +\tl_const:cn { c_@@_parameter_cmd/./after_tl } { #1#2#3#4#5#6#7#8#9 } +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\c_@@_parameter_cmd/./before_tl} +% {Hooks~with~args} +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hook_gremove_code:nn} % \begin{macro}{\@@_gremove_code:nn} % % With \cs{hook_gremove_code:nn}\Arg{hook}\Arg{label} any code % for \meta{hook} stored under \meta{label} is removed. % \changes{v1.0o}{2021/07/22}{Do not queue removals (gh/625)} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_gremove_code:nn} +% {Hooks~with~args} \cs_new_protected:Npn \hook_gremove_code:nn #1 #2 { \@@_normalize_hook_args:Nnn \@@_gremove_code:nn {#1} {#2} } \cs_new_protected:Npn \@@_gremove_code:nn #1 #2 @@ -3542,8 +4348,8 @@ \str_if_eq:nnTF {#2} {*} { \prop_gclear:c { g_@@_#1_code_prop } - \@@_tl_gclear:c { @@_toplevel~#1 } - \@@_tl_gclear:c { @@_next~#1 } + \@@_toplevel_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } } { % \end{macrocode} @@ -3551,7 +4357,7 @@ % there is under the same label. % \begin{macrocode} \str_if_eq:nnTF {#2} { top-level } - { \@@_tl_gclear:c { @@_toplevel~#1 } } + { \@@_toplevel_gset:nn {#1} { } } { \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } @@ -3576,14 +4382,568 @@ { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } } } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_gremove_code:nn} +% {Hooks~with~args} +%\cs_new_protected:Npn \@@_gremove_code:nn #1 #2 +% { +% \@@_if_structure_exist:nTF {#1} +% { +% \str_if_eq:nnTF {#2} {*} +% { +% \prop_gclear:c { g_@@_#1_code_prop } +% \@@_tl_gclear:c { @@_toplevel~#1 } +% \@@_tl_gclear:c { @@_next~#1 } +% } +% { +% \str_if_eq:nnTF {#2} { top-level } +% { \@@_tl_gclear:c { @@_toplevel~#1 } } +% { +% \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +% { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +% } +% } +% \@@_if_usable:nT {#1} +% { \@@_update_hook_code:n {#1} } +% } +% { +% \@@_if_deprecated_generic:nTF {#1} +% { +% \@@_deprecated_generic_warn:n {#1} +% \@@_do_deprecated_generic:Nn \@@_gremove_code:nn {#1} {#2} +% } +% { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +% } +% } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_cs_gput_right:nnn} +% \begin{macro}{\@@_cs_gput_right_fast:nnn,\@@_cs_gput_right_slow:nnn} +% \begin{macro}{\@@_code_gset_auxi:nnnn,\@@_code_gset_auxi:eeen} +% This macro is used to append code to the \verb|toplevel| and +% \verb|next| token lists, trating them correctly depending on their +% number of arguments, and depending if the code being added should +% have parameter tokens understood as parameters, or doubled to be +% stored as parameter tokens. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \changes{v1.1e}{2023/06/06} +% {Short-circuit when the hook is declared without args (gh1078).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_cs_gput_right:nnn} +% {Hooks~with~args} +% \end{macrocode} +% +% Check if the current hook is declared and takes no arguments. In +% this case, we short-circuit and use the simpler and much faster +% approach that doesn't require hash-doubling. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cs_gput_right:nnn #1 #2 + { + \if:w T + \@@_if_declared:nF {#2} { F } + \tl_if_empty:cF { c_@@_#2_parameter_tl } { F } + T + \exp_after:wN \@@_cs_gput_right_fast:nnn + \else: + \exp_after:wN \@@_cs_gput_right_slow:nnn + \fi: + {#1} {#2} + } +\cs_new_protected:Npn \@@_cs_gput_right_fast:nnn #1 #2 #3 + { \cs_gset:cpx { @@#1~#2 } { \exp_not:v { @@#1~#2 } \exp_not:n {#3} } } +\cs_new_protected:Npn \@@_cs_gput_right_slow:nnn #1 #2 #3 + { +% \end{macrocode} +% The auxiliary \cs{@@_code_gset_auxi:eeen} just does the assignment +% at the end. Its first argument is the parameter text of the macro, +% which is chosen here depending if +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} exists, if the hook is +% declared, and if it's a generic hook. +% \begin{macrocode} + \cs_if_exist:cF { @@#1~#2 } + { \@@_code_gset_aux:nnn {#1} {#2} { } } + \@@_code_gset_auxi:eeen + { + \@@_if_declared:nTF {#2} + { \tl_use:c { c_@@_#2_parameter_tl } } + { + \@@_if_generic:nTF {#2} + { \@@_generic_parameter:n {#2} } + { \c_@@_nine_parameters_tl } + } + } +% \end{macrocode} +% Here we take the existing code in the macro, expand it with as many +% arguments as it takes, then double the hashes so the code can be +% reused. \pho{Maybe can be improved. The case of adding to an empty +% cs can be optimised by quickly checking \cs{cs_replacement_spec}.} +% \begin{macrocode} + { + \exp_args:NNo \exp_args:No \@@_double_hashes:n + { + \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: + { \@@_braced_cs_parameter:n { @@#1~#2 } } + } + } +% \end{macrocode} +% Now the new code: if we are replacing arguments, then hashes are +% left untouched, otherwise they are doubled. +% \begin{macrocode} + { + \@@_if_replacing_args:TF + { \exp_not:n } + { \@@_double_hashes:n } + {#3} + } +% \end{macrocode} +% And finally, the csname which we'll define with all the above. +% \begin{macrocode} + { @@#1~#2 } + } +% \end{macrocode} +% +% And as promised, the auxiliary that does the definition. +% \begin{macrocode} +\cs_new_protected:Npn \@@_code_gset_auxi:nnnn #1 #2 #3 #4 + { \cs_gset:cpn {#4} #1 { #2 #3 } } +\cs_generate_variant:Nn \@@_code_gset_auxi:nnnn { eeen } % \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_cs_gput_right:nnn} +% {Hooks~with~args} +%\cs_undefine:N \@@_cs_gput_right:nnn +%\cs_undefine:N \@@_cs_gput_right_fast:nnn +%\cs_undefine:N \@@_cs_gput_right_slow:nnn +%\cs_undefine:N \@@_code_gset_auxi:nnnn +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{ +% \@@_code_gset:nn,\@@_code_gset:ne, +% \@@_toplevel_gset:nn, +% \@@_next_gset:nn, +% \@@_code_gset_aux:nnn +% } +% These macros define +% \cs[no-index]{@@\meta{type}\textvisiblespace\meta{hook}} (with +% \meta{type} being \verb|_next|, \verb|_toplevel|, or empty) with the +% given code and the parameters stored in +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} (or none, if that +% doesn't exist). +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_code_gset:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_code_gset:nn + { \@@_code_gset_aux:nnn { } } +\cs_new_protected:Npn \@@_toplevel_gset:nn + { \@@_code_gset_aux:nnn { _toplevel } } +\cs_new_protected:Npn \@@_next_gset:nn + { \@@_code_gset_aux:nnn { _next } } +\cs_new_protected:Npn \@@_code_gset_aux:nnn #1 #2 #3 + { + \cs_gset:cpn { @@#1~#2 \exp_last_unbraced:Ne } + { \@@_parameter:n {#2} } + {#3} + } +\cs_generate_variant:Nn \@@_code_gset:nn { ne } +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_code_gset:nn} +% {Hooks~with~args} +%\cs_undefine:N \@@_code_gset:nn +%\cs_undefine:N \@@_toplevel_gset:nn +%\cs_undefine:N \@@_next_gset:nn +%\cs_undefine:N \@@_code_gset_aux:nnn +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalise_cs_args:nn} +% This macro normalises the parameters of the macros +% \cs[no-index]{@@\meta{type}\textvisiblespace\meta{hook}} to take the +% right number of arguments after a hook is declared. At this point +% we know \cs[no-index]{c_@@_\meta{hook}_parameter_tl} exists, so use +% that to count the arguments and use that as \meta{parameter text} +% for the newly (re)defined macro. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_normalise_cs_args:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_normalise_cs_args:nn #1 #2 + { + \cs_if_exist:cT { @@#1~#2 } + { + \@@_code_gset_auxi:eeen + { \tl_use:c { c_@@_#2_parameter_tl } } + { + \exp_args:NNo \exp_args:No \@@_double_hashes:n + { + \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: + { \@@_braced_cs_parameter:n { @@#1~#2 } } + } + } + { } + { @@#1~#2 } + } + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_normalise_cs_args:nn} +% {Hooks~with~args} +%\cs_undefine:N \@@_normalise_cs_args:nn +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalise_code_pool:n} +% \begin{macro}{\@@_set_normalise_fn:nn} +% This one's a bit of a hack. It takes a hook, and iterates over its +% code pool (\cs[no-index]{g_@@_\meta{hook}_code_prop}), redefining +% each code label to use only valid arguments. This is used when, for +% example, a code is added referencing arguments \verb|#1| and +% \verb|#2|, but the hook has only \verb|#1|. In this example, every +% reference to \verb|#2| is changed to \verb|##2|. This is done +% because otherwise \TeX{} will throw a low-level error every time +% some change happens to the hook (code is added, a rule is set, etc), +% which can get quite repetitive for no good reason. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_normalise_code_pool:n} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_normalise_code_pool:n #1 + { +% \end{macrocode} +% First, call \cs{@@_set_normalise_fn:nn} with the hook name to set +% everything up, then we'll loop over the +% hook's code pool applying the normalisation above. After that's +% done, copy the temporary property list back to the hook's. +% \begin{macrocode} + \@@_set_normalise_fn:nn {#1} { Offending~label:~'##1' } + \prop_clear:N \l_@@_work_prop + \prop_map_function:cN { g_@@_#1_code_prop } \@@_normalise_fn:nn + \prop_gset_eq:cN { g_@@_#1_code_prop } \l_@@_work_prop + } +% \end{macrocode} +% +% The sole purpose of this function is to define +% \cs{@@_normalise_fn:nn}, which will then do the correcting of the +% code being added to the hook. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_normalise_fn:nn #1 #2 + { +% \end{macrocode} +% To start, we define two auxiliary token lists. +% \cs[no-index]{l_@@_tmpb_tl} contains: +%\begin{verbatim} +% {\c__hook_hashes_tl 1} +% {\c__hook_hashes_tl 2} +% ... +% {\c__hook_hashes_tl 9} +%\end{verbatim} +% \begin{macrocode} + \cs_set:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8##9 { } + \tl_set:Ne \l_@@_tmpb_tl + { \@@_braced_cs_parameter:n { @@_tmp:w } } + \group_begin: + \@@_tl_set:cn { c_@@_hash_tl } { \exp_not:N \c_@@_hashes_tl } + \use:e + { + \group_end: + \tl_set:Nn \exp_not:N \l_@@_tmpb_tl { \l_@@_tmpb_tl } + } +% \end{macrocode} +% And \cs[no-index]{l_@@_tmpa_tl} contains: +%\begin{verbatim} +% {\c__hook_hash_tl 1} +% {\c__hook_hash_tl 2} +% ... +% {\c__hook_hash_tl } +%\end{verbatim} +% with \meta{n} being the number of arguments declared for the hook. +% \begin{macrocode} + \exp_last_unbraced:NNf + \cs_set:Npn \@@_tmp:w { \@@_parameter:n {#1} } { } + \tl_set:Ne \l_@@_tmpa_tl { \@@_braced_cs_parameter:n { @@_tmp:w } } +% \end{macrocode} +% Now this function does the fun part. It is meant to be used with +% \cs{prop_map_function:NN}, taking a label name in \verb|##1| and the +% code stored in that label in \verb|##2|. +% \begin{macrocode} + \cs_gset_protected:Npx \@@_normalise_fn:nn ##1 ##2 + { +% \end{macrocode} +% Here we'll define two auxiliary macros: the first one throws an +% error when it detects an invalid argument reference. It piggybacks +% on \TeX's low-level \enquote{Illegal parameter number} error, but it +% defines a weirdly-named control sequence so that the error comes out +% nicely formatted. For example, if the label \enquote{badpkg} adds +% some code that references argument \verb|#3| in the hook +% \enquote{foo}, which takes only two arguments, the error will be: +%\begin{verbatim} +% ! Illegal parameter number in definition of hook 'foo'. +% (hooks) Offending label: 'badpkg'. +% +% 3 +%\end{verbatim} +% At the point of this definition, the error is raised if the code +% happens to reference an invalid argument. If it was possible to +% detect that this definition raised no error, the next step would be +% unnecessary. We'll do all this in a group so this weird definition +% doesn't leak out, and set \cs{tex_escapechar:D} to $-1$ so this hack +% shows up extra nice in the case of an error. +% \begin{macrocode} + \group_begin: + \int_set:Nn \tex_escapechar:D { -1 } + \cs_set:cpn + { + hook~'#1'. ^^J + (hooks) \prg_replicate:nn { 13 } { ~ } + #2 % more message text + } + \exp_not:v { c_@@_#1_parameter_tl } + {##2} + \group_end: +% \end{macrocode} +% This next macro, with a much less fabulous name, takes always nine +% arguments, and it just transfers the code \verb|##2| under the label +% \verb|##1| to the temporary property list. The first \meta{n} +% arguments are taken from \cs[no-index]{l_@@_tmpa_tl}, and the other +% $9-\meta{n}$ taken from \cs[no-index]{l_@@_tmpb_tl} (which contains +% twice as many \verb|#| tokens as the former). Then, +% \cs{@@_double_hashes:n} is used to double non-argument hashes, and +% expand the \cs{c_@@_hash_tl} and \cs{c_@@_hashes_tl} to the actual +% parameter tokens. +% \begin{macrocode} + \cs_set:Npn \exp_not:N \@@_tmp:w + \exp_not:V \c_@@_nine_parameters_tl + { + \prop_put:Nne \exp_not:N \l_@@_work_prop + {##1} { \exp_not:N \@@_double_hashes:n {##2} } + } +% \end{macrocode} +% This next macro, with a much less fabulous name, takes always nine +% arguments, and it just transfers the code \verb|##2| under the label +% \verb|##1| to the temporary property list. The first \meta{n} +% arguments are taken from \cs[no-index]{l_@@_tmpa_tl}, and the other +% $9-\meta{n}$ taken from \cs[no-index]{l_@@_tmpb_tl} (which contains +% twice as many \verb|#| tokens as the former). Then, +% \cs{@@_double_hashes:n} is used to double non-argument hashes, and +% expand the \cs{c_@@_hash_tl} and \cs{c_@@_hashes_tl} to the actual +% parameter tokens. +% \begin{macrocode} + \exp_not:N \@@_tmp:w + \exp_not:V \l_@@_tmpa_tl + \exp_args:No \exp_not:o + { \exp_after:wN \@@_tmp:w \l_@@_tmpb_tl } + } + } +\cs_new_eq:NN \@@_normalise_fn:nn ? +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_normalise_code_pool:n} +% {Hooks~with~args} +%\cs_undefine:N \@@_normalise_code_pool:n +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\@@_cs_if_empty:c} +% Check if the expansion of a control sequence is empty by looking at +% its replacement text. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_cs_if_empty:c} +% {Hooks~with~args} +\prg_new_conditional:Npnn \@@_cs_if_empty:c #1 { p, T, F, TF } + { + \if:w \scan_stop: \@@_replacement_spec:c {#1} \scan_stop: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +\cs_new:Npn \@@_replacement_spec:c #1 + { + \exp_args:Nc \token_if_macro:NT {#1} + { \cs_replacement_spec:c {#1} } + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_cs_if_empty:c} +% {Hooks~with~args} +%\cs_undefine:N \@@_cs_if_empty:c +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_braced_cs_parameter:n} +% \begin{macro}{\@@_braced_hidden_loop:w} +% \begin{macro}{\@@_cs_parameter_count:N} +% \begin{macro}{\@@_cs_parameter_count:w,\@@_cs_end:w} +% Looks at the \meta{parameter text} of a control sequence, and +% returns a run of \enquote{hidden} braced parameters for that macro. +% This works as long as the macros take a simple run of zero to nine +% arguments. The parameters are \enquote{hidden} because the +% parameter tokens are returned inside \cs{c_@@_hash_tl} instead of +% explicitly, so that \cs{@@_double_hashes:n} won't touch these. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_braced_cs_parameter:n} +% {Hooks~with~args} +\cs_new:Npn \@@_braced_cs_parameter:n #1 + { + \exp_last_unbraced:Ne \@@_braced_hidden_loop:w + { \exp_args:Nc \@@_cs_parameter_count:N {#1} } ? \s_@@_mark + } +\cs_new:Npn \@@_braced_hidden_loop:w #1 + { + \if:w ? #1 + \@@_use_i_delimit_by_s_mark:nw + \fi: + { \exp_not:N \c_@@_hash_tl #1 } + \@@_braced_hidden_loop:w + } +\cs_new:Npn \@@_cs_parameter_count:N #1 + { + \exp_last_unbraced:Nf \@@_cs_parameter_count:w + { \token_if_macro:NT #1 { \cs_parameter_spec:N #1 } } + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + \s_@@_mark + } +\cs_new:Npn \@@_cs_parameter_count:w #1#2 #3#4 #5#6 #7#8 + { #2 #4 #6 #8 \@@_cs_parameter_count:w } +\cs_new:Npn \@@_cs_end:w #1 \s_@@_mark { } +%\EndIncludeInRelease +% \end{macrocode} +% +% This function can't be undefined when rolling back because it's used +% at the end of this module to adequate the hook data structures to +% previous versions. +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_braced_cs_parameter:n} +% {Hooks~with~args} +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_braced_parameter:n} +% \begin{macro}{\@@_braced_real_loop:w} +% This one is used in simpler cases, where no special handling of +% hashes is required. This is used only inside +% \cs{@@_initialize_hook_code:n}, so it assumes +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} is defined, but should +% work otherwise. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_braced_parameter:n} +% {Hooks~with~args} +\cs_new:Npn \@@_braced_parameter:n #1 + { + \if_case:w + \int_eval:n + { \exp_args:Nv \str_count:n { c_@@_#1_parameter_tl } / 3 } + \exp_stop_f: + \or: {##1} + \or: {##1} {##2} + \or: {##1} {##2} {##3} + \or: {##1} {##2} {##3} {##4} + \or: {##1} {##2} {##3} {##4} {##5} + \or: {##1} {##2} {##3} {##4} {##5} {##6} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} {##9} + \else: + \msg_expandable_error:nnn { latex2e } { should-not-happen } + { Invalid~parameter~spec. } + \fi: + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_braced_parameter:n} +% {Hooks~with~args} +%\cs_undefine:N \@@_braced_parameter:n +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parameter:n} +% This is just a shortcut to \verb|e|- or \verb|f|-expand to the +% \meta{parameter text} of the hook. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_parameter:n} +% {Hooks~with~args} +\cs_new:Npn \@@_parameter:n #1 + { + \cs:w c_@@_ + \tl_if_exist:cTF { c_@@_#1_parameter_tl } + { #1_parameter } { empty } + _tl \cs_end: + } +\cs_new:Npn \@@_generic_parameter:n #1 + { \@@_generic_parameter:w #1 / / / \s_@@_mark } +\cs_new:Npn \@@_generic_parameter:w #1 / #2 / #3 / #4 \s_@@_mark + { + \cs_if_exist_use:cF { c_@@_parameter_#1/./#3_tl } + { \c_@@_empty_tl } + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_parameter:n} +% {Hooks~with~args} +%\cs_undefine:N \@@_parameter:n +%\cs_undefine:N \@@_generic_parameter:n +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Setting rules for hooks code} +% +% \begin{macro}{ % \g_@@_??_code_prop, % \@@~??, % \g_@@_??_reversed_tl, +% \c_@@_??_parameter_tl, % } % % Initially these variables simply used an empty ``label'' name (not @@ -3597,11 +4957,11 @@ % lot, the code should be fast, so this is not done with \texttt{c} % expansion in the code later on. % -% \cs{@@\textvisiblespace??} isn't used, but it has to be defined to trick -% the code into thinking that \texttt{??} is actually a hook. +% \cs{@@\textvisiblespace??} isn't used, but it has to be defined to +% trick the code into thinking that \texttt{??} is actually a hook. % \begin{macrocode} -\prop_new:c {g_@@_??_code_prop} -\prop_new:c {@@~??} +\prop_new:c { g_@@_??_code_prop } +\prop_new:c { @@~?? } % \end{macrocode} % % Default rules are always given in normal ordering (never in @@ -3610,11 +4970,23 @@ % \texttt{after} becomes \texttt{before}) % because those rules are applied first and then the order is reversed. % \begin{macrocode} -\tl_new:c {g_@@_??_reversed_tl} +\tl_new:c { g_@@_??_reversed_tl } % \end{macrocode} -% \end{macro} % -% \subsection{Setting rules for hooks code} +% The parameter text for the \enquote{default} hook is empty. +% \changes{v1.1a}{2023/04/06} +% {Token list added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\c_@@_??_parameter_tl} +% {Hooks~with~args} +\tl_const:cn { c_@@_??_parameter_tl } { } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\c_@@_??_parameter_tl} +% {Hooks~with~args} +%\cs_undefine:c { c_@@_??_parameter_tl } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % \begin{macro}{\hook_gset_rule:nnnn} % \begin{macro}{\@@_gset_rule:nnnn} @@ -3645,13 +5017,13 @@ \@@_deprecated_generic_warn:n {#1} \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn {#1} {#2} {#3} {#4} - \@@_clean_to_scan:w + \@@_use_none_delimit_by_s_mark:w } \@@_if_execute_immediately:nT {#1} { \msg_error:nnnnnn { hooks } { rule-too-late } {#1} {#2} {#3} {#4} - \@@_clean_to_scan:w + \@@_use_none_delimit_by_s_mark:w } % \end{macrocode} % First we ensure the basic data structure of the hook exists: @@ -3840,44 +5212,82 @@ % \begin{macro}{\@@_initialize_all:} % Initialize all known hooks (at \verb=\begin{document}=), i.e., % update the fast execution token lists to hold the necessary code -% in the right order. +% in the right order. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_initialize_all: { +%\IncludeInRelease{2023/06/01}{\@@_initialize_all:} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_initialize_all: + { % \end{macrocode} % First we change \cs{@@_update_hook_code:n} which so far was a % no-op to now initialize one hook. This way any later updates to % the hook will run that code and also update the execution token % list. % \begin{macrocode} - \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n + \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n % \end{macrocode} % Now we loop over all hooks that have been defined and update each -% of them. +% of them. Here we have to determine if the hook has arguments so +% that auxiliaries know what to do with hashes. We look at +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl}, if it has any +% parameters, and set \verb|replacing_args| accordingly. % \begin{macrocode} - \@@_debug:n { \prop_gclear:N \g_@@_used_prop } - \seq_map_inline:Nn \g_@@_all_seq + \@@_debug:n { \prop_gclear:N \g_@@_used_prop } + \seq_map_inline:Nn \g_@@_all_seq { + \tl_if_empty:cTF { c_@@_##1_parameter_tl } + { \@@_replacing_args_false: } + { \@@_replacing_args_true: } \@@_update_hook_code:n {##1} + \@@_replacing_args_reset: } % \end{macrocode} % If we are debugging we show results hook by hook for all hooks % that have data. % \begin{macrocode} - \@@_debug:n - { \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} - \prop_map_inline:Nn \g_@@_used_prop - { \iow_term:x{^^J~ ##1~ ->~ - \exp_not:v {@@~##1}~ } - } - } + \@@_debug:n + { + \iow_term:x { ^^J All~initialized~(non-empty)~hooks: } + \prop_map_inline:Nn \g_@@_used_prop + { + \iow_term:x + { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ } + } + } % \end{macrocode} % After all hooks are initialized we change the ``use'' to just % call the hook code and not initialize it (as it was done in the % preamble. % \begin{macrocode} - \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n - \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n -} + \@@_post_initialization_defs: + } +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_initialize_all:} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_initialize_all: +% { +% \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n +% \@@_debug:n { \prop_gclear:N \g_@@_used_prop } +% \seq_map_inline:Nn \g_@@_all_seq +% { \@@_update_hook_code:n {##1} } +% \@@_debug:n +% { +% \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} +% \prop_map_inline:Nn \g_@@_used_prop +% { +% \iow_term:x +% { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ } +% } +% } +% \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n +% \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -3887,7 +5297,11 @@ % the preamble this is selectively done in case a hook gets used % and at \verb=\begin{document}= this is done for all hooks and % afterwards only if the hook code changes. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_initialize_hook_code:n} +% {Hooks~with~args} \cs_new_protected:Npn \@@_initialize_hook_code:n #1 { \@@_debug:n @@ -3915,10 +5329,15 @@ { \prop_if_empty:cTF { g_@@_#1_code_prop } { - \@@_tl_gset:co { @@~#1 } + \@@_code_gset:ne {#1} { - \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: - \cs:w @@_next~#1 \cs_end: +% \end{macrocode} +% The hook may take arguments, so we add a run of braced parameters +% after the \verb|_next| and \verb|_toplevel| macros, so that the +% arguments passed to the hook are forwarded to them. +% \begin{macrocode} + \exp_not:c { @@_toplevel~#1 } \@@_braced_parameter:n {#1} + \exp_not:c { @@_next~#1 } \@@_braced_parameter:n {#1} } } { @@ -3958,6 +5377,42 @@ } } } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_initialize_hook_code:n} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_initialize_hook_code:n #1 +% { +% \@@_debug:n +% { \iow_term:x { ^^J Update~code~for~hook~'#1' \on@line :^^J } } +% \@@_include_legacy_code_chunk:n {#1} +% \@@_if_usable:nT {#1} +% { +% \prop_if_empty:cTF { g_@@_#1_code_prop } +% { +% \@@_tl_gset:co { @@~#1 } +% { +% \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: +% \cs:w @@_next~#1 \cs_end: +% } +% } +% { +% \@@_if_reversed:nTF {#1} +% { \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:Nn \@@_tl_gput_right:Nn +% \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } +% \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } +% \@@_initialize_single:ccn +% { @@~#1 } { g_@@_#1_labels_clist } {#1} +% \@@_debug:n +% { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1} { } } +% } +% } +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4034,7 +5489,12 @@ % ^^A #1 <- \@@~#1 % ^^A #2 <- \g_@@_#1_labels_clist % ^^A #3 <- #1 +% +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_initialize_single:NNn} +% {Hooks~with~args} \cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 { % \end{macrocode} @@ -4181,15 +5641,103 @@ % 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: } +% chunk added). The |next| code is always added last (to the right). +% The hook may take arguments, so we add a run of braced parameters +% after the \verb|_next| and \verb|_toplevel| macros, so that the +% arguments passed to the hook are forwarded to them. +% \begin{macrocode} + \exp_args:NNe \@@_tl_gput:Nn #1 + { \exp_not:c { @@_toplevel~#3 } \@@_braced_parameter:n {#3} } + \@@_tl_gput_right:Ne #1 + { \exp_not:c { @@_next~#3 } \@@_braced_parameter:n {#3} } + \use:e + { + \cs_gset:cpn { @@~#3 } \use:c { c_@@_#3_parameter_tl } + { \exp_not:V #1 } + } } % \end{macrocode} % % \begin{macrocode} \cs_generate_variant:Nn \@@_initialize_single:NNn { cc } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_initialize_single:NNn} +% {Hooks~with~args} +%\cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 +% { +% \seq_clear:N \l_@@_labels_seq +% \int_zero:N \l_@@_labels_int +% \tl_set:Nn \l_@@_cur_hook_tl {#3} +% \prop_map_inline:Nn \l_@@_work_prop +% { +% \int_incr:N \l_@@_labels_int +% \seq_put_right:Nn \l_@@_labels_seq {##1} +% \@@_tl_set:cn { \@@_tl_csname:n {##1} } { 0 } +% \seq_clear_new:c { \@@_seq_csname:n {##1} } +% } +% \prop_map_inline:Nn \l_@@_work_prop +% { +% \prop_map_inline:Nn \l_@@_work_prop +% { +% \@@_if_label_case:nnnnn {##1} {####1} +% { \prop_map_break: } +% { \@@_apply_label_pair:nnn {##1} {####1} } +% { \@@_apply_label_pair:nnn {####1} {##1} } +% {#3} +% } +% } +% \@@_debug:n { \@@_debug_label_data:N \l_@@_work_prop } +% \tl_set:Nn \l_@@_rear_tl { 0 } +% \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } +% \seq_map_inline:Nn \l_@@_labels_seq +% { +% \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +% { +% \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } }{##1} +% \tl_set:Nn \l_@@_rear_tl {##1} +% } +% } +% \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { 0 } } +% \@@_tl_gclear:N #1 +% \clist_gclear:N #2 +% \bool_while_do:nn { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } } +% { +% \int_decr:N \l_@@_labels_int +% \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl +% \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl +% \@@_clist_gput:NV #2 \l_@@_front_tl +% \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } +% \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } } +% { +% \tl_set:cx { \@@_tl_csname:n {##1} } +% { \int_eval:n +% { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } +% } +% \int_compare:nNnT +% { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +% { +% \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} +% \tl_set:Nn \l_@@_rear_tl {##1} +% } +% } +% \tl_set_eq:Nc \l_@@_front_tl +% { \@@_tl_csname:n { \l_@@_front_tl } } +% } +% \int_compare:nNnF \l_@@_labels_int = 0 +% { +% \iow_term:x{====================} +% \iow_term:x{Error:~ label~ rules~ are~ incompatible:} +% \@@_debug_label_data:N \l_@@_work_prop +% \iow_term:x{====================} +% } +% \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } +% \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } +% } +%\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4444,7 +5992,11 @@ { \@@_log_cmd:x { >~\@spaces #1 } } % \end{macrocode} % +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_log:nN} +% {Hooks~with~args} \cs_new_protected:Npn \@@_log:nN #1 #2 { \@@_if_deprecated_generic:nT {#1} @@ -4455,7 +6007,20 @@ } \@@_preamble_hook:n {#1} \@@_log_cmd:x - { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': } + { + ^^J ->~The~ + \@@_if_generic:nT {#1} { generic~ } + hook~'#1' + \@@_if_disabled:nF {#1} + { + \exp_args:Nf \@@_print_args:nn {#1} + { + \int_eval:n + { \str_count:e { \@@_parameter:n {#1} } / 3 } + } + } + : + } % \end{macrocode} % % \begin{macrocode} @@ -4471,7 +6036,12 @@ { \@@_log_line_indent:x { --- } } { \prop_map_inline:cn { g_@@_#1_code_prop } - { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } + { + \exp_after:wN \cs_set:Npn \exp_after:wN \@@_tmp:w + \c_@@_nine_parameters_tl {##2} + \@@_log_line_indent:x + { ##1~->~\cs_replacement_spec:N \@@_tmp:w } + } } % \end{macrocode} % @@ -4485,9 +6055,9 @@ } \@@_log_line_indent:x { - \tl_if_empty:cTF { @@_toplevel~#1 } + \@@_cs_if_empty:cTF { @@_toplevel~#1 } { --- } - { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } + { -> ~ \cs_replacement_spec:c { @@_toplevel~#1 } } } % \end{macrocode} % @@ -4495,7 +6065,7 @@ \@@_log_line:x { Extra~code~for~next~invocation: } \@@_log_line_indent:x { - \tl_if_empty:cTF { @@_next~#1 } + \@@_cs_if_empty:cTF { @@_next~#1 } { --- } % \end{macrocode} % @@ -4503,7 +6073,10 @@ % the first tokens (the code to clear itself) so we call a helper % command to get rid of them. % \begin{macrocode} - { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } } + { + -> ~ \exp_last_unbraced:Nf \@@_log_next_code:w + { \cs_replacement_spec:c { @@_next~#1 } } + } } % \end{macrocode} % @@ -4549,7 +6122,7 @@ \@spaces \clist_if_empty:cTF { g_@@_#1_labels_clist } { --- } - { \clist_use:cn {g_@@_#1_labels_clist} { ,~ } } + { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } } } } { @@ -4563,15 +6136,139 @@ } } } +%\EndIncludeInRelease +% +%\IncludeInRelease{2020/10/01}{\@@_log:nN} +% {Hooks~with~args} +%\cs_new_protected:Npn \@@_log:nN #1 #2 +% { +% \@@_if_deprecated_generic:nT {#1} +% { +% \@@_deprecated_generic_warn:n {#1} +% \@@_do_deprecated_generic:Nn \@@_log:nN {#1} #2 +% \exp_after:wN \use_none:nnnnnnnnn \use_none:nnnnn +% } +% \@@_preamble_hook:n {#1} +% \@@_log_cmd:x +% { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': } +% \@@_if_usable:nF {#1} +% { \@@_log_line:x { The~hook~is~not~declared. } } +% \@@_if_disabled:nT {#1} +% { \@@_log_line:x { The~hook~is~disabled. } } +% \hook_if_empty:nTF {#1} +% { #2 { The~hook~is~empty } } +% { +% \@@_log_line:x { Code~chunks: } +% \prop_if_empty:cTF { g_@@_#1_code_prop } +% { \@@_log_line_indent:x { --- } } +% { +% \prop_map_inline:cn { g_@@_#1_code_prop } +% { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } +% } +% \@@_log_line:x +% { +% Document-level~(top-level)~code +% \@@_if_usable: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 } } +% } +% \@@_log_line:x { Extra~code~for~next~invocation: } +% \@@_log_line_indent:x +% { +% \tl_if_empty:cTF { @@_next~#1 } +% { --- } +% { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } } +% } +% \@@_log_line:x { Rules: } +% \bool_set_true:N \l_@@_tmpa_bool +% \@@_list_rules:nn {#1} +% { +% \bool_set_false:N \l_@@_tmpa_bool +% \@@_log_line_indent:x +% { +% ##2~ with~ +% \str_if_eq:nnT {##3} {??} { default~ } +% relation~ ##1 +% } +% } +% \bool_if:NT \l_@@_tmpa_bool +% { \@@_log_line_indent:x { --- } } +% \bool_lazy_and:nnTF +% { \@@_if_usable_p:n {#1} } +% { ! \hook_if_empty_p:n {#1} } +% { +% \@@_log_line:x +% { +% Execution~order +% \bool_if:NTF \l_@@_tmpa_bool +% { \@@_if_reversed:nT {#1} { ~(after~reversal) } } +% { ~(after~ +% \@@_if_reversed:nT {#1} { reversal~and~ } +% applying~rules) +% } : +% } +% #2 % \tl_show:n +% { +% \@spaces +% \clist_if_empty:cTF { g_@@_#1_labels_clist } +% { --- } +% { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } } +% } +% } +% { +% \@@_log_line:x { Execution~order: } +% #2 +% { +% \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1} +% { code~pool~is~empty } +% { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} } +% } +% } +% } +% } +%\EndIncludeInRelease % \end{macrocode} % % \begin{macro}{\@@_log_next_code:n} % To display the code for next invocation only (i.e., from -% \cs{AddToHookNext} we have to remove the first two tokens at the -% front which are \cs{tl_gclear:N} and the token list to clear. +% \cs{AddToHookNext} we have to remove the string +% \cs{@@_clear_next:n}\Arg{hook}, so the simplest is to use a macro +% delimited by a \verb|}|$_12$. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_log_next_code:n} +% {Hooks~with~args} +\exp_last_unbraced:NNNNo +\cs_new:Npn \@@_log_next_code:w #1 \c_right_brace_str { } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_log_next_code:n} +% {Hooks~with~args} +%\cs_gset:Npn \@@_log_next_code:n #1 +% { \exp_args:No \tl_to_str:n { \use_none:nn #1 } } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_print_args:n} +% Pretty-prints the number of arguments of a hook. % \begin{macrocode} -\cs_new:Npn \@@_log_next_code:n #1 - { \exp_args:No \tl_to_str:n { \use_none:nn #1 } } +\cs_new:Npn \@@_print_args:nn #1 #2 + { + \int_compare:nNnT {#2} > { 0 } + { + \@@_if_declared:nT {#1} { \use_none:nnn } + \@@_if_cmd_hook:nT {#1} + { \use_i:nnn { ~ (unknown ~ } } + \use:n { ~ (#2 ~ } + argument \int_compare:nNnT {#2} > { 1 } { s } ) + } + } % \end{macrocode} % \end{macro} % @@ -4656,15 +6353,34 @@ % \subsection{Specifying code for next invocation} % % \begin{macro}{\hook_gput_next_code:nn} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_gput_next_code_with_args:nn} (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \hook_gput_next_code:nn #1 - { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +%\IncludeInRelease{2023/06/01}{\hook_gput_next_code:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \hook_gput_next_code:nn #1 #2 + { + \@@_replacing_args_false: + \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} {#2} + \@@_replacing_args_reset: + } +\cs_new_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 + { + \@@_replacing_args_true: + \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} {#2} + \@@_replacing_args_reset: + } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\hook_gput_next_code:nn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \hook_gput_next_code:nn #1 +% { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +%\cs_gset_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_gput_next_code:nn, -% \@@_gput_next_do:nn, -% \@@_gput_next_do:Nnn} +% \begin{macro}{\@@_gput_next_code:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 { @@ -4672,20 +6388,17 @@ { \msg_error:nnn { hooks } { hook-disabled } {#1} } { \@@_if_structure_exist:nTF {#1} - { \@@_gput_next_do:nn {#1} {#2} } - { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } + { \@@_gput_next_do:nn } + { \@@_try_declaring_generic_next_hook:nn } + {#1} {#2} } } % \end{macrocode} +% \end{macro} % -% \begin{macrocode} -\cs_new_protected:Npn \@@_gput_next_do:nn #1 - { - \exp_args:Nc \@@_gput_next_do:Nnn - { @@_next~#1 } {#1} - } -% \end{macrocode} -% First check if the ``next code'' token list is empty: if so we need +% \begin{macro}{\@@_gput_next_do:nn} +% Start by sanity-checking with \cs{@@_chk_args_allowed:nn}. +% Then check if the ``next code'' token list is empty: if so we need % to add a \cs{tl_gclear:c} to clear it, so the code lasts for one % usage only. The token list is cleared early so that nested usages % don't get lost. \cs{tl_gclear:c} is used instead of @@ -4694,38 +6407,74 @@ % that would make an infinite loop. Also in case the main code token % list is empty, the hook code has to be updated to add the next % execution token list. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \changes{v1.1c}{2023/04/19} +% {Initialise hook structure when adding 'next' code (gh/1052).} % \begin{macrocode} -\cs_new_protected:Npn \@@_gput_next_do:Nnn #1 #2 +%\IncludeInRelease{2023/06/01}{\@@_gput_next_do:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_gput_next_do:nn #1 { - \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 + \@@_init_structure:n {#1} + \@@_chk_args_allowed:nn {#1} { AddToHookNext } + \@@_cs_if_empty:cT { @@~#1 } + { \@@_update_hook_code:n {#1} } + \@@_cs_if_empty:cT { @@_next~#1 } + { \@@_next_gset:nn {#1} { \@@_clear_next:n {#1} } } + \@@_cs_gput_right:nnn { _next } {#1} } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_gput_next_do:nn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_gput_next_do:nn #1 +% { +% \exp_args:Nc \@@_gput_next_do:Nnn +% { @@_next~#1 } {#1} +% } +%\cs_gset_protected:Npn \@@_gput_next_do:Nnn #1 #2 +% { +% \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 +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% -% -% \begin{macro}{\hook_gclear_next_code:n,\@@_clear_next:n} +% \begin{macro}{\hook_gclear_next_code:n} % Discard anything set up for next invocation of the hook. % \changes{v1.0o}{2021/07/27}{Macro made public} % \begin{macrocode} \cs_new_protected:Npn \hook_gclear_next_code:n #1 { \@@_normalize_hook_args:Nn \@@_clear_next:n {#1} } -\cs_new_protected:Npn \@@_clear_next:n #1 - { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_clear_next:n} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_clear_next:n} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_clear_next:n #1 + { \@@_next_gset:nn {#1} { } } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_clear_next:n} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_clear_next:n #1 +% { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % % \subsection{Using the hook} % % \begin{macro}{\hook_use:n} % \begin{macro}[EXP]{\@@_use_initialized:n} -% \begin{macro}{\@@_use_undefined:w,\@@_use_end:} % \begin{macro}{\@@_preamble_hook:n} % \cs{hook_use:n} as defined here is used in the preamble, where % hooks aren't initialized by default. \cs{@@_use_initialized:n} is @@ -4750,24 +6499,50 @@ % \verb=\csname ...\endcsname= construct \cs{tl_if_exist:c} is % careful to avoid this. % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\hook_use:n} -% {Standardise~generic~hook~names} +%\IncludeInRelease{2023/06/01}{\hook_use:n} +% {Hooks~with~args} \cs_new_protected:Npn \hook_use:n #1 { - \tl_if_exist:cT { @@~#1 } - { - \@@_preamble_hook:n {#1} - \cs:w @@~#1 \cs_end: - } + \@@_preamble_hook:n {#1} + \@@_use_initialized:n {#1} } \cs_new:Npn \@@_use_initialized:n #1 { \if_cs_exist:w @@~#1 \cs_end: - \cs:w @@~#1 \exp_after:wN \cs_end: + \cs:w @@~#1 \use_i:nn \fi: + \use_none:n + \cs_end: } \cs_new_protected:Npn \@@_preamble_hook:n #1 - { \@@_initialize_hook_code:n {#1} } + { + \if_cs_exist:w @@~#1 \cs_end: + \@@_initialize_hook_code:n {#1} + \fi: + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2021/11/15}{\hook_use:n} +% {Standardise~generic~hook~names} +%\cs_new_protected:Npn \hook_use:n #1 +% { +% \tl_if_exist:cT { @@~#1 } +% { +% \@@_preamble_hook:n {#1} +% \cs:w @@~#1 \cs_end: +% } +% } +%\cs_new:Npn \@@_use_initialized:n #1 +% { +% \if_cs_exist:w @@~#1 \cs_end: +% \cs:w @@~#1 \exp_after:wN \cs_end: +% \fi: +% } +%\cs_new_protected:Npn \@@_preamble_hook:n #1 +% { \@@_initialize_hook_code:n {#1} } +%\cs_new:Npn \hook_use:nnw #1 { } %\EndIncludeInRelease % \end{macrocode} % @@ -4799,13 +6574,69 @@ %\cs_new_protected:Npn \@@_preamble_hook:n #1 % { \@@_initialize_hook_code:n {#1} } %\cs_new_eq:NN \@@_use_end: \cs_end: +%\cs_new:Npn \hook_use:nnw #1 { } %\EndIncludeInRelease % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +% +% \begin{macro}{\hook_use:nnw} +% \begin{macro}[EXP]{\@@_use_initialized:nnw} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_use:nnw} (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_use:nnw} +% {Hooks~with~args} +\cs_new_protected:Npn \hook_use:nnw #1 + { + \@@_preamble_hook:n {#1} + \@@_use_initialized:nnw {#1} + } +\cs_new:Npn \@@_use_initialized:nnw #1 #2 + { + \cs:w + \if_cs_exist:w @@~#1 \cs_end: + @@~#1 + \else: + use_none: \prg_replicate:nn {#2} { n } + \fi: + \cs_end: + } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\hook_use:nnw} +% {Hooks~with~args} +%\cs_gset:Npn \hook_use:nnw #1 #2 +% { \use:c { use_none: \prg_replicate:nn {#2} { n } } } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@@_post_initialization_defs:} +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_post_initialization_defs:} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_post_initialization_defs: + { + \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n + \cs_gset_eq:NN \hook_use:nnw \@@_use_initialized:nnw + \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n + \cs_gset_eq:NN \@@_post_initialization_defs: \prg_do_nothing: + } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_post_initialization_defs:} +% {Hooks~with~args} +%\cs_undefine:N \@@_post_initialization_defs: +%\EndIncludeInRelease +% \end{macrocode} % \end{macro} % +% % \begin{macro}[EXP]{\@@_use:wn} % \begin{macro}{\@@_try_file_hook:n,\@@_if_usable_use:n} % \cs{@@_use:wn} does a quick check to test if the current hook is a @@ -4861,8 +6692,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\hook_use_once:n} -% \begin{macro}{\@@_use_once:n} +% \begin{macro}{\hook_use_once:n,\hook_use_once:nnw} % For hooks that can and should be used only once we have a special % use command that further inhibits the hook from getting more code % added to it. This has the effect that any @@ -4874,20 +6704,80 @@ % documented to not trim spaces. % % \changes{v1.0r}{2021/09/06}{Clean up after \cs{UseOneTimeHook} (gh/606)} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_use_once:nnw} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_use_once:nnw} +% {Hooks~with~args} \cs_new_protected:Npn \hook_use_once:n #1 { \@@_if_execute_immediately:nF {#1} - { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } } + { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } { 0 } } } -\cs_new_protected:Npn \@@_use_once:n #1 +\cs_new_protected:Npn \hook_use_once:nnw #1 #2 + { + \@@_if_execute_immediately:nF {#1} + { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } {#2} } + } +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_use_once:nnw} +% {Hooks~with~args} +%\cs_gset_protected:Npn \hook_use_once:n #1 +% { +% \@@_if_execute_immediately:nF {#1} +% { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } } +% } +%\cs_gset:Npn \hook_use_once:nnw #1 #2 +% { \use:c { use_none: \prg_replicate:nn {#2} { n } } } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macro}{\@@_use_once:nn} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_use_once:nn} +% {Hooks~with~args} +\cs_new_protected:Npn \@@_use_once:nn #1 #2 { \@@_preamble_hook:n {#1} \@@_use_once_set:n {#1} - \@@_use_initialized:n {#1} - \@@_use_once_clear:n {#1} +% \end{macrocode} +% When a hook has arguments, the call to \cs{@@_use_initialized:n}, +% should be the very last thing to happen, otherwise the arguments +% grabbed will be wrong. So, to clean up after the hook we need to +% cheat a bit and sneak the cleanup code at the end of the hook, +% along with the next execution code. +% \begin{macrocode} + \@@_replacing_args_false: + \@@_cs_gput_right:nnn { _next } {#1} { \@@_use_once_clear:n {#1} } + \@@_replacing_args_reset: + \@@_if_usable:nTF {#1} + { \@@_use_initialized:n {#1} } + { + \int_compare:nNnT {#2} > { 0 } + { \use:c { use_none: \prg_replicate:nn {#2} { n } } } + } } +%\EndIncludeInRelease +% +%\IncludeInRelease{2020/10/01}{\@@_use_once:nn} +% {Hooks~with~args} +%\cs_gset_protected:Npn \@@_use_once:n #1 +% { +% \@@_preamble_hook:n {#1} +% \@@_use_once_set:n {#1} +% \@@_use_initialized:n {#1} +% \@@_use_once_clear:n {#1} +% } +%\cs_undefine:N \@@_use_once:nn +%\EndIncludeInRelease % \end{macrocode} +% \end{macro} % % \begin{macro}{\@@_use_once_set:n} % \begin{macro}{\@@_use_once_clear:n} @@ -4900,43 +6790,60 @@ % \cs{hook_use_once:n} will expand to nothing. % \changes{v1.0r}{2021/09/06}{Clean up after \cs{UseOneTimeHook} (gh/606)} % \changes{v1.0u}{2022/05/13}{Check if prop exists to avoid l3debug error} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_use_once_clear:n} +% {Hooks~with~args} \cs_new_protected:Npn \@@_use_once_set:n #1 { \@@_tl_gset:cn { g_@@_#1_reversed_tl } { I } } \cs_new_protected:Npn \@@_use_once_clear:n #1 { - \@@_tl_gclear:c { @@~#1 } - \@@_tl_gclear:c { @@_next~#1 } - \@@_tl_gclear:c { @@_toplevel~#1 } + \@@_code_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } + \@@_toplevel_gset:nn {#1} { } \prop_gclear_new:c { g_@@_#1_code_prop } } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@@_use_once_clear:n} +% {Hooks~with~args} +%\cs_new_protected:Npn \@@_use_once_clear:n #1 +% { +% \@@_tl_gclear:c { @@~#1 } +% \@@_tl_gclear:c { @@_next~#1 } +% \@@_tl_gclear:c { @@_toplevel~#1 } +% \prop_gclear_new:c { g_@@_#1_code_prop } +% } +%\EndIncludeInRelease % \end{macrocode} -% \end{macro} -% \end{macro} % \end{macro} % \end{macro} % % \begin{macro}[pTF]{\@@_if_execute_immediately:n} -% To check whether the code being added should be executed immediately (that -% is, if the hook is a one-time hook), we check if it's usable (it -% can't be one-time if it was not already usable), then we check that +% To check whether the code being added should be executed immediately +% (that is, if the hook is a one-time hook), we check if % \cs[no-index]{g_@@_\meta{hook}_reversed_tl} is |I|. The gymnastics % around \cs{if:w} is there to allow the |reversed| token list to be % empty. % \changes{v1.0r}{2021/09/06}{Macro added (gh/606)} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_execute_immediately:n #1 { T, F, TF } { - \@@_if_usable:nTF {#1} - { - \exp_after:wN \@@_clean_to_scan:w - \if:w I \cs:w g_@@_#1_reversed_tl \cs_end: - \s_@@_mark \prg_return_true: - \else: - \s_@@_mark \prg_return_false: + \exp_after:wN \@@_use_none_delimit_by_s_mark:w + \if:w I + \if_cs_exist:w g_@@_#1_reversed_tl \cs_end: + \cs:w g_@@_#1_reversed_tl \exp_after:wN \cs_end: \fi: - } - { \prg_return_false: } + X + \s_@@_mark \prg_return_true: + \else: + \s_@@_mark \prg_return_false: + \fi: } % \end{macrocode} % \end{macro} @@ -4963,30 +6870,57 @@ % % All other states can only be queried with internal tests as the % different states are irrelevant for package code. - +% % \begin{macro}[pTF]{\hook_if_empty:n} % Test if a hook is empty (that is, no code was added to that hook). % A \meta{hook} being empty means that all three of its % \cs{g_@@_\meta{hook}_code_prop}, its % \cs{@@_toplevel\textvisiblespace\meta{hook}} and its % \cs{@@_next\textvisiblespace\meta{hook}} are empty. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \changes{v1.1c}{2023/04/19} +% {Simpler and faster version (gh/1052).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\hook_if_empty:n} +% {Hooks~with~args} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } { - \@@_if_structure_exist:nTF {#1} - { - \bool_lazy_and:nnTF - { \prop_if_empty_p:c { g_@@_#1_code_prop } } - { - \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: } - } - { \prg_return_true: } + \if:w + T + \prop_if_exist:cT { g_@@_#1_code_prop } + { \prop_if_empty:cF { g_@@_#1_code_prop } { F } } + \@@_cs_if_empty:cF { @@_toplevel~#1 } { F } + \@@_cs_if_empty:cF { @@_next~#1 } { F } + T + \prg_return_true: + \else: + \prg_return_false: + \fi: } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\hook_if_empty:n} +% {Hooks~with~args} +%\prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } +% { +% \@@_if_structure_exist:nTF {#1} +% { +% \bool_lazy_and:nnTF +% { \prop_if_empty_p:c { g_@@_#1_code_prop } } +% { +% \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: } +% } +% { \prg_return_true: } +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4994,15 +6928,15 @@ % \begin{macro}[pTF]{\@@_if_usable:n} % A hook is usable if the % token list that stores the sorted code for that hook, -% \cs[no-index]{@@~\meta{hook}}, exists. The property list -% \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here +% \cs[no-index]{@@\textvisiblespace\meta{hook}}, exists. The property +% list \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here % because often it is necessary to add code to a hook without knowing % if such hook was already declared, or even if it will ever be % (for example, in case the package that defines it isn't loaded). % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_usable:n #1 { p , T , F , TF } { - \tl_if_exist:cTF { @@~#1 } + \cs_if_exist:cTF { @@~#1 } { \prg_return_true: } { \prg_return_false: } } @@ -5046,7 +6980,7 @@ % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_reversed:n #1 { p , T , F , TF } { - \exp_after:wN \@@_clean_to_scan:w + \exp_after:wN \@@_use_none_delimit_by_s_mark:w \if:w - \cs:w g_@@_#1_reversed_tl \cs_end: \s_@@_mark \prg_return_true: \else: @@ -5086,6 +7020,37 @@ % \end{macro} % \end{macro} % +% \begin{macro}[pTF]{\@@_if_cmd_hook:n} +% \begin{macro}[pTF]{\@@_if_cmd_hook:w} +% An internal conditional that checks if a given hook is a valid +% generic \hook{cmd} hook. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\@@_if_cmd_hook:n} +% {Hooks~with~args} +\prg_new_conditional:Npnn \@@_if_cmd_hook:n #1 { T } + { \@@_if_cmd_hook:w #1 / / / \s_@@_mark } +\cs_new:Npn \@@_if_cmd_hook:w #1 / #2 / #3 / #4 \s_@@_mark + { + \if:w Y + \str_if_eq:nnF {#1} { cmd } { N } + \tl_if_exist:cF { c_@@_generic_#1/./#3_tl } { N } + Y + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_if_cmd_hook:n} +% {Hooks~with~args} +%\cs_undefine:N \@@_if_cmd_hook:nT +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[pTF]{\@@_if_generic_reversed:n} % An internal conditional that checks if a name belongs to a generic % reversed hook. @@ -5103,6 +7068,50 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\@@_if_replacing_args:TF} +% \begin{macro}[EXP]{\@@_misused_if_replacing_args:nn} +% \begin{macro}{\@@_replacing_args_true:} +% \begin{macro}{\@@_replacing_args_false:} +% \begin{macro}{\@@_replacing_args_reset:} +% \begin{macro}{\g_@@_replacing_stack_seq} +% An internal conditional that checks if the code being added to the +% hook contains arguments. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +\seq_new:N \g_@@_replacing_stack_seq +\cs_new:Npn \@@_misused_if_replacing_args:nn #1 #2 + { + \msg_expandable_error:nnn { latex2e } { should-not-happen } + { Misused~\@@_if_replacing_args:. } + } +\cs_new:Npn \@@_if_replacing_args:TF + { \@@_misused_if_replacing_args:nn } +\cs_new_protected:Npn \@@_replacing_args_true: + { + \seq_gpush:No \g_@@_replacing_stack_seq + { \@@_if_replacing_args:TF } + \cs_set:Npn \@@_if_replacing_args:TF { \use_i:nn } + } +\cs_new_protected:Npn \@@_replacing_args_false: + { + \seq_gpush:No \g_@@_replacing_stack_seq + { \@@_if_replacing_args:TF } + \cs_set:Npn \@@_if_replacing_args:TF { \use_ii:nn } + } +\cs_new_protected:Npn \@@_replacing_args_reset: + { + \seq_gpop:NN \g_@@_replacing_stack_seq \l_@@_return_tl + \cs_gset_eq:NN \@@_if_replacing_args:TF \l_@@_return_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Messages} % % Hook errors are LaTeX kernel errors: @@ -5137,6 +7146,55 @@ Please~ use~ a~ different~ name~ for~ your~ hook.} % \end{macrocode} % +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{too-many-args} +% {Hooks~with~args} +% \end{macrocode} +% +% \changes{v1.1a}{2023/04/06} +% {Messages 'too-many-args', 'without-args' and 'one-time-args' added (hook-args).} +% \begin{macrocode} +\msg_new:nnnn { hooks } { too-many-args } + { Too~many~arguments~for~hook~'#1'. } + { + You~tried~to~declare~a~hook~with~#2~arguments,~but~a~ + hook~can~only~have~up~to~nine.~LaTeX~will~define~this~ + hook~with~nine~arguments. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { without-args } + { Hook~'#1'~has~no~arguments. } + { + You~tried~to~use~\iow_char:N\\#2WithArguments~ + on~a~hook~that~takes~no~arguments.\\ + Check~the~usage~of~the~hook~or~use~\iow_char:N\\#2~instead.\\ + \\ + LaTeX~will~use~\iow_char:N\\#2. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { one-time-args } + { You~can't~have~arguments~in~used~one-time~hook~'#1'. } + { + You~tried~to~use~\iow_char:N\\#2WithArguments~ + on~a~one-time~hook~that~has~already~been~used.~ + You~have~to~add~the~code~before~the~hook~is~used,~ + or~add~the~code~without~arguments~using~\iow_char:N\\#2~instead.\\ + \\ + LaTeX~will~use~\iow_char:N\\#2. + } +% \end{macrocode} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{too-many-args} +% {Hooks~with~args} +%\EndIncludeInRelease +% \end{macrocode} +% % % \begin{macrocode} \msg_new:nnnn { hooks } { hook-disabled } @@ -5278,17 +7336,49 @@ % \begin{macro}{\NewHook,\NewReversedHook,\NewMirroredHookPair} % Declaring new hooks \ldots % \begin{macrocode} -\NewDocumentCommand \NewHook { m }{ \hook_new:n {#1} } -\NewDocumentCommand \NewReversedHook { m }{ \hook_new_reversed:n {#1} } -\NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} } +\NewDocumentCommand \NewHook { m } + { \hook_new:n {#1} } +\NewDocumentCommand \NewReversedHook { m } + { \hook_new_reversed:n {#1} } +\NewDocumentCommand \NewMirroredHookPair { mm } + { \hook_new_pair:nn {#1}{#2} } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{ +% \NewHookWithArguments, +% \NewReversedHookWithArguments, +% \NewMirroredHookPairWithArguments +% } +% Declaring new hooks with arguments\ldots +% \changes{v1.1a}{2023/04/06} +% {Add \cs{NewHookWithArguments} (hook-args).} +% \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\NewHookWithArguments} +% {Hooks~with~args} +\NewDocumentCommand \NewHookWithArguments { mm } + { \hook_new_with_args:nn {#1} {#2} } +\NewDocumentCommand \NewReversedHookWithArguments { mm } + { \hook_new_reversed_with_args:nn {#1} {#2} } +\NewDocumentCommand \NewMirroredHookPairWithArguments { mmm } + { \hook_new_pair_with_args:nnn {#1} {#2} {#3} } +%\EndIncludeInRelease +%\IncludeInRelease{2023/06/01}{\NewHookWithArguments} +% {Hooks~with~args} +%\cs_new_protected:Npn \NewHookWithArguments #1 #2 { } +%\cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { } +%\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % % % % \begin{macrocode} -%\IncludeInRelease{2021/06/01}% -% {\hook_activate_generic:n}{Providing~hooks} +%\IncludeInRelease{2021/06/01}{\ActivateGenericHook} +% {Providing~hooks} % \end{macrocode} % % \begin{macro}{\ActivateGenericHook} @@ -5296,7 +7386,8 @@ % \changes{v1.0m}{2021/04/29}{Add \cs{ProvideHook} etc.} % \changes{v1.0o}{2021/08/02}{Change name} % \begin{macrocode} -\NewDocumentCommand \ActivateGenericHook { m }{ \hook_activate_generic:n {#1} } +\NewDocumentCommand \ActivateGenericHook { m } + { \hook_activate_generic:n {#1} } % \end{macrocode} % \end{macro} % @@ -5304,32 +7395,57 @@ % Disabling a generic hook. % \changes{v1.0o}{2021/08/02}{Change name} % \begin{macrocode} -\NewDocumentCommand \DisableGenericHook { m }{ \hook_disable_generic:n {#1} } +\NewDocumentCommand \DisableGenericHook { m } + { \hook_disable_generic:n {#1} } % \end{macrocode} % \end{macro} % % \begin{macrocode} %\EndIncludeInRelease -%\IncludeInRelease{2020/10/01} -% {\hook_activate_generic:n}{Providing~hooks} -% -%\def \ActivateGenericHook#1{} -% +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\ActivateGenericHook} +% {Providing~hooks} +%\def \ActivateGenericHook #1 { } +%\def \DisableGenericHook #1 { } %\EndIncludeInRelease % \end{macrocode} % % -% \begin{macro}{\AddToHook} +% \begin{macro}{\AddToHook,\AddToHookWithArguments} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{AddToHookWithArguments} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\AddToHookWithArguments} +% {Hooks~with~args} \NewDocumentCommand \AddToHook { m o +m } { \hook_gput_code:nnn {#1} {#2} {#3} } +\NewDocumentCommand \AddToHookWithArguments { m o +m } + { \hook_gput_code_with_args:nnn {#1} {#2} {#3} } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\AddToHookWithArguments} +% {Hooks~with~args} +%\cs_new_protected:Npn \AddToHookWithArguments #1 #2 #3 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% \begin{macro}{\AddToHookNext} +% \begin{macro}{\AddToHookNext,\AddToHookNextWithArguments} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{AddToHookNextWithArguments} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\AddToHookNextWithArguments} +% {Hooks~with~args} \NewDocumentCommand \AddToHookNext { m +m } { \hook_gput_next_code:nn {#1} {#2} } +\NewDocumentCommand \AddToHookNextWithArguments { m +m } + { \hook_gput_next_code_with_args:nn {#1} {#2} } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\AddToHookNextWithArguments} +% {Hooks~with~args} +%\cs_new_protected:Npn \AddToHookNextWithArguments #1 #2 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -5396,12 +7512,29 @@ % % % -% \begin{macro}{\UseHook,\UseOneTimeHook} +% \begin{macro}{ +% \UseHook, +% \UseOneTimeHook, +% \UseHookWithArguments, +% \UseOneTimeHookWithArguments, +% } % Avoid the overhead of \pkg{xparse} and its protection that we % don't want here (since the hook should vanish without trace if empty)! +% \changes{v1.1a}{2023/04/06} +% {Add \cs{UseHookWithArguments} (hook-args).} % \begin{macrocode} +%\IncludeInRelease{2023/06/01}{\UseHookWithArguments} +% {Hooks~with~args} \cs_new:Npn \UseHook { \hook_use:n } \cs_new:Npn \UseOneTimeHook { \hook_use_once:n } +\cs_new:Npn \UseHookWithArguments { \hook_use:nnw } +\cs_new:Npn \UseOneTimeHookWithArguments { \hook_use_once:nnw } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\UseHookWithArguments} +% {Hooks~with~args} +%\cs_new:Npn \UseHookWithArguments #1 #2 { } +%\cs_new:Npn \UseOneTimeHookWithArguments #1 #2 { } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -5462,7 +7595,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\IfHookExistsTF} +% \begin{macro}[EXP,int]{\IfHookExistsTF} % Marked for removal and no longer documented in the doc section! % \phoinline{\cs{IfHookExistsTF} is used in \texttt{jlreq.cls}, % \texttt{pxatbegshi.sty}, \texttt{pxeverysel.sty}, @@ -5484,7 +7617,7 @@ % \changes{v1.0p}{2021/08/20}{Added deprecation warnings for % old generic hook commands (gh/638)} % -% \begin{macro}{ +% \begin{macro}[int]{ % \hook_disable:n, % \hook_provide:n, % \hook_provide_reversed:n, @@ -5529,7 +7662,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[int]{ % \DisableHook, % \ProvideHook, % \ProvideReversedHook, @@ -5596,8 +7729,10 @@ %<@@=> % \end{macrocode} % -% \begin{macro}{\@expl@@@initialize@all@@, -% \@expl@@@hook@curr@name@pop@@} +% \begin{macro}[int]{ +% \@expl@@@initialize@all@@, +% \@expl@@@hook@curr@name@pop@@ +% } % % \InternalDetectionOff % \begin{macrocode} @@ -5620,8 +7755,8 @@ % to be for \cs{AddToHook} vice versa (gh/401)} % \begin{macrocode} % -%\IncludeInRelease{0000/00/00}% -% {lthooks}{The~hook~management}% +%\IncludeInRelease{0000/00/00}{lthooks} +% {The~hook~management}% % %\def \NewHook#1{} %\def \NewReversedHook#1{} @@ -5656,10 +7791,56 @@ %\long\def \IfHookEmptyTF #1#2#3{#2} % %\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +%<@@=hook> +% \end{macrocode} +% +% \changes{v1.1a}{2023/04/06} +% {Add dedicated rollback code to revert data structures (hook-args).} +% \begin{macrocode} +%\cs:w @@_rollback_tidying: \cs_end: +%\bool_lazy_and:nnT +% { \int_compare_p:nNn { \sourceLaTeXdate } > { 20230600 } } +% { \int_compare_p:nNn { \requestedLaTeXdate } < { 20230601 } } +% { +% \cs_gset_protected:Npn \@@_rollback_tidying: +% { +% \@latex@error { Rollback~code~executed~twice } +% { +% Something~went~wrong~(unless~this~was~ +% done~on~purpose~in~a~testing~environment). +% } +% \use_none:nnnn +% } +% \cs_set:Npn \@@_tmp:w #1 #2 +% { +% \@@_tl_gset:cx { @@#1~#2 } +% { +% \exp_args:No \exp_not:o +% { +% \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: +% { \@@_braced_cs_parameter:n { @@#1~#2 } } +% } +% } +% } +% \seq_map_inline:Nn \g_@@_all_seq +% { +% \exp_after:wN \cs_gset_nopar:Npn +% \cs:w g_@@_#1_code_prop \exp_args:NNo \exp_args:No +% \cs_end: { \cs:w g_@@_#1_code_prop \cs_end: } +% \@@_tmp:w { _toplevel } {#1} +% \@@_tmp:w { _next } {#1} +% } +% } \ExplSyntaxOff % % \end{macrocode} % +% \begin{macrocode} +%<@@=> +% \end{macrocode} % % \Finale % diff --git a/Master/texmf-dist/source/latex/base/lthyphen.dtx b/Master/texmf-dist/source/latex/base/lthyphen.dtx index b7cede11750..88d30c9ccac 100644 --- a/Master/texmf-dist/source/latex/base/lthyphen.dtx +++ b/Master/texmf-dist/source/latex/base/lthyphen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltidxglo.dtx b/Master/texmf-dist/source/latex/base/ltidxglo.dtx index 395fe839759..a2dc6b873ee 100644 --- a/Master/texmf-dist/source/latex/base/ltidxglo.dtx +++ b/Master/texmf-dist/source/latex/base/ltidxglo.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltkeys.dtx b/Master/texmf-dist/source/latex/base/ltkeys.dtx index edf12f7cb25..80c36d5cd9a 100644 --- a/Master/texmf-dist/source/latex/base/ltkeys.dtx +++ b/Master/texmf-dist/source/latex/base/ltkeys.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2021-2022 +% Copyright (C) 2021-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltlength.dtx b/Master/texmf-dist/source/latex/base/ltlength.dtx index f979dd4e239..10e4b671c81 100644 --- a/Master/texmf-dist/source/latex/base/ltlength.dtx +++ b/Master/texmf-dist/source/latex/base/ltlength.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltlists.dtx b/Master/texmf-dist/source/latex/base/ltlists.dtx index d0413dad082..d43df93a54e 100644 --- a/Master/texmf-dist/source/latex/base/ltlists.dtx +++ b/Master/texmf-dist/source/latex/base/ltlists.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -31,7 +31,7 @@ %<*driver> % \fi \ProvidesFile{ltlists.dtx} - [2020/12/05 v1.0t LaTeX Kernel (List Environments)] + [2023/05/17 v1.0t LaTeX Kernel (List Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltlists.dtx} @@ -68,7 +68,6 @@ % \begin{quote} % |\list|\marg{LABEL}\marg{COMMANDS} ... |\endlist| % \end{quote} -% % which can be invoked by the user as the list environment. The LABEL % argument specifies item labeling. COMMANDS contains commands for % changing the horizontal and vertical spacing parameters. @@ -187,7 +186,7 @@ % |\hsize|. % % Here are the parameters of a list that can be set by commands in -% the |\list|'s COMMANDS argument. These parameters are all TeX +% the |\list|'s COMMANDS argument. These parameters are all \TeX{} % skips or dimensions (defined by |\newskip| or |\newdimen|), so the % usual \TeX\ or \LaTeX\ commands can be used to set them. The % commands will be executed in vmode if and only if the |\list| was @@ -228,7 +227,7 @@ % label. % \item[\cs{labelwidth}:] nominal width of box that contains the label. % If the natural width of the -% label $< =$ \cs{labelwidth}, +% label $\leq$ \cs{labelwidth}, % then the label is flushed right inside a box % of width \cs{labelwidth} (with an \cs{hfil}). % Otherwise, diff --git a/Master/texmf-dist/source/latex/base/ltlogos.dtx b/Master/texmf-dist/source/latex/base/ltlogos.dtx index 56453f73dbc..7589cf36e1b 100644 --- a/Master/texmf-dist/source/latex/base/ltlogos.dtx +++ b/Master/texmf-dist/source/latex/base/ltlogos.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltluatex.dtx b/Master/texmf-dist/source/latex/base/ltluatex.dtx index 6c66a96be0e..135cb630096 100644 --- a/Master/texmf-dist/source/latex/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex/base/ltluatex.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2022 +% Copyright (C) 2015-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -28,7 +28,7 @@ \ProvidesFile{ltluatex.dtx} % %<*tex> -[2022/10/03 v1.2a +[2023/01/19 v1.2b % % LuaTeX support for plain TeX (core) %<*tex> @@ -968,10 +968,10 @@ local luatexbase = luatexbase % % Some Lua best practice: use local versions of functions where possible. % \changes{v1.1u}{2021/08/11}{Define missing local function} +% \changes{v1.2b}{2023/01/19}{Remove unused local variable tex_setattribute} % \begin{macrocode} local string_gsub = string.gsub local tex_count = tex.count -local tex_setattribute = tex.setattribute local tex_setcount = tex.setcount local texio_write_nl = texio.write_nl local flush_list = node.flush_list diff --git a/Master/texmf-dist/source/latex/base/ltmarks.dtx b/Master/texmf-dist/source/latex/base/ltmarks.dtx index 3dc4b493ace..677534dd27c 100644 --- a/Master/texmf-dist/source/latex/base/ltmarks.dtx +++ b/Master/texmf-dist/source/latex/base/ltmarks.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltmarks.dtx (C) Copyright 2022 -% Frank Mittelbach, LaTeX Team +%% File: ltmarks.dtx +%% Copyright (C) 2022-2023 +%% Frank Mittelbach, The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/base/ltmath.dtx b/Master/texmf-dist/source/latex/base/ltmath.dtx index 60394460f57..3b1518dd2eb 100644 --- a/Master/texmf-dist/source/latex/base/ltmath.dtx +++ b/Master/texmf-dist/source/latex/base/ltmath.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2022/09/07 v1.2m LaTeX Kernel (Math Setup)] + [2023/05/13 v1.2n LaTeX Kernel (Math Setup)] % \iffalse % % @@ -1132,9 +1132,29 @@ \fi % \end{macrocode} % +% \begin{macro}{\eqno} +% \begin{macro}{\leqno} +% \changes{v1.2n}{2023/05/13}{add \cs{ignorespaces} gh/1059} +% Ensure the (deprecated) \verb|$$..\eqno 1 $$| ignores spaces. % \begin{macrocode} % +%<*2ekernel|latexrelease> +%\IncludeInRelease{2023/06/01}% +% {\eqno}{add ignorespaces to eqno}% +\let\@kernel@eqno\eqno +\let\@kernel@leqno\leqno +\protected\def\eqno{\@kernel@eqno\aftergroup\ignorespaces} +\protected\def\leqno{\@kernel@leqno\aftergroup\ignorespaces} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\eqno}{add ignorespaces to eqno}% +%\let\eqno\@kernel@eqno +%\let\leqno\@kernel@leqno +%\EndIncludeInRelease % \end{macrocode} +% \end{macro} +% \end{macro} % % % @@ -1322,6 +1342,5 @@ % \end{environment} % % -% % \Finale % diff --git a/Master/texmf-dist/source/latex/base/ltmeta.dtx b/Master/texmf-dist/source/latex/base/ltmeta.dtx index 31c5d8dbeec..daaa71626bb 100644 --- a/Master/texmf-dist/source/latex/base/ltmeta.dtx +++ b/Master/texmf-dist/source/latex/base/ltmeta.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltmeta.dtx (C) Copyright 2021, 2022 -% Frank Mittelbach, LaTeX Team +%% File: ltmeta.dtx +%% Copyright (C) 2021-2023 +%% Frank Mittelbach, The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/base/ltmiscen.dtx b/Master/texmf-dist/source/latex/base/ltmiscen.dtx index b7b2bf5e312..801d1e68627 100644 --- a/Master/texmf-dist/source/latex/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex/base/ltmiscen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2021/06/05 v1.1z LaTeX Kernel (Misc. Environments)] + [2022/11/06 v1.2a LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -270,9 +270,17 @@ % This is one of the few places where we already add data and rules % to a hook already in the kernel. % \changes{v1.0w}{1994/11/30}{(DPC) Use \cs{@dofilelist}} +% \changes{v1.2a}{2022/11/06}{Repeat release info at the end (gh/944)} % \begin{macrocode} \AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} \AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +\AddToHook{enddocument/info}[kernel/release]{% + \let\show@release@info\wlog + \show@release@info{ ***********}% + \the\LaTeXReleaseInfo + \show@release@info{ ***********}} + +\DeclareHookRule{enddocument/info}{kernel/release}{before}{kernel/filelist} \DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/base/ltoutenc.dtx b/Master/texmf-dist/source/latex/base/ltoutenc.dtx index 4dac4e15486..1d257805a43 100644 --- a/Master/texmf-dist/source/latex/base/ltoutenc.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutenc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltoutenc.ins b/Master/texmf-dist/source/latex/base/ltoutenc.ins index 8ff0f02608d..2f0c39517fe 100644 --- a/Master/texmf-dist/source/latex/base/ltoutenc.ins +++ b/Master/texmf-dist/source/latex/base/ltoutenc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/ltoutput.dtx b/Master/texmf-dist/source/latex/base/ltoutput.dtx index 1cbc7ab0b1b..18388b1cc64 100644 --- a/Master/texmf-dist/source/latex/base/ltoutput.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutput.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltoutput.dtx} - [2022/08/20 v1.4j LaTeX Kernel (Output Routine)] + [2023/05/26 v1.4j LaTeX Kernel (Output Routine)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutput.dtx} @@ -3005,9 +3005,6 @@ % % There is also an |\addpenalty\interlinepenalty| above. % -% Since in 2e |\samepage| is no longer supported, these could be -% removed. -% % Although it is best to use |\addvspace| in case two h floats come % together, this makes other spacing more difficult to adjust; whereas % if a user specifies two h floats together then they can more easily @@ -3227,9 +3224,6 @@ % % There is also an |\addpenalty\interlinepenalty| above. % -% Since in 2e |\samepage| is no longer supported, these could be -% removed. -% % Although it is best to use |\addvspace| in case two h floats come % together, this makes other spacing more difficult to adjust; whereas % if a user specifies two h floats together then they can more easily diff --git a/Master/texmf-dist/source/latex/base/ltpage.dtx b/Master/texmf-dist/source/latex/base/ltpage.dtx index 1d514fc7c75..1a6586d067e 100644 --- a/Master/texmf-dist/source/latex/base/ltpage.dtx +++ b/Master/texmf-dist/source/latex/base/ltpage.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltpageno.dtx b/Master/texmf-dist/source/latex/base/ltpageno.dtx index 8142639633f..6c02d0fa7f7 100644 --- a/Master/texmf-dist/source/latex/base/ltpageno.dtx +++ b/Master/texmf-dist/source/latex/base/ltpageno.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltpar.dtx b/Master/texmf-dist/source/latex/base/ltpar.dtx index 50ff57183cc..31d863610b4 100644 --- a/Master/texmf-dist/source/latex/base/ltpar.dtx +++ b/Master/texmf-dist/source/latex/base/ltpar.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltpara.dtx b/Master/texmf-dist/source/latex/base/ltpara.dtx index 9296f2b2cd9..9c1a95ee61b 100644 --- a/Master/texmf-dist/source/latex/base/ltpara.dtx +++ b/Master/texmf-dist/source/latex/base/ltpara.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltpara.dtx (C) Copyright 2020-2021 -% Frank Mittelbach, LaTeX Team +%% File: ltpara.dtx +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -14,8 +15,8 @@ %%% From File: ltpara.dtx % % \begin{macrocode} -\def\ltparaversion{v1.0k} -\def\ltparadate{2022/05/13} +\def\ltparaversion{v1.0l} +\def\ltparadate{2023/01/30} % \end{macrocode} %<*driver> \documentclass{l3doc} @@ -729,6 +730,8 @@ % for error recovery and so altering \cs{tex_everypar:D} all the % time should be a tiny bit faster. % \begin{macrocode} +%\IncludeInRelease{2023/06/01} +% {\g_@@_standard_everypar_tl}{minipage~ fix} \tl_new:N \g_@@_standard_everypar_tl % \end{macrocode} % Here is now its definition: @@ -769,7 +772,28 @@ % \begin{macrocode} \group_begin: \tex_everypar:D {} - \skip_zero:N \tex_parskip:D +% \end{macrocode} +% There has been a long-standing problem with \LaTeX's minipages in +% that invisible material at the beginning of a minipage (such as a +% \cs{color} setting) would result in \cs{parskip} being added in +% front of the first paragraph---something that is not done by +% \TeX{} if a vertical list is completely empty. As this is +% happening on a very low-level in the engine it wasn't really +% possible to find out if this \cs{parskip} was added or if a space +% we see in front of the current point is legitimate. However, with +% the new paragraph handling we are in a better position: while we +% still don't know if there is such a space or not, we do know +% if we have just created an empty paragraph. Thus, if we now set +% \cs{parskip} to \texttt{-}\cs{parskip} the two will cancel each other +% if present and if the first was ignored because the vertical list +% was empty, then the second will be ignored too because it is +% still empty. Of course, we don't want to cancel always but only +% at the start of a minipage and that is signaled with the +% \texttt{@minipage} switch. +% \changes{v1.0l}{2023/01/30}{Backout \cs{parskip} at top of minipage (gh/989)} +% \begin{macrocode} + \skip_set:Nn \tex_parskip:D + { \if@minipage -\tex_parskip:D \else: \c_zero_skip \fi: } \tex_noindent:D \group_end: % \end{macrocode} @@ -800,6 +824,43 @@ \@@_handle_indent: % \the \everypar % <--- done differently below } +%\EndIncludeInRelease +%\IncludeInRelease{2021/06/01} +% {\g_@@_standard_everypar_tl}{minipage~ fix} +% +%\tl_gset:Nn \g_@@_standard_everypar_tl { +% \box_gset_to_last:N \g_para_indent_box +% \group_begin: +% \tex_par:D +% \group_end: +% \tex_everypar:D { \msg_error:nnnn { hooks }{ para-mode }{before}{vertical} } +% \@kernel@before@para@before +% \hook_use:n {para/before} +% \group_begin: +% \tex_everypar:D {} +% \skip_zero:N \tex_parskip:D +% \tex_noindent:D +% \group_end: +% \tex_everypar:D{\g_@@_standard_everypar_tl} +% \@kernel@before@para@begin +% \hook_use:n {para/begin} +% \if_mode_horizontal: \else: +% \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi: +% \@@_handle_indent: +%} +% \end{macrocode} +% We also have to add the \cs{everypar} toks register at the +% end. In case of rollback this is already allocated and we have to +% find out the correct number (hope this is correctly done) +% \begin{macrocode} +%\cs_set:Npn \@@_tmp:w #1#2#3#4#5 { } +%\tl_gput_right:Nx \g_@@_standard_everypar_tl { +% \exp_not:N \the +% \exp_not:N \toks +% \exp_after:wN \@@_tmp:w \token_to_meaning:N \everypar +% \c_space_tl +%} +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/base/ltpictur.dtx b/Master/texmf-dist/source/latex/base/ltpictur.dtx index 453ec6149e3..926fd5c6924 100644 --- a/Master/texmf-dist/source/latex/base/ltpictur.dtx +++ b/Master/texmf-dist/source/latex/base/ltpictur.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltplain.dtx b/Master/texmf-dist/source/latex/base/ltplain.dtx index ee1cf0a1613..89e5017300f 100644 --- a/Master/texmf-dist/source/latex/base/ltplain.dtx +++ b/Master/texmf-dist/source/latex/base/ltplain.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2022/01/25 v2.3h LaTeX Kernel (Plain TeX)] + [2023/04/15 v2.3i LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -660,6 +660,10 @@ \def\extrafloats#1{% \ifnum#1>\z@ \count@\numexpr\float@count-1\relax +% \end{macrocode} +% \changes{v2.3i}{2023/04/15}{Protect box 255 in lualatex gh/1041} +% \begin{macrocode} + \ifnum\count@<266 \ch@ck0\m@ne\insert\fi \ch@ck0\count@\count \ch@ck1\count@\dimen \ch@ck2\count@\skip @@ -668,8 +672,12 @@ \global\expandafter\e@alloc@chardef \csname bx@\the\float@count\endcsname\float@count \@cons\@freelist{\csname bx@\the\float@count\endcsname}% -\expandafter -\extrafloats\expandafter{\numexpr#1-1\relax}% +% \end{macrocode} +% \changes{v2.3i}{2023/04/15}{unwind numexpr and ifnum nesting} +% \begin{macrocode} +\expandafter\extrafloats\expandafter{\the\numexpr#1-1\expandafter}% +% \end{macrocode} +% \begin{macrocode} \fi}% % \end{macrocode} % @@ -880,7 +888,6 @@ % but the code is commented out if no special value needs to be set. % INITEX makes all parameters zero except where noted. % -% \begin{oldcomments} % \begin{macrocode} \pretolerance=100 \tolerance=200 % INITEX sets this to 10000 @@ -897,10 +904,14 @@ \brokenpenalty=100 \predisplaypenalty=10000 % \end{macrocode} +% +% \begin{macrocode} % \postdisplaypenalty=0 % \interlinepenalty=0 % \floatingpenalty=0, set during \insert % \outputpenalty=0, set before TeX enters \output +% \end{macrocode} +% % \begin{macrocode} \doublehyphendemerits=10000 \finalhyphendemerits=5000 @@ -971,6 +982,8 @@ % \begin{macrocode} \uchyph=1 % \end{macrocode} +% +% \begin{macrocode} % \lefthyphenmin=2 \righthyphenmin=3 set below % \globaldefs=0 % \maxdeadcycles=25 % INITEX does this @@ -978,21 +991,29 @@ % \fam=0 % \mag=1000 % INITEX does this % \escapechar=`\\ % INITEX does this +% \end{macrocode} +% % \begin{macrocode} \defaulthyphenchar=`\- \defaultskewchar=-1 % \end{macrocode} +% +% \begin{macrocode} % \endlinechar=`\^^M % INITEX does this % \newlinechar=-1 \LaTeX\ sets this in ltdefns.dtx. +% \end{macrocode} +% % \begin{macrocode} \delimiterfactor=901 % \end{macrocode} +% +% \begin{macrocode} % \time=now % TeX does this at beginning of job % \day=now % TeX does this at beginning of job % \month=now % TeX does this at beginning of job % \year=now % TeX does this at beginning of job +% \end{macrocode} % -% \end{oldcomments} % In \LaTeX{} we don't want box information in the transcript % unless we do a full tracing. % \changes{v1.0g}{1994/04/28}{Turn off overfull box tracing in log} @@ -1012,26 +1033,36 @@ \boxmaxdepth=\maxdimen % \end{macrocode} % -% \begin{oldcomments} +% \begin{macrocode} % \lineskiplimit=0pt, changed by \normalbaselines +% \end{macrocode} +% % \begin{macrocode} \delimitershortfall=5pt \nulldelimiterspace=1.2pt \scriptspace=0.5pt % \end{macrocode} +% +% \begin{macrocode} % \mathsurround=0pt % \predisplaysize=0pt, set before TeX enters $$ % \displaywidth=0pt, set before TeX enters $$ % \displayindent=0pt, set before TeX enters $$ +% \end{macrocode} +% % \begin{macrocode} \parindent=20pt % \end{macrocode} +% +% \begin{macrocode} % \hangindent=0pt, zeroed by TeX after each paragraph % \hoffset=0pt % \voffset=0pt % % \baselineskip=0pt, changed by \normalbaselines % \lineskip=0pt, changed by \normalbaselines +% \end{macrocode} +% % \begin{macrocode} \parskip=0pt plus 1pt \abovedisplayskip=12pt plus 3pt minus 9pt @@ -1039,19 +1070,26 @@ \belowdisplayskip=12pt plus 3pt minus 9pt \belowdisplayshortskip=7pt plus 3pt minus 4pt % \end{macrocode} +% +% \begin{macrocode} % \leftskip=0pt % \rightskip=0pt +% \end{macrocode} +% % \begin{macrocode} \topskip=10pt \splittopskip=10pt % \end{macrocode} +% +% \begin{macrocode} % \tabskip=0pt % \spaceskip=0pt % \xspaceskip=0pt +% \end{macrocode} +% % \begin{macrocode} \parfillskip=0pt plus 1fil % \end{macrocode} -% \end{oldcomments} % % % \begin{macro}{\normalbaselineskip} @@ -1215,7 +1253,7 @@ \gdef\obeylines{\catcode`\^^M\active% \let^^M\obeyedline% % \end{macrocode} -% +% % The next line ending the definition is rather curious and it took % me awhile to understand why rollback fails. The problem is the % following: if \texttt{latexrelease} is used, then blocks of diff --git a/Master/texmf-dist/source/latex/base/ltsect.dtx b/Master/texmf-dist/source/latex/base/ltsect.dtx index 71ab1ee89dd..5a03fd49777 100644 --- a/Master/texmf-dist/source/latex/base/ltsect.dtx +++ b/Master/texmf-dist/source/latex/base/ltsect.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltshipout.dtx b/Master/texmf-dist/source/latex/base/ltshipout.dtx index ae29c1acade..b19814a6fd4 100644 --- a/Master/texmf-dist/source/latex/base/ltshipout.dtx +++ b/Master/texmf-dist/source/latex/base/ltshipout.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment %% -%% Copyright (C) 2020-2022 -%% Frank Mittelbach, LaTeX Team +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, The LaTeX Project %% % % This file is part of the LaTeX base system. @@ -32,8 +32,8 @@ %%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v1.0m} -\providecommand\ltshipoutdate{2022/08/26} +\providecommand\ltshipoutversion{v1.0n} +\providecommand\ltshipoutdate{2022/11/08} % \end{macrocode} % %<*driver> @@ -75,7 +75,7 @@ % \providecommand\pkg[1]{\texttt{#1}} % % -% \title{The \texttt{ltshipout} package\thanks{This package has version +% \title{The \texttt{ltshipout} documentation\thanks{This file has version % \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\ % Project.}} % @@ -241,6 +241,18 @@ % But being placed after the main box content it will be typeset % later and thus overprints it (i.e., is in the foreground). % +% \item[\hook{shipout}] +% This hook is executed after foreground and/or background +% material has been added, i.e., just in front of the actual +% shipout operation. Its purpose is to allow manipulation of the +% finalized box (stored in \cs{ShipoutBox}) with the extra +% material also in place (which is not yet the case in +% \hook{shipout/before}). +% +% It cannot be used to cancel the shipout operation via +% \cs{DiscardShipoutBox} (that has +% to happen in \hook{shipout/before}, if desired! +% % % \item[\hook{shipout/firstpage}] % @@ -296,7 +308,7 @@ % actual shipout. It is even run if there was a % \cs{DiscardShipoutBox} request in the document. % -% The other hooks (except \hook{shipout/after}) are added inside +% The other hooks (except \hook{shipout} and \hook{shipout/after}) are added inside % hboxes to the box being shipped out in the following order: % \begin{center} % \begin{tabular}{ll} @@ -307,9 +319,13 @@ % \hook{shipout/lastpage} & only on the last page \\ % \end{tabular} % \end{center} -% If any of the hooks has no code then that particular no box is +% If any of the hooks has no code then the corresponding box is % added at that point. % +% Once the (page) box has got the above extra content it can +% again be manipulated using the \hook{shipout} hook and then +% is shipped out for real. +% % Once the (page) box has been shipped out the \hook{shipout/after} % hook is called (while you are still inside the output routine). It % is not called if the shipout box was discarded. @@ -381,13 +397,16 @@ % % \fmi{Once we have a new mark mechanism available we can improve % on that and make sure that the declaration applies to the page -% that contains it.} +% that contains it --- not done (yet)} +% +% \cs{DiscardShipoutBox} cannot be used in any of the \hook{shipout/...} +% hooks other than \hook{shipout/before}. % \end{function} % % In the \pkg{atbegshi} package there are a number of additional % commands for use inside the \hook{shipout/before} hook. They % should normally not be needed any more as one can instead simply -% add code to the hooks \hook{shipout/before}, +% add code to the hooks \hook{shipout/before}, \hook{shipout}, % \hook{shipout/background} or % \hook{shipout/foreground}.\footnote{If that assumption turns out to % be wrong it would be trivial to change them to public functions @@ -401,7 +420,9 @@ % % \begin{variable}{pre_shipout_filter} % Under Lua\TeX{} the \texttt{pre\_shipout\_filter} Lua callback is -% provided which gets called immediately before the shipout primitive gets invoked. +% provided which gets called directly after the +% \hook{shipout} hook, immediately before the shipout +% primitive gets invoked. % The signature is % \begin{verbatim} % function( head) @@ -1014,15 +1035,20 @@ \_@@_add_foreground_box:n { \UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage } - \bool_gset_true:N \g_@@_lastpage_handled_bool % \end{macrocode} % We record that we have handled the \hook{shipout/lastpage} hook % but only if we really did. % \changes{v1.0m}{2022/05/08}{Handle case where shipout/lastpage is % run too early (gh/813)} % \begin{macrocode} + \bool_gset_true:N \g_@@_lastpage_handled_bool } } +% \end{macrocode} +% +% \changes{v1.0n}{2022/11/08}{Add shipout hook (gh/920)} +% \begin{macrocode} + \hook_use:n {shipout} \@@_finalize_box: % \end{macrocode} % Finally we run the actual \TeX{} primitive for shipout. As that will @@ -1116,13 +1142,14 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{shipout/before,shipout/after, +% \begin{macro}{shipout/before,shipout,shipout/after, % shipout/foreground,shipout/background, -% shipout/firstpage, -% shipout/lastpage} +% shipout/firstpage,shipout/lastpage} % Declaring all hooks for the shipout code. +% \changes{v1.0n}{2022/11/08}{Add shipout hook (gh/920)} % \begin{macrocode} \hook_new:n{shipout/before} +\hook_new:n{shipout} \hook_new:n{shipout/after} \hook_new:n{shipout/foreground} \hook_new:n{shipout/background} diff --git a/Master/texmf-dist/source/latex/base/ltspace.dtx b/Master/texmf-dist/source/latex/base/ltspace.dtx index 30bda278fbf..a77314b1bd1 100644 --- a/Master/texmf-dist/source/latex/base/ltspace.dtx +++ b/Master/texmf-dist/source/latex/base/ltspace.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltspace.dtx} - [2022/11/28 v1.3o LaTeX Kernel (spacing)] + [2023/05/26 v1.3p LaTeX Kernel (spacing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltspace.dtx} @@ -94,6 +94,7 @@ % inhibits page breaking most places by setting the % following penalties to 10000:\\ % |\interlinepenalty|\\ +% |\predisplaypenalty|\\ % |\postdisplaypenalty|\\ % |\interdisplaylinepenalty|\\ % |\@beginparpenalty|\\ @@ -308,8 +309,10 @@ % \end{macro} % % \begin{macro}{\samepage} +% \changes{v1.3p}{2023/03/22}{Add \cs{predisplaypenalty} setting (gh/1022)} % \begin{macrocode} \DeclareRobustCommand\samepage{\interlinepenalty\@M + \predisplaypenalty\@M \postdisplaypenalty\@M \interdisplaylinepenalty\@M \@beginparpenalty\@M diff --git a/Master/texmf-dist/source/latex/base/lttab.dtx b/Master/texmf-dist/source/latex/base/lttab.dtx index e32153f31c3..e76325d82ba 100644 --- a/Master/texmf-dist/source/latex/base/lttab.dtx +++ b/Master/texmf-dist/source/latex/base/lttab.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/lttextcomp.dtx b/Master/texmf-dist/source/latex/base/lttextcomp.dtx index 8f5ec0d2002..3602e0a6b00 100644 --- a/Master/texmf-dist/source/latex/base/lttextcomp.dtx +++ b/Master/texmf-dist/source/latex/base/lttextcomp.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltthm.dtx b/Master/texmf-dist/source/latex/base/ltthm.dtx index d0d04d9669d..b321c7ac2b1 100644 --- a/Master/texmf-dist/source/latex/base/ltthm.dtx +++ b/Master/texmf-dist/source/latex/base/ltthm.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/ltvers.dtx b/Master/texmf-dist/source/latex/base/ltvers.dtx index 24308589f1f..de3c022755c 100644 --- a/Master/texmf-dist/source/latex/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex/base/ltvers.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltvers.dtx} - [2022/02/28 v1.1i LaTeX Kernel (Version Info)] + [2022/11/06 v1.1j LaTeX Kernel (Version Info)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltvers.dtx} @@ -112,10 +112,10 @@ % %\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2022-11-01} + {2023-06-01} % %<*2ekernel> -\def\patch@level{1} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} @@ -178,20 +178,33 @@ % by a loader (\texttt{.ini} file)} % \changes{v1.0v}{2015/08/23}{Allow negative patchlevel for pre-release} % \changes{v1.1e}{2020/01/31}{Allow for upcoming format as pre-release 0} +% \changes{v1.1j}{2022/11/06}{Repeat release info at the end (gh/944)} +% +% We store release info in the toks \cs{LaTeXReleaseInfo} to be +% used in \cs{everyjob} but also when \verb=\end{document}= is +% executed. +% Instead of using \cs{typeout} we use \cs{show@release@info} so +% that we can write to the log only by changing that to \cs{wlog}. +% \begin{macrocode} +\newtoks\LaTeXReleaseInfo +\everyjob\expandafter{\the\everyjob\the\LaTeXReleaseInfo} +\let\show@release@info\typeout +% \end{macrocode} +% % \begin{macrocode} \ifnum0\ifnum\patch@level=0 \ifx\development@branch@name\@empty 1\fi\fi>0 % - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion>}} + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion>}} \immediate \write16{\fmtname \space<\fmtversion>} \else\ifnum\patch@level>0 - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion> patch level \patch@level}} + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion> patch level \patch@level}} \immediate \write16{\fmtname\space <\fmtversion> patch level \patch@level} \else - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion> + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion> pre-release-\number-\patch@level\space \ifx\development@branch@name\@undefined \else \ifx\development@branch@name\@empty \else diff --git a/Master/texmf-dist/source/latex/base/ltxdoc.dtx b/Master/texmf-dist/source/latex/base/ltxdoc.dtx index 6863349be3d..e147c9d22fe 100644 --- a/Master/texmf-dist/source/latex/base/ltxdoc.dtx +++ b/Master/texmf-dist/source/latex/base/ltxdoc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -30,7 +30,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesClass{ltxdoc} -% [2022/06/22 v2.1i Standard LaTeX documentation class] +% [2023/03/28 v2.1j Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -182,9 +182,13 @@ % % Support rolling back \pkg{doc} to version 2: % \changes{v2.1e}{2022/05/27}{Support rolling back doc to version 2} +% \changes{v2.1j}{2023/03/28}{Define \cs{cs} if doc is rolled back to v2 (gh/981)} % \begin{macrocode} \let\ltxdoc@doc@version\@empty % use current version by default -\DeclareOption{doc2}{\def\ltxdoc@doc@version{=v2}} +\DeclareOption{doc2}{% + \def\ltxdoc@doc@version{=v2}% + \DeclareRobustCommand\cs[1]{\texttt{\bslash #1}}% +} % \end{macrocode} % % \begin{macrocode} @@ -670,8 +674,10 @@ Bug reports can be opened (category \texttt{#1}) at\\% % kernel sources. % % -% Copyright 2006, 2007, 2011 Heiko Oberdiek -% Copyright 2014-2021 The LaTeX Project +% Copyright 2006, 2007, 2011 +% Heiko Oberdiek +% Copyright (C) 2014-2023 +% The LaTeX Project % \ProvidesFile{ltxdoc.cfg}% diff --git a/Master/texmf-dist/source/latex/base/ltxref.dtx b/Master/texmf-dist/source/latex/base/ltxref.dtx index 596eb2fd74d..0f842e4312a 100644 --- a/Master/texmf-dist/source/latex/base/ltxref.dtx +++ b/Master/texmf-dist/source/latex/base/ltxref.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltxref.dtx} - [2022/04/12 v1.1p LaTeX Kernel (Cross Referencing)] + [2023/05/16 v1.1q LaTeX Kernel (Cross Referencing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltxref.dtx} @@ -93,6 +93,15 @@ % to align with the use of \pkg{hyperref}. Without \pkg{hyperref} (or some % other package using the starred form) the star is simply ignored. % +% Note: starting with 2023-06-01 |\label| stores also the current value +% of |\@currentlabelname| which should typically contain a (sanitized) title. +% (A reference command |\nameref| is provided by the \pkg{nameref} package.) +% |\label| also stores |\@currentHref| which if set should refer to a target name +% for links. This value is set and used by \pkg{hyperref}. Unlike the other values +% |\@currentHref| should be set globally. A fifth value |\@kernel@reserved@label@data| +% is reserved for the kernel to allow future extensions of the cross-reference +% system. +% % % \MaybeStop{} % @@ -108,7 +117,8 @@ % incremented by the command \refstepcounter{CNT} , which sets % \@currentlabel == {CNT}{eval(\p@cnt\theCNT)}. The command % \label{FOO} then writes the following on file \@auxout : -% \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}} +% \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}% +% {eval(\@currentlabelname)}{eval(\@currentHref)}{eval(\@kernel@reserved@label@data)}} % % \ref{FOO} == % BEGIN @@ -228,6 +238,10 @@ % % RmS 93/09/08: Added setting of refundefined switch. % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2023/06/01}% +% {\@kernel@sref}{store five arguments}% \def\@setref#1#2#3{% \ifx#1\relax \protect\G@refundefinedtrue @@ -235,19 +249,53 @@ \@latex@warning{Reference `#3' on page \thepage \space undefined}% \else - \expandafter#2#1\null + \expandafter#2#1\@empty\@empty\@empty\null \fi} % \end{macrocode} % \begin{macrocode} -% -%<*2ekernel|latexrelease> +\long\def\@firstoffive#1#2#3#4#5{#1} +\long\def\@secondoffive#1#2#3#4#5{#2} +\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoffive{#1}} +\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname + \@secondoffive{#1}} +%\EndIncludeInRelease +%\IncludeInRelease{2022/06/01}% +% {\@kernel@sref}{store five arguments}% +%\def\@setref#1#2#3{% +% \ifx#1\relax +% \protect\G@refundefinedtrue +% \nfss@text{\reset@font\bfseries ??}% +% \@latex@warning{Reference `#3' on page \thepage \space +% undefined}% +% \else +% \expandafter#2#1\null +% \fi} +%\let\@firstoffive\undefined +%\let\@secondoffive\undefined +%\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} +%\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname +% \@secondoftwo{#1}} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@kernel@sref}{store five arguments}% +%\def\@setref#1#2#3{% +% \ifx#1\relax +% \protect\G@refundefinedtrue +% \nfss@text{\reset@font\bfseries ??}% +% \@latex@warning{Reference `#3' on page \thepage \space +% undefined}% +% \else +% \expandafter#2#1\null +% \fi} +%\let\@firstoffive\undefined +%\let\@secondoffive\undefined +%\let\@kernel@sref\undefined +%\let\@kernel@spageref\undefined +%\EndIncludeInRelease %\IncludeInRelease{2022/06/01}% % {\ref}{Add starred reference commands}% % \end{macrocode} % \begin{macrocode} -\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} -\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname - \@secondoftwo{#1}} \let\@kernel@ref\@kernel@sref \let\@kernel@pageref\@kernel@spageref \NewDocumentCommand\ref{s} @@ -334,6 +382,8 @@ % \begin{macro}{\label} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@write}} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@edef}} +% \changes{v1.1q}{2023/05/12}{(UFi)extended to store five arguments} +% \changes{v1.1q}{2023/05/12}{(UFi)added a hook with argument} % The commands |\label| and |\refstepcounter| have been changed to % allow |\protect|'ed commands to work properly. For example, %\begin{verbatim} @@ -343,16 +393,27 @@ % to something like |\foo{4.d}|. Change made 20 Jul 88. % % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2023/06/01}% +% {\label}{store five label arguments}% +\providecommand\@currentlabelname{} +\providecommand\@currentHref{} +\providecommand\@kernel@reserved@label@data{} +\NewHookWithArguments{label}{1} \def\label#1{\@bsphack + \begingroup + \UseHookWithArguments{label}{1}{#1}% \protected@write\@auxout{}% - {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% + {\string\newlabel{#1}{{\@currentlabel}{\thepage}% + {\@currentlabelname}{\@currentHref}{\@kernel@reserved@label@data}}}% + \endgroup \@esphack} +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % % \begin{macrocode} -% -%<*2ekernel|latexrelease> %\IncludeInRelease{2022/06/01}% % {\Ref}{Add starred version}% % \end{macrocode} @@ -432,6 +493,16 @@ % \begin{macrocode} % %\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\label}{store five label arguments}% +%\let\@currenttitle\@undefined +%\let\@currenttarget\@undefined +%\let\@kernel@currentdata\@undefined +%\def\label#1{\@bsphack +% \protected@write\@auxout{}% +% {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% +% \@esphack} +%\EndIncludeInRelease %\IncludeInRelease{2020/10/01}% % {\Ref}{Add starred version}% %\def\@currentcounter{} diff --git a/Master/texmf-dist/source/latex/base/makeindx.dtx b/Master/texmf-dist/source/latex/base/makeindx.dtx index fb6c4746594..b91d3a6c441 100644 --- a/Master/texmf-dist/source/latex/base/makeindx.dtx +++ b/Master/texmf-dist/source/latex/base/makeindx.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/makeindx.ins b/Master/texmf-dist/source/latex/base/makeindx.ins index 0fe55ed0392..1c5f6edcb92 100644 --- a/Master/texmf-dist/source/latex/base/makeindx.ins +++ b/Master/texmf-dist/source/latex/base/makeindx.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/newdc.ins b/Master/texmf-dist/source/latex/base/newdc.ins index eeec6479ebb..277e8ea21f6 100644 --- a/Master/texmf-dist/source/latex/base/newdc.ins +++ b/Master/texmf-dist/source/latex/base/newdc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/newlfont.dtx b/Master/texmf-dist/source/latex/base/newlfont.dtx index 86c0d47ab63..0b35eddd800 100644 --- a/Master/texmf-dist/source/latex/base/newlfont.dtx +++ b/Master/texmf-dist/source/latex/base/newlfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/nfssfont.dtx b/Master/texmf-dist/source/latex/base/nfssfont.dtx index 51d7834aa32..556ce5f76da 100644 --- a/Master/texmf-dist/source/latex/base/nfssfont.dtx +++ b/Master/texmf-dist/source/latex/base/nfssfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/nfssfont.ins b/Master/texmf-dist/source/latex/base/nfssfont.ins index a181c619721..21a13f70a89 100644 --- a/Master/texmf-dist/source/latex/base/nfssfont.ins +++ b/Master/texmf-dist/source/latex/base/nfssfont.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/olddc.ins b/Master/texmf-dist/source/latex/base/olddc.ins index 707fb207e6c..320b3a4b0ef 100644 --- a/Master/texmf-dist/source/latex/base/olddc.ins +++ b/Master/texmf-dist/source/latex/base/olddc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/oldlfont.dtx b/Master/texmf-dist/source/latex/base/oldlfont.dtx index b7c9abc3eb4..33ae5e6fd9d 100644 --- a/Master/texmf-dist/source/latex/base/oldlfont.dtx +++ b/Master/texmf-dist/source/latex/base/oldlfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/preload.dtx b/Master/texmf-dist/source/latex/base/preload.dtx index 3b75df38fdb..d26bdaa9ed1 100644 --- a/Master/texmf-dist/source/latex/base/preload.dtx +++ b/Master/texmf-dist/source/latex/base/preload.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/proc.dtx b/Master/texmf-dist/source/latex/base/proc.dtx index 135c67bc0b2..bbbf71162ff 100644 --- a/Master/texmf-dist/source/latex/base/proc.dtx +++ b/Master/texmf-dist/source/latex/base/proc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/proc.ins b/Master/texmf-dist/source/latex/base/proc.ins index 16f60195e59..056816e99ef 100644 --- a/Master/texmf-dist/source/latex/base/proc.ins +++ b/Master/texmf-dist/source/latex/base/proc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/slides.dtx b/Master/texmf-dist/source/latex/base/slides.dtx index 5ea9e58d9c8..a918c337dd8 100644 --- a/Master/texmf-dist/source/latex/base/slides.dtx +++ b/Master/texmf-dist/source/latex/base/slides.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/slides.ins b/Master/texmf-dist/source/latex/base/slides.ins index 8c9862c2d54..3acb556b96a 100644 --- a/Master/texmf-dist/source/latex/base/slides.ins +++ b/Master/texmf-dist/source/latex/base/slides.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -96,7 +96,7 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -138,7 +138,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/slifonts.fdd b/Master/texmf-dist/source/latex/base/slifonts.fdd index ec8b802596f..5b66975095c 100644 --- a/Master/texmf-dist/source/latex/base/slifonts.fdd +++ b/Master/texmf-dist/source/latex/base/slifonts.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2019 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/syntonly.dtx b/Master/texmf-dist/source/latex/base/syntonly.dtx index ae4d4cd1f85..2b0049b6964 100644 --- a/Master/texmf-dist/source/latex/base/syntonly.dtx +++ b/Master/texmf-dist/source/latex/base/syntonly.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/syntonly.ins b/Master/texmf-dist/source/latex/base/syntonly.ins index 5812ef2fd6b..8ccaf254d15 100644 --- a/Master/texmf-dist/source/latex/base/syntonly.ins +++ b/Master/texmf-dist/source/latex/base/syntonly.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/tulm.fdd b/Master/texmf-dist/source/latex/base/tulm.fdd index 243cbe30cc7..c8dd8b95fcf 100644 --- a/Master/texmf-dist/source/latex/base/tulm.fdd +++ b/Master/texmf-dist/source/latex/base/tulm.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2016-2021 +% Copyright (C) 2016-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/Master/texmf-dist/source/latex/base/tulm.ins b/Master/texmf-dist/source/latex/base/tulm.ins index a50060b2013..85970a51333 100644 --- a/Master/texmf-dist/source/latex/base/tulm.ins +++ b/Master/texmf-dist/source/latex/base/tulm.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2016-2022 +%% Copyright (C) 2016-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2016-2022 +Copyright (C) 2016-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/base/unpack.ins b/Master/texmf-dist/source/latex/base/unpack.ins index 21ba62a33a7..5baa2b5447c 100644 --- a/Master/texmf-dist/source/latex/base/unpack.ins +++ b/Master/texmf-dist/source/latex/base/unpack.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/Master/texmf-dist/source/latex/base/utf8ienc.dtx b/Master/texmf-dist/source/latex/base/utf8ienc.dtx index a2b25fd3ab5..f1623ee0e6c 100644 --- a/Master/texmf-dist/source/latex/base/utf8ienc.dtx +++ b/Master/texmf-dist/source/latex/base/utf8ienc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % -- cgit v1.2.3