From f496422c8703b52babe725eb473534648fad4367 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 1 Jun 2021 21:12:14 +0000 Subject: latex2e (1jun21) git-svn-id: svn://tug.org/texlive/trunk@59424 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/base/alltt.dtx | 27 +- Master/texmf-dist/source/latex/base/alltt.ins | 8 +- Master/texmf-dist/source/latex/base/classes.dtx | 137 +- Master/texmf-dist/source/latex/base/classes.ins | 8 +- Master/texmf-dist/source/latex/base/cmextra.ins | 8 +- Master/texmf-dist/source/latex/base/cmfonts.fdd | 2 +- Master/texmf-dist/source/latex/base/cmfonts.ins | 8 +- Master/texmf-dist/source/latex/base/doc.dtx | 27 +- Master/texmf-dist/source/latex/base/docstrip.dtx | 22 +- Master/texmf-dist/source/latex/base/docstrip.ins | 8 +- Master/texmf-dist/source/latex/base/ec.ins | 8 +- Master/texmf-dist/source/latex/base/exscale.dtx | 4 +- Master/texmf-dist/source/latex/base/exscale.ins | 8 +- Master/texmf-dist/source/latex/base/fix-cm.dtx | 8 +- Master/texmf-dist/source/latex/base/fix-cm.ins | 8 +- Master/texmf-dist/source/latex/base/fontdef.dtx | 16 +- Master/texmf-dist/source/latex/base/format.ins | 22 +- Master/texmf-dist/source/latex/base/graphpap.dtx | 4 +- Master/texmf-dist/source/latex/base/graphpap.ins | 8 +- Master/texmf-dist/source/latex/base/ifthen.dtx | 10 +- Master/texmf-dist/source/latex/base/ifthen.ins | 8 +- Master/texmf-dist/source/latex/base/inputenc.dtx | 12 +- Master/texmf-dist/source/latex/base/inputenc.ins | 8 +- Master/texmf-dist/source/latex/base/latex209.dtx | 8 +- Master/texmf-dist/source/latex/base/latex209.ins | 8 +- .../texmf-dist/source/latex/base/latexrelease.dtx | 350 +- .../texmf-dist/source/latex/base/latexrelease.ins | 16 +- Master/texmf-dist/source/latex/base/latexsym.dtx | 4 +- Master/texmf-dist/source/latex/base/latexsym.ins | 12 +- Master/texmf-dist/source/latex/base/letter.dtx | 32 +- Master/texmf-dist/source/latex/base/letter.ins | 8 +- Master/texmf-dist/source/latex/base/ltalloc.dtx | 4 +- Master/texmf-dist/source/latex/base/ltbibl.dtx | 63 +- Master/texmf-dist/source/latex/base/ltboxes.dtx | 118 +- Master/texmf-dist/source/latex/base/ltclass.dtx | 271 +- Master/texmf-dist/source/latex/base/ltcmd.dtx | 4034 ++++++++++++++++++++ Master/texmf-dist/source/latex/base/ltcmdhooks.dtx | 1094 ++++++ Master/texmf-dist/source/latex/base/ltcntrl.dtx | 8 +- Master/texmf-dist/source/latex/base/ltcounts.dtx | 8 +- Master/texmf-dist/source/latex/base/ltdefns.dtx | 32 +- Master/texmf-dist/source/latex/base/ltdirchk.dtx | 30 +- Master/texmf-dist/source/latex/base/lterror.dtx | 4 +- Master/texmf-dist/source/latex/base/ltexpl.dtx | 107 +- Master/texmf-dist/source/latex/base/ltfilehook.dtx | 133 +- Master/texmf-dist/source/latex/base/ltfiles.dtx | 179 +- Master/texmf-dist/source/latex/base/ltfinal.dtx | 136 +- Master/texmf-dist/source/latex/base/ltfloat.dtx | 122 +- Master/texmf-dist/source/latex/base/ltfntcmd.dtx | 12 +- Master/texmf-dist/source/latex/base/ltfssaxes.dtx | 402 +- Master/texmf-dist/source/latex/base/ltfssbas.dtx | 56 +- Master/texmf-dist/source/latex/base/ltfsscmp.dtx | 8 +- Master/texmf-dist/source/latex/base/ltfssdcl.dtx | 18 +- Master/texmf-dist/source/latex/base/ltfssini.dtx | 146 +- Master/texmf-dist/source/latex/base/ltfsstrc.dtx | 176 +- Master/texmf-dist/source/latex/base/lthooks.dtx | 1210 ++++-- Master/texmf-dist/source/latex/base/lthyphen.dtx | 6 +- Master/texmf-dist/source/latex/base/ltidxglo.dtx | 4 +- Master/texmf-dist/source/latex/base/ltlength.dtx | 8 +- Master/texmf-dist/source/latex/base/ltlists.dtx | 16 +- Master/texmf-dist/source/latex/base/ltlogos.dtx | 4 +- Master/texmf-dist/source/latex/base/ltluatex.dtx | 36 +- Master/texmf-dist/source/latex/base/ltmath.dtx | 16 +- Master/texmf-dist/source/latex/base/ltmiscen.dtx | 45 +- Master/texmf-dist/source/latex/base/ltoutenc.dtx | 112 +- Master/texmf-dist/source/latex/base/ltoutenc.ins | 8 +- Master/texmf-dist/source/latex/base/ltoutput.dtx | 38 +- Master/texmf-dist/source/latex/base/ltpage.dtx | 8 +- Master/texmf-dist/source/latex/base/ltpageno.dtx | 8 +- Master/texmf-dist/source/latex/base/ltpar.dtx | 20 +- Master/texmf-dist/source/latex/base/ltpara.dtx | 1223 ++++++ Master/texmf-dist/source/latex/base/ltpictur.dtx | 11 +- Master/texmf-dist/source/latex/base/ltplain.dtx | 222 +- Master/texmf-dist/source/latex/base/ltsect.dtx | 8 +- Master/texmf-dist/source/latex/base/ltshipout.dtx | 730 +++- Master/texmf-dist/source/latex/base/ltspace.dtx | 4 +- Master/texmf-dist/source/latex/base/lttab.dtx | 14 +- Master/texmf-dist/source/latex/base/lttextcomp.dtx | 545 +-- Master/texmf-dist/source/latex/base/ltthm.dtx | 4 +- Master/texmf-dist/source/latex/base/ltvers.dtx | 153 +- Master/texmf-dist/source/latex/base/ltxdoc.dtx | 8 +- Master/texmf-dist/source/latex/base/ltxref.dtx | 12 +- Master/texmf-dist/source/latex/base/makeindx.dtx | 6 +- Master/texmf-dist/source/latex/base/makeindx.ins | 8 +- Master/texmf-dist/source/latex/base/newdc.ins | 8 +- Master/texmf-dist/source/latex/base/newlfont.dtx | 4 +- Master/texmf-dist/source/latex/base/nfssfont.dtx | 10 +- Master/texmf-dist/source/latex/base/nfssfont.ins | 8 +- Master/texmf-dist/source/latex/base/olddc.ins | 8 +- Master/texmf-dist/source/latex/base/oldlfont.dtx | 4 +- Master/texmf-dist/source/latex/base/preload.dtx | 4 +- Master/texmf-dist/source/latex/base/proc.dtx | 12 +- Master/texmf-dist/source/latex/base/proc.ins | 8 +- Master/texmf-dist/source/latex/base/slides.dtx | 22 +- Master/texmf-dist/source/latex/base/slides.ins | 16 +- Master/texmf-dist/source/latex/base/slifonts.fdd | 4 +- Master/texmf-dist/source/latex/base/syntonly.dtx | 4 +- Master/texmf-dist/source/latex/base/syntonly.ins | 8 +- Master/texmf-dist/source/latex/base/tulm.fdd | 6 +- Master/texmf-dist/source/latex/base/tulm.ins | 8 +- Master/texmf-dist/source/latex/base/unpack.ins | 4 +- Master/texmf-dist/source/latex/base/utf8ienc.dtx | 41 +- 101 files changed, 10967 insertions(+), 1677 deletions(-) create mode 100644 Master/texmf-dist/source/latex/base/ltcmd.dtx create mode 100644 Master/texmf-dist/source/latex/base/ltcmdhooks.dtx create mode 100644 Master/texmf-dist/source/latex/base/ltpara.dtx (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 2c9e22a1243..350229ab40f 100644 --- a/Master/texmf-dist/source/latex/base/alltt.dtx +++ b/Master/texmf-dist/source/latex/base/alltt.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,7 +30,7 @@ %% %% File `alltt.dtx'. %% Copyright (C) 1987 by Leslie Lamport -%% Copyright (C) 1994--1997 LaTeX3 project, Johannes Braams +%% Copyright (C) 1994-2021 LaTeX Project, Johannes Braams %% all rights reserved. %% %<*dtx> @@ -40,10 +40,11 @@ %\ProvidesPackage{alltt} %\ProvidesFile{alltt.drv} %\ProvidesFile{alltt.dtx} - [1997/06/16 v2.0g defines alltt environment] + [2021/01/29 v2.0g defines alltt environment] % %<*driver> \documentclass{ltxdoc} +\usepackage{alltt} \begin{document} \providecommand{\Lenv}[1]{\textsf{#1}} \providecommand{\pkg}[1]{\texttt{#1}} @@ -55,6 +56,8 @@ % % \changes{v2.0g}{1997/06/16}{A few documentation fixes (PR 2520)} % \changes{v2.0d}{1995/04/02}{A few documentation fixes (PR 1517)} +% \changes{v2.0g}{2021-01-29}{Added a warning about OT1 versus T1 font +% encoding} % % \GetFileInfo{alltt.dtx} % \title{The \texttt{alltt} environment\thanks{This file @@ -88,11 +91,19 @@ % extra blank line if you're not careful. % % \item Insert a math formula. Note that |$| just produces a dollar -% sign, so you'll have to type |\(...\)| or |\[...\]|. Also, |^| -% and |_| just produce their characters; use |\sp| or |\sb| for -% super- and subscripts, as in |\(x\sp{2}\)|. +% sign, so you'll have to type |\(...\)| or |\[...\]|. Also, |^| +% and |_| just produce their characters; use |\sp| or |\sb| for +% super- and subscripts, as in |\(x\sp{2}\)|. % \end{itemize} % +% \textbf{NB} When you are using \textsf{OT1} encoded fonts you might +% be surprsied when you switch to italics, becuase those fonts have +% a different set of glyphs: +% \begin{alltt} +% The glyph at the position of the $ in a slanted font: \textsl{$}. +% The glyph at the position of the $ in an italic font: \textit{$}. +% \end{alltt} +% % \StopEventually{} % % \section{The Implementation} @@ -173,7 +184,7 @@ % control sequence |\do| between the characters. We use that to % check whether a character has to be removed. % -% The macro |\g@remfrom@specials| takes one argument, the chracter +% The macro |\g@remfrom@specials| takes one argument, the character % to be removed from the list. % \begin{macrocode} \def\g@remfrom@specials#1{% diff --git a/Master/texmf-dist/source/latex/base/alltt.ins b/Master/texmf-dist/source/latex/base/alltt.ins index adb3838a473..7ce21032079 100644 --- a/Master/texmf-dist/source/latex/base/alltt.ins +++ b/Master/texmf-dist/source/latex/base/alltt.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/classes.dtx b/Master/texmf-dist/source/latex/base/classes.dtx index d6f2bb64e6a..ffe04c620fa 100644 --- a/Master/texmf-dist/source/latex/base/classes.dtx +++ b/Master/texmf-dist/source/latex/base/classes.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -53,7 +53,7 @@ %<*driver> \ProvidesFile{classes.drv} % - [2020/04/10 v1.4m + [2021/02/12 v1.4n % Standard LaTeX document class] %<10pt|11pt|12pt> Standard LaTeX file (size option)] % \end{macrocode} @@ -116,7 +116,7 @@ \DoNotIndex{\viipt,\vipt,\vskip,\vspace} \DoNotIndex{\wd,\xiipt,\year,\z@} % \end{macrocode} -% We do want an index, using linenumbers +% We do want an index, using line numbers % \begin{macrocode} \EnableCrossrefs \CodelineIndex @@ -199,7 +199,7 @@ % \changes{v1.2o}{1994/05/24}{Changed file information} % \changes{v1.2p}{1994/05/27}{Moved identification and driver to the % front of the file} -% \changes{v1.2t}{1994/06/22}{Refrased a few sentences to prevent +% \changes{v1.2t}{1994/06/22}{Rephrased a few sentences to prevent % overfull hboxes} % \changes{v1.2v}{1994/12/01}{Made the oneside option work for the % book class} @@ -221,9 +221,9 @@ % file has version number \fileversion, last revised \filedate.}} % % \author{% -% Copyright (C) 1992 by Leslie Lamport \and -% Copyright (C) 1994-2020 by Frank Mittelbach \and Johannes Braams \and -% \LaTeX3 Project Team +% Copyright (C) 1992 by Leslie Lamport and +% Copyright (C) 1994-2020 by Frank Mittelbach and Johannes Braams and +% LaTeX Project Team % } % \date{\filedate} % \MaintainedByLaTeXTeam{latex} @@ -423,7 +423,7 @@ %\fi % \end{macrocode} % -% \subsection{Twocolumn printing} +% \subsection{Two-column printing} % % Two-column and one-column printing is again realized via a switch. % \begin{macrocode} @@ -788,7 +788,7 @@ % \begin{macro}{\parindent} % |\parskip| gives extra vertical space between paragraphs and % |\parindent| is the width of the paragraph indentation. The value -% of |\parindent| depends on whether we are in two column mode. +% of |\parindent| depends on whether we are in two-column mode. % \changes{v1.0m}{1994/01/12}{\cs{parindent} should be different, % depending on the pointsize} % \begin{macrocode} @@ -998,7 +998,7 @@ % Now we can set the |\textwidth|, depending on whether we will be % setting one or two columns. % -% In two column mode each \emph{column} shouldn't be wider than +% In two-column mode each \emph{column} shouldn't be wider than % |\@tempdimb| (which could happen on \textsc{a3} paper for % instance). % \begin{macrocode} @@ -1010,7 +1010,7 @@ \fi % \end{macrocode} % -% In one column mode the text should not be wider than the minimum +% In one-column mode the text should not be wider than the minimum % of the paperwidth (minus 2 inches for the margins) and the % maximum length of a line as defined by the number of characters. % \begin{macrocode} @@ -1168,7 +1168,7 @@ \fi % % \end{macrocode} -% And values for two column mode: +% And values for two-column mode: % \begin{macrocode} \if@twocolumn \setlength\oddsidemargin {30\p@} @@ -1389,7 +1389,7 @@ % % \begin{macro}{\c@dbltopnumber} % The \Lcount{dbltopnumber} counter holds the maximum number of -% two column floats that can appear on the top of a two column text +% two-column floats that can appear on the top of a two-column text % page. % \begin{macrocode} \setcounter{dbltopnumber}{2} @@ -1397,8 +1397,8 @@ % \end{macro} % % \begin{macro}{\dbltopfraction} -% This indicates the maximum part of a two column text page that -% can be occupied by two column floats at the top. +% This indicates the maximum part of a two-column text page that +% can be occupied by two-column floats at the top. % \changes{v1.0h}{1993/12/18}{Replaced \cs{newcommand} with % \cs{renewcommand}. ASAJ.} % \begin{macrocode} @@ -1408,7 +1408,7 @@ % % \begin{macro}{\dblfloatpagefraction} % This indicates the minimum part of a page that has to be -% occupied by two column wide floating objects before a `float +% occupied by two-column wide floating objects before a `float % page' is produced. % \changes{v1.0h}{1993/12/18}{Replaced \cs{newcommand} with % \cs{renewcommand}. ASAJ.} @@ -1459,7 +1459,7 @@ % \begin{macro}{\dblfloatsep} % \begin{macro}{\dbltextfloatsep} % When floating objects that span the whole |\textwidth| are placed -% on a text page when we are in twocolumn mode the separation +% on a text page when we are in two-column mode the separation % between the float and the text is controlled by |\dblfloatsep| % and |\dbltextfloatsep|. % @@ -1498,7 +1498,7 @@ % whitespace. Between adjacent floats the |\@fpsep| is inserted. % % These parameters are used for the placement of floating objects -% in one column mode, or in single column floats in two column +% in one-column mode, or in single-column floats in two-column % mode. % % Note that at least one of the two parameters |\@fptop| and @@ -1528,7 +1528,7 @@ % \begin{macro}{\@dblfptop} % \begin{macro}{\@dblfpsep} % \begin{macro}{\@dblfpbot} -% Double column floats in two column mode are handled with similar +% Double-column floats in two-column mode are handled with similar % parameters. % \begin{macrocode} %<*10pt> @@ -1809,7 +1809,7 @@ \let \footnote \thanks % \end{macrocode} % We center the entire title vertically; the centering is set off a -% little by adding a |\vskip|. (In compatibility mode the pagenumber +% little by adding a |\vskip|. (In compatibility mode the page number % is set to 0 by the titlepage environment to keep the behaviour % of \LaTeX\ 2.09 style files.) % \changes{v1.0g}{1993/12/09}{Removed the setting of the page number, @@ -1872,7 +1872,7 @@ % \end{macrocode} % When the title is not on a page of its own, the layout of the % title is a little different. We use symbols to mark the footnotes -% and we have to deal with two column documents. +% and we have to deal with two-column documents. % % Therefore we first start a new group to keep changes local. Then % we redefine |\thefootnote| to use |\fnsymbol|; and change @@ -1893,7 +1893,7 @@ \hb@xt@1.8em{% \hss\@textsuperscript{\normalfont\@thefnmark}}##1}% % \end{macrocode} -% If this is a twocolumn document we start a new page in twocolumn +% If this is a two-column document we start a new page in two-column % mode, with the title set to the full width of the text. The % actual printing of the title information is left to % |\@maketitle|. @@ -1908,7 +1908,7 @@ \fi \else % \end{macrocode} -% When this is not a twocolumn document we just start a new page, +% When this is not a two-column document we just start a new page, % prevent floating objects from appearing on the top of this page % and print the title information. % \begin{macrocode} @@ -2133,10 +2133,10 @@ % \Lcount{COUNTER} as an arabic numeral. % % |\roman{|\Lcount{COUNTER}|}| prints the value of -% \Lcount{COUNTER} as a lowercase roman numberal. +% \Lcount{COUNTER} as a lowercase roman numeral. % % |\Roman{|\Lcount{COUNTER}|}| prints the value of -% \Lcount{COUNTER} as an uppercase roman numberal. +% \Lcount{COUNTER} as an uppercase roman numeral. % % |\alph{|\Lcount{COUNTER}|}| prints the value of \Lcount{COUNTER} % as a lowercase letter: $1 =$~a, $2 =$~ b, etc. @@ -2144,7 +2144,7 @@ % |\Alph{|\Lcount{COUNTER}|}| prints the value of \Lcount{COUNTER} % as an uppercase letter: $1 =$~A, $2 =$~B, etc. % -% Actually to save space the internal counter repesentations +% Actually to save space the internal counter representations % and the commands operating on those are used. % \begin{macrocode} \renewcommand \thepart {\@Roman\c@part} @@ -2281,7 +2281,7 @@ \fi \thispagestyle{plain}% % \end{macrocode} -% When we are making a two column document, this will be a one +% When we are making a two-column document, this will be a one % column page. We use |@tempswa| to remember to switch back to two % columns. % \begin{macrocode} @@ -2453,8 +2453,8 @@ \fi \fi % \end{macrocode} -% When this was a two column document we have to switch back to two -% column mode. +% When this was a two-column document we have to switch back to +% two-column mode. % \begin{macrocode} \if@tempswa \twocolumn @@ -2522,8 +2522,8 @@ % \end{macrocode} % Then we call upon |\@makechapterhead| to format the actual % chapter title. We have to do this in a special way when we are in -% twocolumn mode in order to have the chapter title use the entire -% |\textwidth|. In one column mode we call |\@afterheading| which +% two-column mode in order to have the chapter title use the entire +% |\textwidth|. In one-column mode we call |\@afterheading| which % takes care of suppressing the indentation. % \begin{macrocode} \if@twocolumn @@ -2705,7 +2705,7 @@ % \changes{v1.3q}{1995/12/20}{Temporary(?) fix: revert to setting % \cs{leftmargin} at outer level} % -% When we are in two column mode some of the margins are set somewhat +% When we are in two-column mode some of the margins are set somewhat % smaller. % \begin{macrocode} \if@twocolumn @@ -2953,11 +2953,12 @@ % the labels of the various itemization levels: the symbols used are % bullet, bold en-dash, centered asterisk and centred dot. % +% \changes{v1.4n}{2021/06/11}{Drop incorrect space in \cs{labelitemiv} (gh/496)} % \begin{macrocode} \newcommand\labelitemi {\labelitemfont \textbullet} \newcommand\labelitemii {\labelitemfont \bfseries \textendash} \newcommand\labelitemiii{\labelitemfont \textasteriskcentered} -\newcommand\labelitemiv{ \labelitemfont \textperiodcentered} +\newcommand\labelitemiv {\labelitemfont \textperiodcentered} % \end{macrocode} % % \begin{macro}{\labelitemfont} @@ -2966,13 +2967,16 @@ % produced regardless of surrounding conditions. % % \changes{v1.4l}{2019/12/20}{Normalize label fonts} -% A possible alternative would be +% Possible alternatives would be, for example, %\begin{verbatim} -%\renewcommand\labelitemfont{% -% \fontseries\seriesdefault -% \fontshape\shapedefault\selectfont} +% \renewcommand\labelitemfont +% {\normalfont\fontfamily{lmss}\selectfont} +% \renewcommand\labelitemfont +% {\rmfamily\normalshape} %\end{verbatim} -% which resets series and shape doesn't touch the family. +% the first would use symbols from Latin Modern Sans, the second +% would only allow changes in the font series so that an +% \texttt{itemize} in a bold context would produce bolder symbols. % \begin{macrocode} \newcommand\labelitemfont{\normalfont} % \end{macrocode} @@ -3036,7 +3040,7 @@ {\par\vfil\null\endtitlepage} % \end{macrocode} % When we are not making a separate titlepage --the default for the -% article document class-- we have to check if we are in twocolumn +% article document class-- we have to check if we are in two-column % mode. In that case the abstract is as a |\section*|, otherwise % the quotation environment is used to typeset the abstract. % \begin{macrocode} @@ -3125,13 +3129,16 @@ % % \begin{environment}{titlepage} % In the normal environments, the titlepage environment does nothing -% but start and end a page, and inhibit page numbers. In the report -% style, it also resets the page number to one, and then sets it -% back to one at the end. In compatibility mode, it sets the -% page number to zero. This is incorrect since it results in using -% the page parameters for a right-hand page but it is the way it was. -% In two-column style, it still makes a -% one-column page. +% but start and end a page, and inhibit page numbers. When \LaTeX\ is +% in two-column mode, the environmont temporarily switches to +% one-column mode. +% In the report class, it also resets the page number to one, and +% then, in two-column mode, sets it back to one at the end. +% For the book class the environment makes sure that the title page +% is on a recto page by issueing a \cs{cleardouplepage}-command. +% In compatibility mode, it sets the page number to zero. This is +% incorrect since it results in using the page parameters for a +% right-hand page but it is the way it was. % % \changes{v1.0g}{1993/12/09}{Moved the setting of % \cs{@restonecolfalse}} @@ -3291,7 +3298,7 @@ % \begin{macro}{\@minipagerestore} % The macro |\@minipagerestore| is called upon entry to a minipage % environment to set up things that are to be handled differently -% inside a minipage environment. In the current styles, it does +% inside a minipage environment. In the current classes, it does % nothing. % \end{macro} % @@ -3397,7 +3404,7 @@ % a figure is defined using the macros |\@float| and |\end@float|, % which are defined in \file{latex.dtx}. % -% An environment that implements a single column floating object is +% An environment that implements a single-column floating object is % started with |\@float{|\texttt{TYPE}|}[|\meta{placement}|]| of type % \texttt{TYPE} with \meta{placement} as the placement specifier. % The default value of \meta{PLACEMENT} is defined by |\fps@TYPE|. @@ -3449,7 +3456,7 @@ % \begin{environment}{figure} % \begin{environment}{figure*} % And the definition of the actual environment. The form with the -% |*| is used for double column figures. +% |*| is used for double-column figures. % \begin{macrocode} \newenvironment{figure} {\@float{figure}} @@ -3506,7 +3513,7 @@ % \begin{environment}{table} % \begin{environment}{table*} % And the definition of the actual environment. The form with the -% |*| is used for double column tables. +% |*| is used for double-column tables. % \begin{macrocode} \newenvironment{table} {\@float{table}} @@ -3743,7 +3750,7 @@ % \begin{macro}{\tableofcontents} % This macro is used to request that \LaTeX{} produces a table of % contents. In the report and book document classes the tables of -% contents, figures etc. are always set in single-column style. +% contents, figures etc. are always set in single-column mode. % % \changes{v1.0g}{1993/12/09}{Moved the setting of % \cs{@restonecolfalse}} @@ -3778,7 +3785,7 @@ \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}% % \end{macrocode} % The actual table of contents is made by calling -% |\@starttoc{toc}|. After that we restore twocolumn mode if +% |\@starttoc{toc}|. After that we restore two-column mode if % necessary. % \begin{macrocode} \@starttoc{toc}% @@ -3823,13 +3830,13 @@ \begingroup % \end{macrocode} % We set |\parindent| to 0pt and use |\rightskip| to leave -% enough room for the pagenumbers.\footnote{^^A +% enough room for the page numbers.\footnote{^^A % We should really set \cs{rightskip} to \cs{@tocrmarg} instead % of \cs{@pnumwidth} (no version of {\LaTeX} ever did this), % otherwise the \cs{rightskip} is too small. % Unfortunately this can't be changed in {\LaTeXe} as we don't % want to create different versions of {\LaTeXe} which produce -% different typset output unless this is absolutely necessary; +% different typeset output unless this is absolutely necessary; % instead we suspend it for \LaTeX3.} % To prevent overfull box messages the |\parfillskip| is set to a % negative value. @@ -3838,7 +3845,7 @@ \parfillskip -\@pnumwidth % \end{macrocode} % Now we can set the entry, in a large bold font. We make sure to -% leave vertical mode, set the part title and add the pagenumber, +% leave vertical mode, set the part title and add the page number, % set flush right. % \begin{macrocode} {\leavevmode @@ -4238,9 +4245,9 @@ \columnsep 35\p@ \let\item\@idxitem} % \end{macrocode} -% When the document continues after the index and it was a one -% column document we have to switch back to one column after the -% index. +% When the document continues after the index and it was a +% one-column document we have to switch back to one column after +% the index. % \begin{macrocode} {\if@restonecol\onecolumn\else\clearpage\fi} % \end{macrocode} @@ -4293,7 +4300,7 @@ % % \begin{macro}{\c@footnote} % Footnotes are numbered within chapters in the report and book -% document styles. +% document classes. % \begin{macrocode} %\@addtoreset{footnote}{chapter} % \end{macrocode} @@ -4433,18 +4440,18 @@ % \end{macrocode} % \end{macro} % -% \subsection{Two column mode} +% \subsection{Two-column mode} % % \begin{macro}{\columnsep} -% This gives the distance between two columns in two column mode. +% This gives the distance between two columns in two-column mode. % \begin{macrocode} \setlength\columnsep{10\p@} % \end{macrocode} % \end{macro} % % \begin{macro}{\columnseprule} -% This gives the width of the rule between two columns in two -% column mode. We have no visible rule. +% This gives the width of the rule between two columns in +% two-column mode. We have no visible rule. % \begin{macrocode} \setlength\columnseprule{0\p@} % \end{macrocode} @@ -4454,7 +4461,7 @@ % We have \pstyle{plain} pages in the document classes article and % report unless the user specified otherwise. In the `book' % document class we use the page style \pstyle{headings} by -% default. We use arabic pagenumbers. +% default. We use arabic page numbers. % \begin{macrocode} %\pagestyle{plain} %\pagestyle{headings} diff --git a/Master/texmf-dist/source/latex/base/classes.ins b/Master/texmf-dist/source/latex/base/classes.ins index 13d49747272..be0dcaf8ff3 100644 --- a/Master/texmf-dist/source/latex/base/classes.ins +++ b/Master/texmf-dist/source/latex/base/classes.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/cmextra.ins b/Master/texmf-dist/source/latex/base/cmextra.ins index 05776a68075..c530e04d0bb 100644 --- a/Master/texmf-dist/source/latex/base/cmextra.ins +++ b/Master/texmf-dist/source/latex/base/cmextra.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/cmfonts.fdd b/Master/texmf-dist/source/latex/base/cmfonts.fdd index 1eb318b0492..f991ee564ee 100644 --- a/Master/texmf-dist/source/latex/base/cmfonts.fdd +++ b/Master/texmf-dist/source/latex/base/cmfonts.fdd @@ -1,7 +1,7 @@ % \iffalse meta-comment % % Copyright 1993-2019 -% The LaTeX3 Project and any individual authors listed elsewhere +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/cmfonts.ins b/Master/texmf-dist/source/latex/base/cmfonts.ins index b5ed3e3f106..d54a325f42e 100644 --- a/Master/texmf-dist/source/latex/base/cmfonts.ins +++ b/Master/texmf-dist/source/latex/base/cmfonts.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/doc.dtx b/Master/texmf-dist/source/latex/base/doc.dtx index 7e7817153c8..fb3412f21f4 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 (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -35,7 +35,7 @@ %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01] %<+package> \ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2020/06/15 v2.1m +%<+package|shortvrb> [2021/05/28 v2.1n %<+package|shortvrb> Standard LaTeX documentation package (FMi)] %\catcode`\<=12 % @@ -47,7 +47,7 @@ % % %% Package `doc' to use with LaTeX 2e -%% Copyright (C) 1989-1999 Frank Mittelbach, all rights reserved. +%% Copyright (C) 1989-2020 Frank Mittelbach, all rights reserved. % % % Version: Date: Changes: @@ -751,7 +751,7 @@ % in your package file. Precede it by any bibliography commands % necessary for your citations. % Alternatively, it may be more convenient to put all such calls -% amongst the arguments of the |\StopEventually| macro, in +% amongt the arguments of the |\StopEventually| macro, in % which case a |\Finale| command should appear at the end of % your file. % @@ -949,7 +949,7 @@ % macro.} % \DescribeMacro\changes % To maintain a change history within the file, the |\changes| -% command may be placed amongst the description part of the changed +% command may be placed amongt the description part of the changed % code. It takes three arguments, thus: % \begin{quote} % |\changes{|\meta{version}|}{|\meta{date}|}{|^^A @@ -2117,6 +2117,7 @@ % \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.} +% \changes{v2.1n}{2021/05/28}{Use same error message text as in format} % \begin{macrocode} \let\verb@balance@group\@empty @@ -2126,7 +2127,7 @@ \obeylines% \gdef\verb@eol@error{\obeylines% \def^^M{\verb@egroup\@latex@error{% - Text for \noexpand\verb command ended by end of line}\@ehc}}% + \noexpand\verb ended by end of line}\@ehc}}% \endgroup % \end{macrocode} % \end{macro} @@ -2200,7 +2201,7 @@ % % \begin{environment}{environment} % \changes{v1.8c}{1993/10/25}{Environment added} -% The ``environment'' envrionment will be implemented just like the +% The ``environment'' environment will be implemented just like the % ``macro'' environment flagging any differences in the code by % passing |\iffalse| or |\iftrue| to the |\m@cro@| environment % doing the actual work. @@ -3029,7 +3030,7 @@ % \begin{macro}{\addto@hook} % The code for adding tokens (the second argument) to a token list % (the first argument) is taken from~\cite{art:verbatim}, but it needs -% to be "\long" in case "\par" is amongst the tokens. +% to be "\long" in case "\par" is amongt the tokens. % \begin{macrocode} \long\def\addto@hook#1#2{#1\expandafter{\the#1#2}} % \end{macrocode} @@ -3149,7 +3150,7 @@ % of an `index style file'; the character selected for this function % is |=|, and therefore this character too must be specially treated % when it is met in a \TeX\ command. A suitable index style file is -% provided amongst the supporting files for this style file in +% provided amongt the supporting files for this style file in % \texttt{gind.ist} and is generated from this source by processing % with \texttt{docstrip} to extract the module \textbf{gind}. A % similar style file \texttt{gglo.ist} is supplied for sorting the @@ -4219,7 +4220,7 @@ % % \begin{macro}{\meta@font@select} % \changes{v2.0k}{2000/05/26}{Macro added (pr/3170)} -% Maske font used inside |\meta| customizable. +% Make font used inside |\meta| customizable. % \begin{macrocode} \def\meta@font@select{\itshape} % \end{macrocode} @@ -4431,7 +4432,7 @@ \global\catcode`#1\csname cc\string#1\endcsname % \end{macrocode} % \changes{v1.9e.2}{1994/02/07}{-js: Reset `cc`\protect\meta{c} in -% in \cs{DeleteShortVerb}} +% \cs{DeleteShortVerb}} % We must not forget to reset "\cc\"\meta{c}, otherwise the check in % "\MakeShortVerb" for a repeated definition will not work. % \begin{macrocode} @@ -4532,7 +4533,7 @@ % % \begin{macro}{\init@checksum} % The checksum mechanism works by counting backslashes in the -% macrocode. This initialises the count (when called from +% macrocode. This initializes the count (when called from % "\StopEventually"). % \changes{v1.5k}{1989/09/04}{Macro added to support checksum.} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/docstrip.dtx b/Master/texmf-dist/source/latex/base/docstrip.dtx index a0a06311edb..c7480988b44 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.dtx +++ b/Master/texmf-dist/source/latex/base/docstrip.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,8 +30,8 @@ \catcode`\}=2 \def\filename{docstrip.dtx} \def\fileversion{v2.6a} -\def\filedate{2020-07-07} -\def\docdate {2020-07-11} +\def\filedate{2020-11-23} +\def\docdate {2020-11-23} %% % %\iffalse @@ -42,7 +42,7 @@ %% Frank Mittelbach %% Copyright (C) 1995 Marcin Woli\'nski %% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski -%% Copyright (C) 1998-2020 LaTeX3 project and the above authors +%% Copyright (C) 1998-2021 LaTeX Project and the above authors. %% All rights are reserved. %% % @@ -77,7 +77,7 @@ % less/more dirty---all uses of \cs{afterfi}} % \changes{2.3e}{1995/09/25}{Directories support} % \changes{2.3e}{1995/10/24}{added \cs{makepathname} to support -% systems with bizzare pathnames} +% systems with bizare pathnames} % \changes{2.3e}{1995/10/25}{batch files work by \cs{input}} % \changes{2.3e}{1996/10/02}{Introduced ``open lists''} % \changes{2.4a}{1996/06/06}{Add stream limits (MDW)} @@ -122,7 +122,7 @@ % % \changes{2.1b}{1993/02/23}{modified mailaddress of Johannes} % \changes{2.4i}{1998/01/18}{removed mail addresses as it is hopeless -% to keep them uptodate} +% to keep them up-to-date} % \author{% % Frank Mittelbach % \and @@ -789,7 +789,7 @@ % % \section{Internal functions and variables} % -% An important consideration for \LaTeX3 development is separating +% An important consideration for \LaTeX\ development is separating % out public and internal functions. Functions and variables which % are private to one module should not be used or modified by any % other module. As \TeX{} does not have any formal namespacing @@ -809,7 +809,7 @@ % \end{verbatim} % % To extract the code using \ds, the original `guard' -% mecahnism is extended by the introduction of the syntax +% mechanism is extended by the introduction of the syntax % \texttt{\%<@@=\meta{module}>}. The \meta{module} name then % replaces the |@@| when the code is extracted, so that % \begin{verbatim} @@ -2305,7 +2305,7 @@ Z % delimited with |\endLine|) on all active output files i.e. % those with off-counters equal to zero. It uses the % search-and-replace macro \cs{replaceModuleInLine} to replace any -% occurences of \texttt{@@} with the current module name. +% occurrences of \texttt{@@} with the current module name. % If statistics are included, the counter % |\codeLinesPassed| is incremented by $1$. % \begin{macrocode} @@ -4310,7 +4310,7 @@ for copying and modification in the file \inFileName. % \begin{macro}{\WriteToDir} % Macro |\WriteToDir| is either empty or holds the prefix % necessary to read a file from the current directory. Under UNIX -% this is |./| but a lot of other systems addopted this concept. +% this is |./| but a lot of other systems adopted this concept. % This macro is a default value for |\destdir|. % % The definition of this macro is now delayed until |\@setwritedir| diff --git a/Master/texmf-dist/source/latex/base/docstrip.ins b/Master/texmf-dist/source/latex/base/docstrip.ins index 281a376761b..e34281fc365 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.ins +++ b/Master/texmf-dist/source/latex/base/docstrip.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -52,8 +52,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ec.ins b/Master/texmf-dist/source/latex/base/ec.ins index 4283ef1ddda..90b7b2e61f3 100644 --- a/Master/texmf-dist/source/latex/base/ec.ins +++ b/Master/texmf-dist/source/latex/base/ec.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/exscale.dtx b/Master/texmf-dist/source/latex/base/exscale.dtx index f13e0116cd1..ea67cb6fb72 100644 --- a/Master/texmf-dist/source/latex/base/exscale.dtx +++ b/Master/texmf-dist/source/latex/base/exscale.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/exscale.ins b/Master/texmf-dist/source/latex/base/exscale.ins index d504b056cb4..cfd2c535a77 100644 --- a/Master/texmf-dist/source/latex/base/exscale.ins +++ b/Master/texmf-dist/source/latex/base/exscale.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/fix-cm.dtx b/Master/texmf-dist/source/latex/base/fix-cm.dtx index e4c384ee70c..1be2e16cc09 100644 --- a/Master/texmf-dist/source/latex/base/fix-cm.dtx +++ b/Master/texmf-dist/source/latex/base/fix-cm.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -37,7 +37,7 @@ %\ProvidesFile{fix-cm.drv} % \fi % \ProvidesFile{fix-cm.dtx} - [2015/01/14 v1.1t fixes to LaTeX] + [2020/11/24 v1.1t fixes to LaTeX] % % \iffalse %<*driver> @@ -446,7 +446,7 @@ {<->sub * cmtt/m/sl}{} % \end{macrocode} % -% \paragraph{CM Typewiter (var.)} +% \paragraph{CM Typewriter (var.)} % \begin{macrocode} \DeclareFontFamily{T1}{cmvtt}{} \DeclareFontShape{T1}{cmvtt}{m}{n}{ diff --git a/Master/texmf-dist/source/latex/base/fix-cm.ins b/Master/texmf-dist/source/latex/base/fix-cm.ins index 0407d39630b..95931970f47 100644 --- a/Master/texmf-dist/source/latex/base/fix-cm.ins +++ b/Master/texmf-dist/source/latex/base/fix-cm.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/fontdef.dtx b/Master/texmf-dist/source/latex/base/fontdef.dtx index 632f1c9be56..581cfeb7895 100644 --- a/Master/texmf-dist/source/latex/base/fontdef.dtx +++ b/Master/texmf-dist/source/latex/base/fontdef.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -39,13 +39,13 @@ %\ProvidesFile{fontdef.drv} % \fi % \ProvidesFile{fontdef.dtx} -%<-latexrelease> [2020/08/01 v3.0i LaTeX Kernel +%<-latexrelease> [2021/01/15 v3.0i LaTeX Kernel % \iftrue (\else %(Text %(Math -%<+cfgtext>(Uncustomised text -%<+cfgmath>(Uncustomised math -%<+cfgprel>(Uncustomised preload +%<+cfgtext>(Uncustomized text +%<+cfgmath>(Uncustomized math +%<+cfgprel>(Uncustomized preload % \fi %<-latexrelease> font setup)] % @@ -110,7 +110,7 @@ % If you don't plan to use Computer Modern much or at all, it might % (!) be a good idea to make your own \texttt{fonttext.cfg}. Look at % the comments below (docstrip module `text') to see what should -% should go into such a file. +% go into such a file. % % To change the math font setup use a copy of \texttt{fontmath.ltx} % under the name \texttt{fontmath.cfg} and change this copy. However, @@ -227,7 +227,7 @@ % described in \texttt{ltoutenc.dtx}. % % By convention, text encoding specific declarations, including the -% declaration |\DeclareFontEncoding|, are kept in separate file of +% |\DeclareFontEncoding| declaration, are kept in separate file of % the form \meta{enc}\texttt{enc.def}, e.g.~\texttt{ot1enc.def}. This % allows other applications to make use of the declarations as % well. diff --git a/Master/texmf-dist/source/latex/base/format.ins b/Master/texmf-dist/source/latex/base/format.ins index 8796d16d3e2..eece2f57ef6 100644 --- a/Master/texmf-dist/source/latex/base/format.ins +++ b/Master/texmf-dist/source/latex/base/format.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -88,8 +88,8 @@ 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 2015 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 2015-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -123,8 +123,8 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -166,11 +166,14 @@ the system are in the document `cfgguide.tex'. % we have the extensions as soon as possible. \from{ltexpl.dtx}{2ekernel} % expl3-based extensions \from{ltdefns.dtx}{2ekernel} + \from{ltcmd.dtx}{2ekernel} % L3 layer module (used to be xparse) \from{lthooks.dtx}{2ekernel} % L3 layer module + \from{ltcmdhooks.dtx}{2ekernel} % L3 layer module \from{ltalloc.dtx}{2ekernel} \from{ltcntrl.dtx}{2ekernel} \from{lterror.dtx}{2ekernel} \from{ltpar.dtx}{2ekernel} + \from{ltpara.dtx}{2ekernel} % L3 layer module \from{ltspace.dtx}{2ekernel} \from{ltlogos.dtx}{2ekernel} \from{ltfiles.dtx}{2ekernel} @@ -233,15 +236,12 @@ the system are in the document `cfgguide.tex'. % hook management support -\generate{\file{everyshi-ltx.sty}{\from{ltshipout.dtx}{everyshi-ltx}}} % emulating everyshi \generate{\file{atbegshi-ltx.sty}{\from{ltshipout.dtx}{atbegshi-ltx}}} % emulating atbegshi \generate{\file{atveryend-ltx.sty}{\from{ltfilehook.dtx}{atveryend-ltx}}} % emulating atveryend \generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}} - - % luatex support (TeX part) \generate{\file{ltluatex.tex}{\from{ltluatex.dtx}{tex,plain}}} diff --git a/Master/texmf-dist/source/latex/base/graphpap.dtx b/Master/texmf-dist/source/latex/base/graphpap.dtx index ac72f4dca5f..cc9f4da3cb1 100644 --- a/Master/texmf-dist/source/latex/base/graphpap.dtx +++ b/Master/texmf-dist/source/latex/base/graphpap.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/graphpap.ins b/Master/texmf-dist/source/latex/base/graphpap.ins index b5bb800122a..65156ad9176 100644 --- a/Master/texmf-dist/source/latex/base/graphpap.ins +++ b/Master/texmf-dist/source/latex/base/graphpap.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ifthen.dtx b/Master/texmf-dist/source/latex/base/ifthen.dtx index f2157e094ab..acb5cf19670 100644 --- a/Master/texmf-dist/source/latex/base/ifthen.dtx +++ b/Master/texmf-dist/source/latex/base/ifthen.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,7 +30,7 @@ %% %% File `ifthen.dtx'. %% Copyright (C) 1991 by Leslie Lamport -%% Copyright (C) 1994-2001 LaTeX3 project, David Carlisle +%% Copyright (C) 1994-2001 LaTeX project, David Carlisle %% all rights reserved. %% % @@ -42,7 +42,7 @@ %\ProvidesFile{ifthen.drv} % \fi % \ProvidesFile{ifthen.dtx} - [2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)] + [2020/11/24 v1.1c Standard LaTeX ifthen package (DPC)] % % \iffalse %<*driver> @@ -368,7 +368,7 @@ % \end{macro} % % \begin{macro}{\TE@endeval} -% Finalise a term. (Expanded on the first pass). +% Finalize a term. (Expanded on the first pass). % \begin{macrocode} \def\TE@endeval{\relax \noexpand\TE@setvaltrue\noexpand diff --git a/Master/texmf-dist/source/latex/base/ifthen.ins b/Master/texmf-dist/source/latex/base/ifthen.ins index 0e813cd5de3..42e1d3f5d93 100644 --- a/Master/texmf-dist/source/latex/base/ifthen.ins +++ b/Master/texmf-dist/source/latex/base/ifthen.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/inputenc.dtx b/Master/texmf-dist/source/latex/base/inputenc.dtx index c1d08b4830f..1b8691d30fa 100644 --- a/Master/texmf-dist/source/latex/base/inputenc.dtx +++ b/Master/texmf-dist/source/latex/base/inputenc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -123,7 +123,7 @@ % THIS MAY CHANGE} % \changes{v0.95}{1997/12/20}{Updated documentation} % \changes{v0.97}{1998/03/05}{Spanish ords changed to text chars, pr/2579} -% \changes{v1.1b}{2006/03/04}{Number of normalisations in the LICR +% \changes{v1.1b}{2006/03/04}{Number of normalizations in the LICR % representation (pr/3849)} % \changes{v1.1c}{2006/11/18}{Added missing \cs{ProvidesFile} line for cp1257 (pr/3892)} % @@ -283,7 +283,7 @@ % with the |utf8| option. % % The |\DeclareUnicodeCharacter| takes UTF-8 code point as its first argument -% (in form of a a hexadecimal number) and the definition that this maps to as +% (in form of a hexadecimal number) and the definition that this maps to as % its second argument. For example, the code point |00E4| which is % ``LATIN SMALL LETTER A WITH DIAERESIS'' would be set up via: %\begin{verbatim} @@ -410,7 +410,7 @@ % \ProvidesFile{cp1252.def} % \ProvidesFile{cp1250.def} % \ProvidesFile{cp1257.def} - [2020/08/01 v1.3d Input encoding file] + [2021/02/14 v1.3d Input encoding file] %%% %%% If you need a Euro symbol, try cp858 instead. %%% @@ -1053,7 +1053,7 @@ % % The ISO Latin-3 encoding file defines the characters % in the ISO 8859-3 encoding. It was contributed by -% by J\"org Knappen (\texttt{joerg.knappen@uni-mainz.de}) and +% J\"org Knappen (\texttt{joerg.knappen@uni-mainz.de}) and % adapted by Chris Rowley. % % It can be used for general purpose applications in diff --git a/Master/texmf-dist/source/latex/base/inputenc.ins b/Master/texmf-dist/source/latex/base/inputenc.ins index 6494a689eab..920a585bffc 100644 --- a/Master/texmf-dist/source/latex/base/inputenc.ins +++ b/Master/texmf-dist/source/latex/base/inputenc.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/latex209.dtx b/Master/texmf-dist/source/latex/base/latex209.dtx index d08a8001b56..bf92f8ef1e8 100644 --- a/Master/texmf-dist/source/latex/base/latex209.dtx +++ b/Master/texmf-dist/source/latex/base/latex209.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -200,7 +200,7 @@ % \end{macrocode} % Describe the file. % \begin{macrocode} -\ProvidesFile{latex209.def}[2020/08/21 v0.55 Standard LaTeX file] +\ProvidesFile{latex209.def}[2020/11/26 v0.55 Standard LaTeX file] % \end{macrocode} % \changes{v0.24}{1994/05/14}{Removed date.} % \changes{v0.40}{1995/03/21} @@ -712,7 +712,7 @@ % % \changes{v0.18}{1994/03/11}{Added the catcode changes} % -% By default, \LaTeXe{} makes the input charactes 0--8, 11, 14--31 and +% By default, \LaTeXe{} makes the input characters 0--8, 11, 14--31 and % 128--255 illegal. In compatibility mode, we restore their old % meanings. % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/latex209.ins b/Master/texmf-dist/source/latex/base/latex209.ins index bb72f344f1b..33ebc2488c4 100644 --- a/Master/texmf-dist/source/latex/base/latex209.ins +++ b/Master/texmf-dist/source/latex/base/latex209.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/latexrelease.dtx b/Master/texmf-dist/source/latex/base/latexrelease.dtx index 5ee39a3a2df..7d2290f4d8a 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.dtx +++ b/Master/texmf-dist/source/latex/base/latexrelease.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -37,13 +37,13 @@ %\ProvidesPackage{fixltx2e} % [2016/12/29 v2.1a fixes to LaTeX (obsolete)] %\ProvidesPackage{latexrelease} -%<*!fixltx2e> +%<*latexrelease> % \fi % \ProvidesFile{latexrelease.dtx} - [2018/05/08 v1.0k LaTeX release emulation and tests + [2021/04/29 v1.0n LaTeX release emulation and tests (including releases up to \latexreleaseversion)] % \iffalse -% +% %<*driver> \documentclass{ltxdoc} \newcommand\Lopt[1]{\textsf{#1}} @@ -51,6 +51,8 @@ \providecommand{\file}[1]{\texttt{#1}} \providecommand{\MF}{\textsf{Metafont}} \providecommand{\danger}{\marginpar[\hfill\protect\Huge!!]{\protect\Huge!!\hfill}} + \DeclareRobustCommand\cs[2][]{\texttt{\char`\\\detokenize{#2}}} + \DeclareRobustCommand\pkg[1]{\textsf{#1}} \begin{document} \DocInput{latexrelease.dtx} \end{document} @@ -69,7 +71,7 @@ % \title{The \Lpack{latexrelease} package\thanks{This file % has version number \fileversion, last % revised \filedate.}} -% \author{The \LaTeX3 Project} +% \author{The \LaTeX{} Project} % \date{\filedate} % \MaintainedByLaTeXTeam{latex} % \maketitle @@ -129,7 +131,6 @@ % package has no information will generate a warning. Dates % earlier than 2015 will work but will roll back to some point in 2015 % when the method was introduced. -% |\IncludeInRelease| command is defined. % The |\requestedLaTeXdate| is set to the normalized date argument % so that package rollback defaults to the specified date. % @@ -137,9 +138,6 @@ % |current| This is the default behaviour, it does not change the % effective date of the format but does ensure that the % |\IncludeInRelease| command is defined. -% the |\requestedLaTeXdate| is reset to 0 so that package rollback -% does not use the implicit date. -% |\IncludeInRelease| command is defined. % The |\requestedLaTeXdate| macro is reset to 0 so that package rollback % does not use the implicit date. % @@ -147,11 +145,16 @@ % |latest| sets the effective date of the format to the release date % of this file, so in an older format applies all patches currently % available. -% |\IncludeInRelease| command is defined. % The |\requestedLaTeXdate| macro is reset to 0 so that package rollback % does not use the implicit date. % \end{itemize} % +% In all cases, when the package is loaded, the |\sourceLaTeXdate| is +% defined to be the numerical representation of |\fmtversion| before the +% rollback/forward actually happens, so it is possible to test from which +% was the original \LaTeX{} version before \Lpack{latexrelease} was loaded. +% This is particularly useful when some code in a package has to be +% redefined differently if rolling backwards in time or forwards. % % \section{Release Specific Code} % @@ -345,7 +348,7 @@ % % Now if you make a further change to |\widget| in the future you % simply copy the current definition into the empty block and add a new -% empty declaration with todays date and the current format date. This +% empty declaration with today's date and the current format date. This % way your main code stays readable and the old versions accumulate at % the end of the package.\footnote{Of course there may be some cases % in which the old code has to be in a specific place within the @@ -363,6 +366,99 @@ % necessary as the new code only gets defined if that release is % chosen. % +% \section{Declaring entire modules} +% +% Sometimes a large chunk of code is added as a module to another larger +% code base. As example of that in the 2020-10-01 release \LaTeX{} got +% a new hook management system, \pkg{lthooks}, which was added in one go +% and, as with all changes to the kernel, it was added to +% \pkg{latexrelease}. However rolling back from a future date to the +% 2020-10-01 release didn't work because \pkg{latexrelease} would try to +% define again all those commands, which would result in many +% ``already defined'' errors and similar issues. +% +% To solve that problem, completely new modules can be defined in +% \pkg{latexrelease} using the commands: +% \begin{quote} +% \cs{NewModuleRelease}%^^A +% \verb|{|\meta{initial release date}%^^A +% \verb|}{|\meta{name}\verb|}{|\meta{message}\verb|}|\\ +% \null\quad\meta{module code}\\ +% \cs{IncludeInRelease}%^^A +% \verb|{0000/00/00}{|\meta{name}\verb|}{|\meta{message}\verb|}|\\ +% \null\quad\meta{undefine module code}\\ +% \cs{EndModuleRelease} +% \end{quote} +% With that setup, the module \meta{name} will be declared to exist only +% in releases equal or later \meta{initial release date}. +% +% If \pkg{latexrelease} is rolling backwards or forwards between dates +% after \meta{initial release date}, then all the \meta{module code} is +% skipped, except when inside \meta{IncludeInRelease} guards, in which +% case the code is applied or skipped as discussed above. +% +% If rolling forward from a date before the module's \meta{initial +% release date} to a date after that, then all the \meta{module code} is +% executed to define the module, and \cs{IncludeInRelease} guards are +% executed accordingly, depending on the date declared and the target +% date. +% +% If \pkg{latexrelease} is rolling back to a date before \meta{release +% date}, then the code in the \cs{IncludeInRelease} guard dated +% \verb|0000/00/00| is executed instead to undefine the module. This +% guard \emph{is not} ended by the usual \cs{EndIncludeInRelease}, but +% instead by \cs{EndModuleRelease}. +% +% Finally, if rolling backwards or forwards between dates both before +% \meta{initial release date}, the entire code between +% \meta{NewModuleRelease} and \meta{EndModuleRelease} is entirely +% skipped. +% +% \subsection{Example} +% +% Here is an example usage of the structure described above, as it would +% be used in the \LaTeX{} kernel, taking \pkg{lthooks} as example: +% \begin{verbatim} +% %<*2ekernel|latexrelease> +% \ExplSyntaxOn +% %\NewModuleRelease{2020/10/01}{lthooks}% +% % {The~hook~management~system} +% \NewDocumentCommand \NewHook { m } +% { \hook_new:n {#1} } +% %\IncludeInRelease{2021/06/01}{\AddToHook}{Long~argument} +% \NewDocumentCommand \AddToHook { m o +m } +% { \hook_gput_code:nnn {#1} {#2} {#3} } +% %\EndIncludeInRelease +% % +% %\IncludeInRelease{2020/10/01}{\AddToHook}{Long~argument} +% %\NewDocumentCommand \AddToHook { m o m } +% % { \hook_gput_code:nnn {#1} {#2} {#3} } +% %\EndIncludeInRelease +% % +% %\IncludeInRelease{0000/00/00}{lthooks}{Undefine~lthooks} +% %\cs_undefine:N \NewHook +% %\cs_undefine:N \AddToHook +% %\EndModuleRelease +% \ExplSyntaxOff +% % +% \end{verbatim} +% +% In the example above, \cs{NewHook} is declared only once, and +% unchanged in the next release (2021/06/01 in the example), so it has +% no \cs{IncludeInRelease} guards, and will only be defined if needed. +% \cs{AddToHook}, on the other hand, changed between the two releases +% (made up for the example; it didn't really happen) +% and has an \cs{IncludeInRelease} block for the current release (off +% \pkg{docstrip} guards, so it goes into the kernel too), and another +% for the previous release (in \pkg{docstrip} guards so it goes only +% into \pkg{latexrelease}). +% +% Note that in the example above, \cs{ExplSyntaxOn} and +% \cs{ExplSyntaxOff} were added \emph{outside} the module code because, +% as discussed above, sometimes the code outside \cs{IncludeInRelease} +% guards may be skipped, but not the code inside them, and in that case +% the catcodes would be wrong when defining the code. +% % \section{fixltx2e} % % As noted above, prior to the 2015 \LaTeX\ release updates to the @@ -386,17 +482,34 @@ \NeedsTeXFormat{LaTeX2e}[1996/06/01] % \end{macrocode} % -% \section{Setup} +% \subsection{Setup} +% +% \begin{macro}{\sourceLaTeXdate} +% \changes{v1.0l}{2021/01/23}{\cs{sourceLaTeXdate} added} +% \changes{v1.0m}{2021/03/18}{Define \cs{sourceLaTeXdate} conditionally} +% Store the original \LaTeX{} format version +% as a number in the format |YYYYMMDD|. This macro has to +% be defined conditionally, so that it isn't changed in case +% \file{latexrelease.sty} is loaded twice (for tests), but it +% can't be defined in the kernel only, otherwise +% \file{latexrelease.sty} wouldn't work in older \LaTeX{} due +% to the missing macro. +% \begin{macrocode} +\@ifundefined{sourceLaTeXdate}{% + \edef\sourceLaTeXdate{% + \expandafter\@parse@version\fmtversion//00\@nil}}{}% +% \end{macrocode} +% \end{macro} % % \begin{macro}{\IncludeInRelease} % \begin{macro}{\EndIncludeInRelease} -% \begin{macrocode} -% \end{macrocode} +% These are defined in \file{ltvers.dtx}. % \end{macro} % \end{macro} % % \changes{v1.0c}{2015/02/19}{Swap argument order} -% \changes{v1.0k}{2018/05/08}{reset \cs{\requestedLaTeXdate} for current and latest options, gitub issue 43} +% \changes{v1.0k}{2018/05/08}{reset \cs{\requestedLaTeXdate} for current +% and latest options, github issue 43} % \begin{macrocode} \DeclareOption*{% \def\@IncludeInRelease#1[#2]{\@IncludeInRele@se{#1}}% @@ -483,16 +596,213 @@ of this package available from CTAN} % \end{macrocode} % % -% \section{Individual Changes} +% \subsection{Ignoring \texttt{\string_new} errors when rolling back} % -% The code for each change will be inserted at this point, extracted -% from the kernel source files. +% Enforce \cs{ExplSyntaxOn} and \cs{ExplSyntaxOff} to be \cs{relax} in +% \pkg{latexrelease} if they are not yet defined. They are later +% restored to be undefined if needed. +% \begin{macrocode} +\csname ExplSyntaxOn\endcsname +\csname ExplSyntaxOff\endcsname +% \end{macrocode} +% +% \changes{v1.0m}{2021/03/18} +% {Make \texttt{\string_new} definitions harmless} +% +% Define a set of changes here, but we'll only use them later to make +% sure they are applied after \pkg{expl3} is loaded. If loading from a +% rather old format, we don't have \cs{ExplSyntaxOn} yet. +% \begin{macrocode} +\begingroup + \endlinechar=-1 + \catcode95=11 % _ + \catcode58=11 % : + \catcode126=10 % ~ + \catcode32=09 % + \xdef\latexrelease@postexpl{\unexpanded{% +%<@@=latexrelease> +% \end{macrocode} +% +% First we'll define a \cs{declarecommand} that does \cs{renewcommand} +% if the command being defined already exists, and \cs{newcommand} +% otherwise. +% \begin{macrocode} +\cs_gset_protected:Npn \@@_declare_command:w + { \@star@or@long \@@_declare_command:Nw } +\cs_gset_protected:Npn \@@_declare_command:Nw #1 + { \cs_if_exist:NTF #1 { \renew@command } { \new@command } #1 } +% \end{macrocode} +% +% Then define a version of \cs{e@alloc} that checks if the control +% sequence being defined already exists, and if so, checks if its +% meaning is the same as the one that would be defined with the call to +% \cs{e@alloc}. If both tests pass, nothing is defined to save a +% register. This version also takes care of setting +% \cs{allocationnumber} to the value it would have after the register is +% allocated. +% \begin{macrocode} +\cs_gset_protected:Npn \@@_e@alloc:NnnnnN #1 #2 #3 #4 #5 #6 + { + \cs_if_free:NTF #6 + { \use:n } + { + \exp_after:wN \@@_e@alloc:N + \token_to_meaning:N #6 \scan_stop: {#2} #6 + } + { \@@_e@alloc #1 {#2} {#3} {#4} {#5} #6 } + } +% \end{macrocode} +% Walk through the meaning of the control sequence token by token, +% looking for the register allocation number. +% \begin{macrocode} +\cs_gset_protected:Npn \@@_e@alloc:N #1 + { + \if_int_compare:w 0 < 0 + \if_int_compare:w 10 < 9#1 ~ 1 \fi: + \if_charcode:w " #1 1 \fi: \exp_stop_f: + \tex_afterassignment:D \@@_e@alloc:w + \@tempcnta #1 + \use_i:nnn + \fi: + \use:n + { + \if_meaning:w \scan_stop: #1 + \exp_after:wN \use_iv:nnnn + \fi: + \@@_e@alloc:N + } + } +% \end{macrocode} +% When found, check if it is the exact same register as it would be +% allocated, and if it is, set \cs{allocationnumber} accordingly and +% exit, otherwise undefine the register and allocate from scratch. +% \begin{macrocode} +\cs_gset_protected:Npn \@@_e@alloc:w #1 \scan_stop: #2 #3 + { + #2 \@@_tmp:w = \@tempcnta + \token_if_eq_meaning:NNTF #3 \@@_tmp:w + { \int_set_eq:NN \allocationnumber \@tempcnta \use_none:n } + { \cs_set_eq:NN #3 \tex_undefined:D \use:n } + } +% \end{macrocode} % +% Now create a token list to hold the list of changed commands, and +% define a temporary macro that will loop through the command list, +% store each in \cs{l_@@_restores_tl}, save a copy, and redefine each. % \begin{macrocode} +\tl_clear_new:N \l_@@_restores_tl +\cs_gset:Npn \@@_tmp:w #1 #2 + { + \quark_if_recursion_tail_stop_do:Nn #1 + { \cs_undefine:N \@@_tmp:w } + \tl_put_right:Nn \l_@@_restores_tl {#1} + \cs_set_eq:cN { @@_ \cs_to_str:N #1 } #1 + \cs_set_eq:NN #1 #2 + \@@_tmp:w + } +% \end{macrocode} +% +% The redefinitions below are needed because: +% \begin{description} +% \def\makelabel#1{\cs{#1}} +% \item[__kernel_chk_if_free_cs:N] This function is used ubiquitously +% in the \pkg{l3kernel} to check if a control sequence is definable, +% and give an error otherwise (similar to \cs{@ifdefinable}). +% Making it a no-op is enough for most cases (except when defining +% new registers); +% \item[e@alloc] In the case of new registers, we waste an allocation +% number if we do \cs[no-index]{new\meta{thing}} in a register +% that's already allocated, so the redefinition of \cs{e@alloc} +% checks if the new register is really necessary. This code does +% not clear the register, which might cause problems in the future, +% if a register is allocated but not properly cleared before using; +% \item[__kernel_msg_error:nnx] This command is used to error on +% already defined scan marks. Just making the error do nothing is +% enough, as no action is taken in that case; +% \item[msg_new:nnnn] Used to define new messages. Making it +% \texttt{\string_gset} is enough. Other msg commands like +% \cs{msg_new:nnn} and \cs[no-index]{__kernel_msg_new:nnn(n)} are +% defined in terms of \cs{msg_new:nnnn}, so there is no need to +% change the other ones; +% \item[NewDocumentCommand] Used to define user-level commands in the +% kernel. Making it equal to \cs{DeclareDocumentCommand} solves the +% problem; +% \item[newcommand] Same as above. +% \end{description} +% And here we go: +% \begin{macrocode} +\@@_tmp:w + \__kernel_chk_if_free_cs:N \use_none:n + \e@alloc \@@_e@alloc:NnnnnN + \__kernel_msg_error:nnx \use_none:nnn + \msg_new:nnnn \msg_gset:nnnn + \NewDocumentCommand \DeclareDocumentCommand + \newcommand \@@_declare_command:w +% \end{macrocode} +% Temp addition \ldots +% \begin{macrocode} + \__kernel_msg_error:nnn \use_none:nnn % needed while redirect for kernel msgs doesn't work + \q_recursion_tail \q_recursion_tail + \q_recursion_stop +% \end{macrocode} +% +% 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). +% \begin{macrocode} +\msg_redirect_name:nnn { hooks } { exists } { none } +% \end{macrocode} +% +% \begin{macrocode} + }}% +\endgroup % % \end{macrocode} % -% \section{fixltx2e} +% \subsection{Undoing the temp modifications} +% +% If \cs{ExplSyntaxOn} exists (defined and not equal \cs{relax}), then +% use the \pkg{expl3} restore code, otherwise restore \cs{ExplSyntaxOn} +% and \cs{ExplSyntaxOff} to be undefined. +% \begin{macrocode} +%<*latexrelease-finish> +\@ifundefined{ExplSyntaxOn}% + {\let\ExplSyntaxOn\@undefined + \let\ExplSyntaxOff\@undefined + \@gobble}% + {\ExplSyntaxOn + \@firstofone}% + {% +% \end{macrocode} +% +% Now just loop through the list of redefined commands and restore their +% previous meanings. +% \begin{macrocode} +\tl_map_inline:Nn \l_@@_restores_tl + { + \cs_set_eq:Nc #1 { @@_ \cs_to_str:N #1 } + \cs_undefine:c { @@_ \cs_to_str:N #1 } + } +\tl_clear:N \l_@@_restores_tl +% \end{macrocode} +% +% And restore the hook error message. +% \begin{macrocode} +\msg_redirect_name:nnn { hooks } { exists } { } +% \end{macrocode} +% +% \begin{macrocode} +%<@@=> + \ExplSyntaxOff}% +% +% \end{macrocode} +% +% \subsection{Individual Changes} +% +% The code for each change will be inserted at this point, extracted +% from the kernel source files. +% +% +% \subsection{fixltx2e} % % Generate a stub \Lpack{fixltx2e} package: % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/latexrelease.ins b/Master/texmf-dist/source/latex/base/latexrelease.ins index ffc92374c35..0b65114a2f9 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.ins +++ b/Master/texmf-dist/source/latex/base/latexrelease.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -93,13 +93,16 @@ extension .ins) which are part of the distribution. \from{ltluatex.dtx} {latexrelease}% empty \from{ltexpl.dtx} {latexrelease}% empty \from{ltdefns.dtx} {latexrelease}% - \from{lthooks.dtx} {latexrelease}% empty % L3 layer module + \from{ltcmd.dtx} {latexrelease}% + \from{lthooks.dtx} {latexrelease}% L3 layer module + \from{ltcmdhooks.dtx} {latexrelease}% L3 layer module \from{ltalloc.dtx} {latexrelease}% empty \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty \from{ltpar.dtx} {latexrelease}% empty + \from{ltpara.dtx} {latexrelease}% empty \from{ltspace.dtx} {latexrelease}% - \from{ltlogos.dtx} {latexrelease}% empty + \from{ltlogos.dtx} {latexrelease}% L3 layer module \from{ltfiles.dtx} {latexrelease}% \from{ltoutenc.dtx} {latexrelease}% \from{ltcounts.dtx} {latexrelease}% @@ -132,6 +135,7 @@ extension .ins) which are part of the distribution. \from{ltoutput.dtx} {latexrelease}% \from{ltfsscmp.dtx} {latexrelease}% only in latexrelease! \from{ltfinal.dtx} {latexrelease}% + \from{latexrelease.dtx}{latexrelease-finish}% } diff --git a/Master/texmf-dist/source/latex/base/latexsym.dtx b/Master/texmf-dist/source/latex/base/latexsym.dtx index 908f11e1244..7a97aa4318c 100644 --- a/Master/texmf-dist/source/latex/base/latexsym.dtx +++ b/Master/texmf-dist/source/latex/base/latexsym.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/latexsym.ins b/Master/texmf-dist/source/latex/base/latexsym.ins index 9e9901b879c..902bbfc9e8e 100644 --- a/Master/texmf-dist/source/latex/base/latexsym.ins +++ b/Master/texmf-dist/source/latex/base/latexsym.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -87,8 +87,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/letter.dtx b/Master/texmf-dist/source/latex/base/letter.dtx index 7b31dfbbc96..6beee81735a 100644 --- a/Master/texmf-dist/source/latex/base/letter.dtx +++ b/Master/texmf-dist/source/latex/base/letter.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% 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 @@ %<*driver> \ProvidesFile{letter.drv} % - [2020/03/11 v1.3b + [2021/03/05 v1.3c %<+letter> Standard LaTeX document class] % \end{macrocode} % @@ -165,7 +165,7 @@ % \changes{v1.3a}{2020/03/07}{merged changes to classes.dtx into letter.dtx} % % \iffalse -% Copyright (C) 1994 LaTeX3 project, Frank Mittelbach +% Copyright (C) 1994 LaTeX Project, Frank Mittelbach % and Rainer Sch\"opf, all rights reserved. % \fi % @@ -1019,7 +1019,29 @@ \@date \end{tabular}\par}% \fi \vspace{2\parskip}% - {\raggedright \toname \\ \toaddress \par}% +% \end{macrocode} +% If the address field used \verb=\\[...]= then we have +% \cs{toaddress} starting with the bracket argument as the split +% was done simply at \verb=\\=. So we add \cs{expandafter} here so +% that is will be used and not typeset. A better fix would be to do +% a proper parsing but \ldots +% +% Other classes based on \texttt{letter.cls} could benefit from the same fix, e.g., +% \texttt{akletter.cls}, +% \texttt{bletter.cls}, +% \texttt{letter.cls}, +% \texttt{chletter.cls}, +% \texttt{extletter.cls},\\ +% \texttt{frletter.cls}, +% \texttt{hletter.cls}, +% \texttt{scrlttr2.cls} (change rejected), +% \texttt{lettre.cls}, +% \texttt{beletter.cls},\\ +% \texttt{brief.cls} and perhaps others. +% +% \changes{v1.3c}{2020/12/28}{Add \cs{expandafter} (gh/427)} +% \begin{macrocode} + {\raggedright \toname \expandafter\\\toaddress \par}% \vspace{2\parskip}% #1\par\nobreak} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/base/letter.ins b/Master/texmf-dist/source/latex/base/letter.ins index 8e8ed4ef7b9..44777393eb6 100644 --- a/Master/texmf-dist/source/latex/base/letter.ins +++ b/Master/texmf-dist/source/latex/base/letter.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltalloc.dtx b/Master/texmf-dist/source/latex/base/ltalloc.dtx index d18df9ad896..59c492836f9 100644 --- a/Master/texmf-dist/source/latex/base/ltalloc.dtx +++ b/Master/texmf-dist/source/latex/base/ltalloc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltbibl.dtx b/Master/texmf-dist/source/latex/base/ltbibl.dtx index a3a25308fe8..cda0fa160ad 100644 --- a/Master/texmf-dist/source/latex/base/ltbibl.dtx +++ b/Master/texmf-dist/source/latex/base/ltbibl.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltbibl.dtx} - [2018/11/09 v1.1r LaTeX Kernel (Bibliography)] + [2020/12/10 v1.1s LaTeX Kernel (Bibliography)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltbibl.dtx} @@ -104,7 +104,7 @@ % but puts nothing in the text. % % |\nocite{*}| is special: it tells \BibTeX{} to put the whole of a -% collection of references into the bibiography. +% collection of references into the bibliography. % % \StopEventually{} % @@ -253,7 +253,7 @@ % year citations it becomes more than questionable. % % So Chris added yet another hook here, as suggested by, at least, -% Donald Arsenau. Note that this one is inside the first argument +% Donald Arseneau. Note that this one is inside the first argument % of the |\@cite| hook. % This decouples the top-level typesetting of the citation from % the details of the other business conducted here. All this really @@ -327,6 +327,10 @@ % \changes{v1.1g}{1995/05/08}{Use \cs{@firstofone}} % \changes{v1.1k}{1995/10/20}{Removed refundefined flag} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\nocite}{Allow nocite in preamble}% \def\nocite#1{\@bsphack % \end{macrocode} % With the implementation designed already in \LaTeX\,2.09 the @@ -335,10 +339,15 @@ % that point. As a result the ``reference'' will appear on the % terminal and nothing else will happen. % -% This would be easy to fix, but then a document using the fix will +% [This would be easy to fix, but then a document using the fix will % silently fail on an older release of \LaTeX{}, missing all % citations done with |\nocite|. Thus we do only generate an error -% message and leave the fix for a \LaTeXe{} successor. +% message and leave the fix for a \LaTeXe{} successor.] +% +% Given that we are now a quarter century into using \LaTeXe{} +% there is no good reason any more do limit ourself to 2.09 +% conciderations. So we now simply delay the \cs{nocide} if it is +% issued in the preamble. % % \changes{v1.1o}{2003/05/18}{Check if we are after \cs{document}} % \changes{v1.1p}{2004/01/04}{Changed error message} @@ -354,18 +363,48 @@ \@latex@warning{Citation `\@citeb' undefined}}{}}% \else % \end{macrocode} -% But before |\begin{document}| we raise an error message: +% But before |\begin{document}| we raised an error message in the +% past but as of 2021/05 not any longer. % \begin{macrocode} - \@latex@error{Cannot be used in preamble}\@eha +% \@latex@error{Cannot be used in preamble}\@eha % \end{macrocode} -% Without the compatibility problems we could fix the problem as follows: +% Instead we delay the declaration to the start of the document. +% We have to use a late hook for this, so that it comes after the +% \texttt{.aux} file is open for writing and after +% \cs{@preamblecmds} was executed to change the above +% test. Therefore \cs{AtBeginDocument} would still be too early. +% \changes{v1.1s}{2020/12/10}{Delay any \cs{nocite} in the preamble +% instead of raising an error} % \begin{macrocode} - % \AtBeginDocument{\nocite{#1}} + \AddToHook{begindocument/end}[kernel]{\nocite{#1}}% \fi \@esphack} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\nocite}{Allow nocite in preamble}% +% +%\def\nocite#1{\@bsphack +% \ifx\@onlypreamble\document +% \@for\@citeb:=#1\do{% +% \edef\@citeb{\expandafter\@firstofone\@citeb}% +% \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi +% \@ifundefined{b@\@citeb}{\G@refundefinedtrue +% \@latex@warning{Citation `\@citeb' undefined}}{}}% +% \else +% \@latex@error{Cannot be used in preamble}\@eha +% \fi +% \@esphack} +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} +% % Since |\nocite{*}| should not produce a warning about undefined -% citation keys (seee PR 557), we need to set the control sequence +% citation keys (see PR 557), we need to set the control sequence % `|\b@*|' to something other than |\relax|. As a result |\cite{*}| % will not warn either (but that never worked with \BibTeX{} in the % first place). diff --git a/Master/texmf-dist/source/latex/base/ltboxes.dtx b/Master/texmf-dist/source/latex/base/ltboxes.dtx index 39c134b3bfd..8499d3ab8b9 100644 --- a/Master/texmf-dist/source/latex/base/ltboxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltboxes.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltboxes.dtx} - [2020/09/27 v1.4a LaTeX Kernel (Box Commands)] + [2021/02/10 v1.4b LaTeX Kernel (Box Commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltboxes.dtx} @@ -222,7 +222,7 @@ % \changes{v1.0j}{1994/10/18} % {stuff from ltpatch done} % \changes{v1.0p}{1994/11/09} -% {more colour changes\ldots} +% {more color changes\ldots} % \changes{v1.0q}{1994/11/17} % {\cs{@tempa} to \cs{reserved@a}} % \changes{v1.0t}{1995/05/07}{Use \cs{hb@xt@}} @@ -422,7 +422,7 @@ % {macro added} % \changes{v0.1a}{1993/12/03} % {color support} -% This macro is initially a no-op, but the colour package will redefine +% This macro is initially a no-op, but the color package will redefine % it to insert a |\special|. % \begin{macrocode} \let\set@color\relax @@ -431,38 +431,66 @@ % % \begin{macro}{\color@begingroup} % \changes{v1.0b}{1994/03/14} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\color@endgroup} % \changes{v1.0b}{1994/03/14} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\color@setgroup} % \changes{v1.0f}{1994/05/11} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\normalcolor} % \changes{v1.0g}{1994/05/12} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\color@hbox} % \changes{v1.0n}{1994/11/05} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\color@vbox} % \changes{v1.0r}{1994/11/18} -% {macro added for colour support} +% {macro added for color support} % \begin{macro}{\color@endbox} % \changes{v1.0n}{1994/11/05} -% {macro added for colour support} -% These macros are initially a no-op, but the colour package will +% {macro added for color support} +% \changes{v1.4b}{2021/02/04} +% {Always add the color groups (gh/488)} +% In the past these macros were initially no-ops, and the \pkg{color} +% package redefined % redefine them to be |\begingroup|, |\endgroup|, % |\begingroup\set@color|,\\ |\hbox\bgroup\color@begingroup|, % |\color@endgroup\egroup|. -% and \meta{set to main document colour} respectively. +% and \meta{set to main document color} respectively. +% +% Nowadays we always set the group already in the kernel as this makes the +% coding simpler. % \begin{macrocode} -\let\color@begingroup\relax -\let\color@endgroup\relax -\let\color@setgroup\relax -\let\normalcolor\relax -\let\color@hbox\relax -\let\color@vbox\relax -\let\color@endbox\relax +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\color@begingroup}{color group settings}% +\let\color@begingroup\begingroup +\def\color@endgroup{\endgraf\endgroup} +\def\color@setgroup{\color@begingroup} % changed further in color package +\let\normalcolor\relax % remains untouched; only changed in a color package +\def\color@hbox{\hbox\bgroup\color@begingroup} +\def\color@vbox{\vbox\bgroup\color@begingroup} +\def\color@endbox{\color@endgroup\egroup} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\color@begingroup}{color group settings}% +% +%\let\color@begingroup\relax +%\let\color@endgroup\relax +%\let\color@setgroup\relax +%\let\normalcolor\relax +%\let\color@hbox\relax +%\let\color@vbox\relax +%\let\color@endbox\relax +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} @@ -539,7 +567,7 @@ % \changes{v1.0b}{1994/03/14} % {Use \cs{color@setgroup}} % \changes{v1.0d}{1994/04/15} -% {Added missing procent character.} +% {Added missing percent character.} % \changes{v1.0v}{1995/07/20} % {Use \cs{sbox}} % \begin{macrocode} @@ -888,7 +916,7 @@ % % The rational for allowing two normally global flags to be set % locally here was stated originally by -% Donald Arsenau and extended by Chris Rowley. +% Donald Arseneau and extended by Chris Rowley. % It is because these flags are only set globally to % true by section commands, and these should never appear within % boxes or, indeed, in any group; and they are only ever @@ -1016,7 +1044,7 @@ % % \begin{macro}{\@iiiminipage} % \changes{v1.0e}{1994/04/21} -% {Extra \cs{bgroup} for colour} +% {Extra \cs{bgroup} for color} % \changes{v1.0f}{1994/05/11} % {Use new \cs{color@setgroup} concept.} % Internal form of |minipage|. @@ -1054,11 +1082,11 @@ % {(RmS) replaced \cs{vskip}-\cs{lastskip} by \cs{unskip} % (proposed by FMi)} % \changes{v1.0e}{1994/04/21} -% {Extra \cs{egroup} for colour} +% {Extra \cs{egroup} for color} % \changes{v1.0f}{1994/05/11} % {Use new \cs{color@setgroup} concept.} % \changes{v1.0n}{1994/11/05} -% {Colour resetting for footnotes moved to here: as for main +% {Color resetting for footnotes moved to here: as for main % page.} % \begin{macrocode} \def\endminipage{% @@ -1093,9 +1121,9 @@ % Final |\strut| added 27 Mar 89, on suggestion by Don Hosek % \changes{LaTeX2.09}{1991/09/29}{(RmS) added \cs{reset@font}} % \changes{LaTeX2.09}{1992/11/26}{(RmS) added protection for \cs{edef}} -% \changes{v0.1a}{1994/03/07}{Extra group for colour} +% \changes{v0.1a}{1994/03/07}{Extra group for color} % \changes{v1.0e}{1994/04/21} -% {Extra \cs{endgraf} for colour} +% {Extra \cs{endgraf} for color} % \changes{v1.0f}{1994/05/11} % {Use new \cs{color@setgroup} concept.} % \changes{v1.0f}{1994/05/11} @@ -1103,11 +1131,17 @@ % \changes{v1.0m}{1994/11/04} % {Added \cs{protected@edef}. ASAJ.} % \changes{v1.0n}{1994/11/05} -% {Colour resetting for footnotes moved to endminipage: as for main +% {Color resetting for footnotes moved to endminipage: as for main % page.} % \changes{v1.0o}{1994/11/05} -% {Colour groups restored here.} +% {Color groups restored here.} +% \changes{v1.4b}{2021/02/10} +% {Explicitly run \cs{par} in support for paragraph tagging} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\@mpfootnotetext}{footnotetext tagging}% \long\def\@mpfootnotetext#1{% \global\setbox\@mpfootins\vbox{% \unvbox\@mpfootins @@ -1119,7 +1153,31 @@ \color@begingroup \@makefntext{% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% + \par \color@endgroup}} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\@mpfootnotetext}{footnotetext tagging}% +% +%\long\def\@mpfootnotetext#1{% +% \global\setbox\@mpfootins\vbox{% +% \unvbox\@mpfootins +% \reset@font\footnotesize +% \hsize\columnwidth +% \@parboxrestore +% \protected@edef\@currentlabel +% {\csname p@mpfootnote\endcsname\@thefnmark}% +% \color@begingroup +% \@makefntext{% +% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% +% \color@endgroup}} +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/base/ltclass.dtx b/Master/texmf-dist/source/latex/base/ltclass.dtx index c62136c3097..a0ab0fa3547 100644 --- a/Master/texmf-dist/source/latex/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex/base/ltclass.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2020/12/17 v1.3v LaTeX Kernel (Class & Package Interface)] + [2021/05/18 v1.4b LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -427,7 +427,7 @@ % \changes{v0.2h}{1993/11/28} % {Primitive filenames now terminated by space not \cs{relax}.} % \changes{v0.2h}{1993/11/28} -% {Directory syntax checing moved to dircheck.dtx} +% {Directory syntax checking moved to dircheck.dtx} % \changes{v0.2h}{1993/11/28} % {Assorted commands now in the kernel removed.} % \changes{v0.2i}{1993/12/03} @@ -486,7 +486,7 @@ % \begin{macro}{\@declaredoptions} % This list is automatically built by |\DeclareOption|. % It is the list of options (separated by commas) declared in -% the class or package file and it defines the order in which the +% the class or package file and it defines the order in which % the corresponding |\ds@|\meta{option} commands are executed. % All local \meta{option}s which are not declared will be processed % in the order defined by the optional argument of |\documentclass| @@ -505,6 +505,14 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@raw@classoptionslist} +% List of options of the main class (unprocessed). +% \changes{v1.4b}{2021/05/18}{Initialise to \cs{relax} to match \cs{@classoptionslist}} +% \begin{macrocode} +\let\@raw@classoptionslist\relax +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\@unusedoptionlist} % \changes{v1.0u}{1996/07/26}{made only preamble} % List of options of the main class that haven't been declared or @@ -640,14 +648,38 @@ % \@expl@push@filename@aux@@} %\EndIncludeInRelease % +% \end{macrocode} +% +% When we roll back from a release that has \pkg{expl3} preloaded, the +% definitions of \cs{@pushfilename} and \cs{@popfilename} can't be +% completely rolled back otherwise \pkg{expl3}-based packages won't +% have the automatic \cs{ExplSyntaxOff} at the end. Here and below for +% \cs{@popfilename}, we don't roll back all the way through if coming +% from \LaTeX${}>2020-02-02$. +% \changes{v1.4a}{2021/03/27} +% {Do not completely roll back if \pkg{expl3} is loaded.} +% \begin{macrocode} %\IncludeInRelease{0000/00/00}{\@pushfilename}% % {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%\ifnum\sourceLaTeXdate<20200202\relax +% \GenericInfo{}{Defining 00-00-00\string\@pushfilename.} %\def\@pushfilename{% % \xdef\@currnamestack{% % {\@currname}% % {\@currext}% % {\the\catcode`\@}% % \@currnamestack}} +%\else +% \GenericInfo{}{Defining 2020-02-02\string\@pushfilename.} +%\def\@pushfilename{% +% \@expl@push@filename@@ +% \xdef\@currnamestack{% +% {\@currname}% +% {\@currext}% +% {\the\catcode`\@}% +% \@currnamestack}% +% \@expl@push@filename@aux@@} +%\fi %\EndIncludeInRelease \@onlypreamble\@pushfilename % \end{macrocode} @@ -676,9 +708,21 @@ % \@expl@pop@filename@@} %\EndIncludeInRelease % +% \end{macrocode} +% +% \changes{v1.4a}{2021/03/27} +% {Do not completely roll back if \pkg{expl3} is loaded.} +% \begin{macrocode} %\IncludeInRelease{0000/00/00}{\@popfilename}% % {Add \@expl@push@filename@@ and \@expl@push@filename@aux@@}% +%\ifnum\sourceLaTeXdate<20200202\relax +% \GenericInfo{}{Defining 00-00-00\string\@popfilename.} %\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil} +%\else +% \GenericInfo{}{Defining 2020-02-02\string\@popfilename.} +%\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil +% \@expl@pop@filename@@} +%\fi %\EndIncludeInRelease \@onlypreamble\@popfilename % \end{macrocode} @@ -712,6 +756,7 @@ % Path to the current file if explicitly given. The auxiliary is % needed here to insert a \cs{@empty} to prevent the loss of braces. % \changes{v1.3u}{2020/11/20}{Macro added} +% \changes{v1.3w}{2021/01/21}{Add empty entry for latexrelease} % \begin{macrocode} % %<*2ekernel|latexrelease> @@ -719,6 +764,7 @@ %\IncludeInRelease{2020/10/01}{\@kernel@currpathstack}% % {Add \@kernel@currpathstack}% \gdef\@kernel@currpathstack{} +%\g@addto@macro\@kernel@currpathstack{{}} \def\@p@pfilepath#1{% \gdef\@currpath{#1}\@p@pfilepath@aux\@empty} \def\@p@pfilepath@aux#1\@nil{% @@ -1026,12 +1072,12 @@ % be cautious when handling the identification string in case it % contains UTF-8 characters. % \changes{v1.3e}{2019/11/29}{Protect package info text (gh/52)} -% \changes{v1.3r}{2020/10/01}{Allow for package subsitution} +% \changes{v1.3r}{2020/10/01}{Allow for package substitution} % \begin{macrocode} % %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% -% {\@pr@videpackage}{Allow for package subsitution}% +% {\@pr@videpackage}{Allow for package substitution}% \def\@pr@videpackage[#1]{% \expandafter\protected@xdef % <-- protected... \csname ver@\@currname.\@currext\endcsname{#1}% Loaded package @@ -1164,13 +1210,14 @@ % % \begin{macro}{\PassOptionsToPackage} % \begin{macro}{\PassOptionsToClass} -% If the package has been loaded, we check that it was first loaded with -% the options. Otherwise we add the option list to that of the package. +% If the package has been loaded, we check that it was first loaded with +% the options. Otherwise we add the option list to that of the package. % \changes{v1.3t}{2020/10/18}{Drop path from \cs{input@path} (gh/414).} +% \changes{v1.3x}{2021/02/18}{save raw option lists (gh/85)} % \begin{macrocode} % -%\IncludeInRelease{2020/10/01}{\@pass@ptions} -% {Add file replacement in \@pass@ptions}% +%\IncludeInRelease{2021/06/01}% +% {\@pass@ptions}{Raw option lists}% %<*2ekernel|latexrelease> \def\@pass@ptions#1#2#3{% \@expl@@@filehook@set@curr@file@@nNN @@ -1187,12 +1234,41 @@ % \begin{macrocode} \expandafter\let \csname opt@#3.#1\expandafter\endcsname - \csname opt@\reserved@a\endcsname} + \csname opt@\reserved@a\endcsname +% \end{macrocode} +% Extend raw option list +% \begin{macrocode} + \@ifundefined{@raw@opt@#3.#1}% + {\expandafter\gdef\csname @raw@opt@#3.#1\endcsname{#2}}% + {\expandafter\g@addto@macro\csname @raw@opt@#3.#1\endcsname{,#2}}% +} % %\EndIncludeInRelease +% \end{macrocode} % +% \begin{macrocode} +%\IncludeInRelease{2020/10/01}{\@pass@ptions} +% {Add file replacement in \@pass@ptions}% +% +%\def\@pass@ptions#1#2#3{% +% \@expl@@@filehook@set@curr@file@@nNN +% {\@expl@@@filehook@resolve@file@subst@@w #3.#1\@nil}% +% \reserved@a\reserved@b +% \@expl@@@filehook@clear@replacement@flag@@ +% \expandafter\xdef\csname opt@\reserved@a\endcsname{% +% \@ifundefined{opt@\reserved@a}\@empty +% {\csname opt@\reserved@a\endcsname,}% +% \zap@space#2 \@empty}% +% \expandafter\let +% \csname opt@#3.#1\expandafter\endcsname +% \csname opt@\reserved@a\endcsname} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} %\IncludeInRelease{0000/00/00}{\@pass@ptions} % {\@pass@ptions}% +% %\def\@pass@ptions#1#2#3{% % \expandafter\xdef\csname opt@#3.#1\endcsname{% % \@ifundefined{opt@#3.#1}\@empty @@ -1200,6 +1276,9 @@ % \zap@space#2 \@empty}} %\EndIncludeInRelease %<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \@onlypreamble\@pass@ptions % \end{macrocode} % @@ -1241,18 +1320,49 @@ % \end{macro} % % \begin{macro}{\OptionNotUsed} +% \changes{v1.3x}{2021/02/18}{filter out =value from unused option list (gh/85)} +% \begin{macro}{\@remove@eq@value} +% \changes{v1.3x}{2021/02/18}{macro added (gh/85)} % If we are in a class file, add |\CurrentOption| to the list of % unused options. Otherwise, in a package file do nothing. % \begin{macrocode} +% +%\IncludeInRelease{2021/06/01}% +% {\OptionNotUsed}{filter unused option list}% +%<*2ekernel|latexrelease> +\def\@remove@eq@value#1=#2\@nil{#1} +% \end{macrocode} +% +% \begin{macrocode} \def\OptionNotUsed{% \ifx\@currext\@clsextension \xdef\@unusedoptionlist{% \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi - \CurrentOption}% + \expandafter\@remove@eq@value\CurrentOption=\@nil}% \fi} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\OptionNotUsed}{filter unused option list}% +%\let\@remove@eq@value\@undefined +% \end{macrocode} +% +% \begin{macrocode} +%\def\OptionNotUsed{% +% \ifx\@currext\@clsextension +% \xdef\@unusedoptionlist{% +% \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi +% \CurrentOption}% +% \fi} +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \@onlypreamble\OptionNotUsed % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\default@ds} % The default option code. @@ -1279,7 +1389,7 @@ % \changes{v0.2a}{1993/11/14} % {Stop adding the global option list inside class files.} % \changes{v0.2a}{1993/11/14} -% {Optimise `empty option' code.} +% {Optimize `empty option' code.} % \changes{v0.2b}{1993/11/15} % {Star form added.} % \changes{v0.2c}{1993/11/17} @@ -1312,19 +1422,50 @@ % % \changes{v0.2y}{1994/02/07} % {Add extra ,s so `two' is not matched with `twocolumn'} +% \changes{v1.3z}{2021/03/05}{modify so braces to not give errors (gh/513)} % \begin{macrocode} +% +%\IncludeInRelease{2021/06/01}% +% {\@xprocess@ptions}{safer @xprocess@ptions}% +%<*2ekernel|latexrelease> \def\@xprocess@ptions{% \ifx\@currext\@clsextension\else + \ifx\@classoptionslist\relax\else \@for\CurrentOption:=\@classoptionslist\do{% \ifx\CurrentOption\@empty\else - \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}% - \ifin@ + \@ifundefined{ds@\CurrentOption}{}{% \@use@ption \expandafter\let\csname ds@\CurrentOption\endcsname\@empty - \fi + }% \fi}% + \fi \fi \@process@pti@ns} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@xprocess@ptions}{safer @xprocess@ptions}% +%\let\@remove@eq@value\@undefined +% \end{macrocode} +% +% \begin{macrocode} +%\def\@xprocess@ptions{% +% \ifx\@currext\@clsextension\else +% \@for\CurrentOption:=\@classoptionslist\do{% +% \ifx\CurrentOption\@empty\else +% \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}% +% \ifin@ +% \@use@ption +% \expandafter\let\csname ds@\CurrentOption\endcsname\@empty +% \fi +% \fi}% +% \fi +% \@process@pti@ns} +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \@onlypreamble\@xprocess@ptions % \end{macrocode} % @@ -1403,11 +1544,30 @@ % {Name changed from \cs{@executeoption}} % \changes{v1.0e}{1994/05/17} % {Execute option after removing from list, not before} +% \changes{v1.3x}{2021/02/18}{filter out =value from unused option list (gh/85)} % \begin{macrocode} +% +%\IncludeInRelease{2021/06/01}% +% {\@use@ption}{filter unused option list}% +%<*2ekernel|latexrelease> \def\@use@ption{% - \@expandtwoargs\@removeelement\CurrentOption + \@expandtwoargs\@removeelement + {\expandafter\@remove@eq@value\CurrentOption=\@nil}% \@unusedoptionlist\@unusedoptionlist \csname ds@\CurrentOption\endcsname} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@use@ption}{filter unused option list}% +%\def\@use@ption{% +% \@expandtwoargs\@removeelement\CurrentOption +% \@unusedoptionlist\@unusedoptionlist +% \csname ds@\CurrentOption\endcsname} +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% \begin{macrocode} \@onlypreamble\@use@ption % \end{macrocode} % \end{macro} @@ -1460,7 +1620,7 @@ % the internal command, |\@fileswithoptions|. % \begin{macro}{\documentclass} % \changes{v1.0q}{1995/06/19} -% {Dont redefine \cs{usepackage} in compat mode for /1634} +% {Don't redefine \cs{usepackage} in compat mode for /1634} % The main new-style class declaration. % \begin{macrocode} \def\documentclass{% @@ -1721,15 +1881,23 @@ % {Prevent loss of brackets PR/3965} % \changes{v2.1b}{2016/11/09} % {Improve \cs{ifx} tests PR/4497} +% \changes{v1.3x}{2021/02/18}{save raw class option list (gh/85)} % \begin{macrocode} % -%\IncludeInRelease{2017/01/01}% +%\IncludeInRelease{2020/10/01}% % {\@fileswith@pti@ns}{ifx tests in \@fileswith@pti@ns}% %<*2ekernel|latexrelease> \def\@fileswith@pti@ns#1[#2]#3[#4]{% \ifx#1\@clsextension \ifx\@classoptionslist\relax \xdef\@classoptionslist{\zap@space#2 \@empty}% +% \end{macrocode} +% Save raw class list. +% \begin{macrocode} + \gdef\@raw@classoptionslist{#2}% +% \end{macrocode} +% +% \begin{macrocode} \def\reserved@a{% \@onefilewithoptions#3[{#2}][{#4}]#1% \@documentclasshook}% @@ -1750,8 +1918,8 @@ % \begin{macrocode} \ifx\@nnil##1\relax\else % \end{macrocode} -% If |\ifx\@nnil##1\n@nil| is true then |#1| is (presumably) empty -% (Older code used |\relax| which is slighly easier to get into |#1| +% If |\ifx\@nnil##1\@nnil| is true then |#1| is (presumably) empty +% (Older code used |\relax| which is slightly easier to get into |#1| % by mistake, which would spoil this test.) % \begin{macrocode} \ifx\@nnil##1\@nnil\else @@ -1768,6 +1936,33 @@ \fi \reserved@a} % +%\EndIncludeInRelease +%\IncludeInRelease{2017/01/01}% +% {\@fileswith@pti@ns}{ifx tests in \@fileswith@pti@ns}% +%\def\@fileswith@pti@ns#1[#2]#3[#4]{% +% \ifx#1\@clsextension +% \ifx\@classoptionslist\relax +% \xdef\@classoptionslist{\zap@space#2 \@empty}% +% \def\reserved@a{% +% \@onefilewithoptions#3[{#2}][{#4}]#1% +% \@documentclasshook}% +% \else +% \def\reserved@a{% +% \@onefilewithoptions#3[{#2}][{#4}]#1}% +% \fi +% \else +% \def\reserved@b##1,{% +% \ifx\@nnil##1\relax\else +% \ifx\@nnil##1\@nnil\else +% \noexpand\@onefilewithoptions##1[{#2}][{#4}]% +% \noexpand\@pkgextension +% \fi +% \expandafter\reserved@b +% \fi}% +% \edef\reserved@a{\zap@space#3 \@empty}% +% \edef\reserved@a{\expandafter\reserved@b\reserved@a,\@nnil,}% +% \fi +% \reserved@a} % \end{macrocode} % % \begin{macrocode} @@ -1834,7 +2029,7 @@ % \usepackage{some/local/path/array} % \usepackage{array} % \end{verbatim} -% won't load \file{array.sty} twice. It is remotely possible that +% won't load |array.sty| twice. It is remotely possible that % those are two different files, but as a matter of principles, we % will consider that the base file name uniquely identifies a % package, regardless of where it lives. This assumption already @@ -2087,7 +2282,7 @@ % loaded.} % % This has changed in 2020. We now use a separate macro per package -% to avoid interferences in case of nested packages. The whole +% to avoid interference in case of nested packages. The whole % code for handling this issue (GitHub 22) was provided by Hironobu % Yamashita, thanks for that. % \changes{v1.3k}{2020/04/07}{Use different method to ignore @@ -2424,7 +2619,7 @@ % \changes{v0.2r}{1993/12/19}{Different message when ignoring a file} % \changes{v0.3g}{1994/04/11} % {Add star form, -% dont write \cs{endinput} at the end of the file.} +% don't write \cs{endinput} at the end of the file.} % \changes{v1.0c}{1994/05/11} % {Add checks for form feed and tab} % \changes{v1.0m}{1995/04/21} @@ -2549,15 +2744,15 @@ % this only works for input files ending in \texttt{.tex}. If a % different extension is used there is no way to see that we are % overwriting ourselves! +% \changes{v1.3y}{2021/03/03} +% {Fix overwrite check for files with UTF-8 (gh/415)} % \begin{macrocode} - \edef\reserved@a{#1}% - \edef\reserved@a{\detokenize\expandafter{\reserved@a}}% \edef\reserved@b{\detokenize\expandafter{\jobname}}% - \ifx\reserved@a\reserved@b% + \ifx\@curr@file\reserved@b% \@fileswtrue% \else% \edef\reserved@b{\reserved@b\detokenize{.tex}}% - \ifx\reserved@a\reserved@b + \ifx\@curr@file\reserved@b \@fileswtrue% \fi% \fi% @@ -2640,7 +2835,8 @@ % Text before the |\end|, write it with a warning. % \begin{macrocode} \@latex@warning{Writing text `##1' before % - \string\end{\@currenvir}\MessageBreak as last line of \@curr@file}% + \string\end{\@currenvir}\MessageBreak + as last line of \@curr@file}% \immediate\write\reserved@c{##1}% \fi% \ifx\relax##2\relax% @@ -2675,7 +2871,8 @@ % %\EndIncludeInRelease %\IncludeInRelease{2019/10/01}% -% {\filec@ntents}{Spaces in file names + optional arg}% +% {\filec@ntents}{Spaces in file names + optional arg}% +% %\def\filecontents{\@tempswatrue\@fileswtrue % \@ifnextchar[\filec@ntents@opt\filec@ntents %} @@ -2805,7 +3002,7 @@ %\endgroup% %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\filec@ntents}{Spaces in file names + optional arg}% +% {\filec@ntents}{Spaces in file names + optional arg}% % %\let\filec@ntents@opt \@undefined %\let\filec@ntents@force \@undefined @@ -2976,7 +3173,7 @@ % YYYYMMDD (if there was one, otherwise the value of % |\requestedLaTeXdate|) and |\pkgcls@targetlabel| will be % empty. If there was a request for a named version then -% |\pkgcls@targetlabel| holds the verion name and +% |\pkgcls@targetlabel| holds the version name and % |\pkgcls@targetdate| is set to \texttt{1}. % % |\pkgcls@targetdate=0| is used to indicate that there was no @@ -3063,7 +3260,7 @@ \pkgcls@parse@date@arg{#3}% % \end{macrocode} % When determining the correct release to load we keep track of -% candiates in |\pkgcls@candidate| and initially we don't have any: +% candidates in |\pkgcls@candidate| and initially we don't have any: % \begin{macrocode} \let\pkgcls@candidate\@empty % \end{macrocode} @@ -3103,7 +3300,7 @@ % % But if it starts with an equal sign followed by a date string or % followed by a version name then this means that we should roll -% back to the state of the package at tht date or to the version +% back to the state of the package at that date or to the version % with the requested name. % % If there was no optional argument or the optional argument @@ -3381,7 +3578,7 @@ % % \begin{macro}{\pkgcls@show@selection} % This command records what selection was made. As that is needed -% in two places (and it is rather lengthly) it was placed in a +% in two places (and it is rather lengthy) it was placed in a % separate command. The first argument is the name of the external % file that is being loaded and is only needed for debugging. The % second argument is the date that corresponds to this file and it @@ -3484,7 +3681,7 @@ \pkgcls@releasedate \fi % \end{macrocode} -% Otherwise the curent file is the right release, so we record that +% Otherwise the current file is the right release, so we record that % in the transcript and then carry on. % \begin{macrocode} \else diff --git a/Master/texmf-dist/source/latex/base/ltcmd.dtx b/Master/texmf-dist/source/latex/base/ltcmd.dtx new file mode 100644 index 00000000000..806161d5386 --- /dev/null +++ b/Master/texmf-dist/source/latex/base/ltcmd.dtx @@ -0,0 +1,4034 @@ +% \iffalse meta-comment +% +% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle +% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project +% Copyright (C) 2009-2021 +% The LaTeX Project and any individual authors listed elsewhere +% in this file. +% +% This file is part of the LaTeX base system. +% ------------------------------------------- +% +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". +% +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. +% +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi +% +% \iffalse +% +%%% From File: ltcmd.dtx +% +% \begin{macrocode} +\def\ltcmdversion{v1.0e} +\def\ltcmddate{2021-05-24} +% \end{macrocode} +% +%<*driver> +% \fi +\ProvidesFile{ltcmd.dtx} + [\ltcmddate\space \ltcmdversion\space + LaTeX Kernel (Document commands)] +% \iffalse +\documentclass{l3doc} +\GetFileInfo{ltcmd.dtx} +\title{\filename} +\date{\filedate} +\author{Frank Mittelbach, Chris Rowley, David Carlisle, \LaTeX{} Project Team} +\begin{document} + \maketitle + \DocInput{ltcmd.dtx} +\end{document} +% +% \fi +% +% \section{Creating document commands} +% +% \changes{v1.0a}{2020/11/20}{Initial version derived from \texttt{xparse.dtx}} +% +% Document commands should be created using the tools provided by this module: +% \cs{NewDocumentCommand}, etc.\@, in almost all cases. This allows clean +% separation of document-level syntax from code-level interfaces. Users have +% a need to create new document commands, and as such a significant amount of +% documentation for \pkg{ltcmd} is provided as part of \texttt{usrguide3}. Here, +% additional material aimed at programmers is provided +% +% \StopEventually{} +% +% \begin{macrocode} +%<@@=cmd> +% \end{macrocode} +% +% \begin{macrocode} +%<*2ekernel> +\message{document commands,} +% +% \end{macrocode} +% +% \changes{v1.0b}{2021/03/18}{Use \cs{NewModuleRelease}.} +% \changes{v1.0e}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} +% +% +% \pkg{ltcmd} code contains an |^^@| character, which usually has +% catcode~15, so \cs{IncludeInRelease} will break when this code is +% being skipped, so we'll save the catcode of |^^@| to restore later: +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\edef\@latexrelease@catcode@null{\the\catcode`\^^@ } +%\catcode`\^^@=12 +\ExplSyntaxOn +%\NewModuleRelease{2020/10/01}{ltcmd} +% {Document~command~parser}% +% \end{macrocode} +% +% \subsection{Variables and constants} +% +% \begin{variable}{\l_@@_arg_spec_tl} +% Holds the argument specification after normalization of shorthands. +% \begin{macrocode} +\tl_new:N \l_@@_arg_spec_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_args_tl} +% Token list variable for grabbed arguments. +% \begin{macrocode} +\tl_new:N \l_@@_args_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_args_i_tl, \l_@@_args_ii_tl} +% Hold the modified arguments when dealing with default values or +% processors. +% \begin{macrocode} +\tl_new:N \l_@@_args_i_tl +\tl_new:N \l_@@_args_ii_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_current_arg_int} +% The number of the current argument being set up: this is used to +% make sure there are at most 9 arguments, then for creating the +% expandable auxiliary functions and knowing how many arguments the +% code function should take. +% \begin{macrocode} +\int_new:N \l_@@_current_arg_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_defaults_bool, \l_@@_defaults_tl} +% The boolean indicates whether there are any argument with default +% value other than |-NoValue-|; the token list holds the code to +% determine these default values in terms of other arguments. +% \begin{macrocode} +\bool_new:N \l_@@_defaults_bool +\tl_new:N \l_@@_defaults_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_environment_bool} +% Generating environments uses the same mechanism as generating functions. +% However, full processing of arguments is always needed for environments, +% and so the function-generating code needs to know this. +% This variable is also used at run time to give correct error messages. +% \begin{macrocode} +\bool_new:N \l_@@_environment_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_environment_str} +% Name of the environment, used at definition time and at run time. +% \begin{macrocode} +\str_new:N \l_@@_environment_str +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_expandable_bool} +% Used to indicate if an expandable command is begin generated, as this +% affects both the acceptable argument types and how they are implemented. +% \begin{macrocode} +\bool_new:N \l_@@_expandable_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_expandable_aux_name_tl} +% Used to create pretty-printing names for the auxiliaries: although the +% immediate definition does not vary, the full expansion does and so it +% does not count as a constant. +% \begin{macrocode} +\tl_new:N \l_@@_expandable_aux_name_tl +\tl_set:Nn \l_@@_expandable_aux_name_tl + { + \l_@@_function_tl \c_space_tl + ( arg~ \int_use:N \l_@@_current_arg_int ) + } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_grabber_int} +% Used (in exceptional cases) to get unique names for grabbers used by +% expandable commands. +% \begin{macrocode} +\int_new:N \g_@@_grabber_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_fn_tl} +% For passing the pre-formed name of the auxiliary to be used as the +% parsing function. +% \begin{macrocode} +\tl_new:N \l_@@_fn_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_fn_code_tl} +% For passing the pre-formed name of the auxiliary that contains the +% actual code. +% \begin{macrocode} +\tl_new:N \l_@@_fn_code_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_function_tl} +% Holds the control sequence name of the function currently being +% defined: used to avoid passing this as an argument and to avoid repeated +% use of \cs{cs_to_str:N}. +% \begin{macrocode} +\tl_new:N \l_@@_function_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_grab_expandably_bool} +% When defining a non-expandable command, indicates whether the +% arguments can all safely be grabbed by expandable grabbers. This is +% to support abuses of \pkg{xparse} that use protected functions +% inside csname constructions. +% \begin{macrocode} +\bool_new:N \l_@@_grab_expandably_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_obey_spaces_bool} +% For trailing optionals. +% \begin{macrocode} +\bool_new:N \l_@@_obey_spaces_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_last_delimiters_tl} +% Holds the delimiters (first tokens) of all optional arguments since +% the previous mandatory argument, to warn about cases where it would +% be impossible to omit optional arguments completely because the +% following mandatory argument has the same delimiter as one of the +% optional arguments. +% \begin{macrocode} +\tl_new:N \l_@@_last_delimiters_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_long_bool} +% Used to indicate that an argument is long, on a per-argument basis. +% \begin{macrocode} +\bool_new:N \l_@@_long_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_m_args_int} +% The number of \texttt{m} arguments: if this is the same as the total +% number of arguments, then a short-cut can be taken in the creation of +% the grabber code. +% \begin{macrocode} +\int_new:N \l_@@_m_args_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_prefixed_bool} +% When preparing the signature of non-expandable commands, indicates +% that the current argument is affected by a processor or by |+| +% (namely is long). +% \begin{macrocode} +\bool_new:N \l_@@_prefixed_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_process_all_tl, \l_@@_process_one_tl, \l_@@_process_some_bool} +% When preparing the signature, the processors that will be applied to +% a given argument are collected in \cs{l_@@_process_one_tl}, while +% \cs{l_@@_process_all_tl} contains processors for all arguments. The +% boolean indicates whether there are any processors (to bypass the +% whole endeavour otherwise). +% \begin{macrocode} +\tl_new:N \l_@@_process_all_tl +\tl_new:N \l_@@_process_one_tl +\bool_new:N \l_@@_process_some_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_saved_args_tl} +% Stores \cs{l_@@_args_tl} to deal with space-trimming of +% \texttt{b}-type arguments. +% \begin{macrocode} +\tl_new:N \l_@@_saved_args_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_signature_tl} +% Used when constructing the signature (code for argument grabbing) to +% hold what will become the implementation of the main function. +% When arguments are grabbed (at point of use of the command/environment), +% it also stores the code for grabbing the remaining arguments. +% \begin{macrocode} +\tl_new:N \l_@@_signature_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% {\l_@@_some_obey_spaces_bool, \l_@@_some_long_bool, \l_@@_some_short_bool} +% These flags are set while normalizing the argument specification. +% The \texttt{obey_spaces} one is used to detect when |!| is used on +% an argument that is not a trailing optional argument. +% The other two are used to check whether all short arguments appear +% before long arguments: this is needed to grab arguments expandably. +% As soon as the first long argument is seen (other than +% \texttt{t}-type, whose long status is ignored) the +% \texttt{some_long} flag is set. The \texttt{some_short} flag is +% used for expandable commands, to know whether to define a short +% auxiliary too. +% \begin{macrocode} +\bool_new:N \l_@@_some_obey_spaces_bool +\bool_new:N \l_@@_some_long_bool +\bool_new:N \l_@@_some_short_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_tmp_prop, \l_@@_tmpa_tl, \l_@@_tmpb_tl} +% \begin{macro}{\@@_tmp:w} +% Scratch space. +% \begin{macrocode} +\prop_new:N \l_@@_tmp_prop +\tl_new:N \l_@@_tmpa_tl +\tl_new:N \l_@@_tmpb_tl +\cs_new_eq:NN \@@_tmp:w ? +% \end{macrocode} +% \end{macro} +% \end{variable} +% +% With \pkg{xparse}, information about commands being (re)defined was +% switched off by default, unless the |log-declarations| package +% option was used, so here we'll switch that off as well. +% \begin{macrocode} +\msg_redirect_module:nnn { cmd } { info } { none } +% \end{macrocode} +% +% Also add \pkg{cmd} to the \pkg{LaTeX} messages. +% \begin{macrocode} +\prop_gput:Nnn \g_msg_module_type_prop { cmd } { LaTeX } +% \end{macrocode} +% +% \subsection{Declaring commands and environments} +% +% \begin{macro}{\@@_declare_cmd:Nnn, \@@_declare_expandable_cmd:Nnn} +% \begin{macro}{\@@_declare_cmd_aux:Nnn} +% \begin{macro} +% {\@@_declare_cmd_internal:Nnnn, \@@_declare_cmd_internal:cnxn} +% The main functions for creating commands set the appropriate flag then +% use the same internal code to do the definition. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd:Nnn + { + \bool_set_false:N \l_@@_expandable_bool + \@@_declare_cmd_aux:Nnn + } +\cs_new_protected:Npn \@@_declare_expandable_cmd:Nnn + { + \bool_set_true:N \l_@@_expandable_bool + \@@_declare_cmd_aux:Nnn + } +% \end{macrocode} +% The first stage is to log information, both for the user in the log and +% for programmatic use in a property list of all declared commands. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_aux:Nnn #1#2#3 + { + \cs_if_exist:NTF #1 + { + \msg_info:nnxx { cmd } { redefine-command } + { \token_to_str:N #1 } { \tl_to_str:n {#2} } + } + { + \bool_lazy_or:nnT + { \cs_if_exist_p:c { \cs_to_str:N #1 ~ code } } + { \cs_if_exist_p:c { \cs_to_str:N #1 ~ defaults } } + { + \msg_warning:nnx { cmd } { unsupported-let } + { \token_to_str:N #1 } + } + \msg_info:nnxx { cmd } { define-command } + { \token_to_str:N #1 } { \tl_to_str:n {#2} } + } + \bool_set_false:N \l_@@_environment_bool + \@@_declare_cmd_internal:Nnnn #1 {#2} {#3} { } + } +% \end{macrocode} +% At definition time, the variable \cs{l_@@_fn_tl} is only used for error messages. +% The real business of defining a document command starts with setting up +% the appropriate name, then normalizing the argument specification to get rid of +% shorthands. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_internal:Nnnn #1#2#3#4 + { + \tl_set:Nx \l_@@_function_tl { \cs_to_str:N #1 } + \tl_set:Nx \l_@@_fn_tl + { \exp_not:c { \l_@@_function_tl \c_space_tl } } + \@@_normalize_arg_spec:n {#2} + \exp_args:No \@@_prepare_signature:n \l_@@_arg_spec_tl + \@@_declare_cmd_code:Nnn #1 {#2} {#3} + #4 + \@@_break_point:n {#2} + } +\cs_generate_variant:Nn \@@_declare_cmd_internal:Nnnn { cnx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_break_point:n} +% A marker used to escape from creating a definition if necessary. +% \begin{macrocode} +\cs_new_eq:NN \@@_break_point:n \use_none:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_declare_cmd_code:Nnn} +% \begin{macro} +% {\@@_declare_cmd_code_aux:Nnn, \@@_declare_cmd_code_expandable:Nnn} +% The appropriate auxiliary is called. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_code:Nnn + { + \bool_if:NTF \l_@@_grab_expandably_bool + { \@@_declare_cmd_code_expandable:Nnn } + { \@@_declare_cmd_code_aux:Nnn } + } +% \end{macrocode} +% Standard functions call \cs{@@_start:nNNnnn}, which receives the +% argument specification, an auxiliary used for +% grabbing arguments, an auxiliary containing the code, and then the +% signature, default arguments, and processors. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_code_aux:Nnn #1#2#3 + { + \cs_generate_from_arg_count:cNnn + { \l_@@_function_tl \c_space_tl code } + \cs_set_protected:Npn \l_@@_current_arg_int {#3} + \cs_set_protected_nopar:Npx #1 + { + \bool_if:NTF \l_@@_environment_bool + { + \@@_start_env:nnnnn { \exp_not:n {#2} } + { \l_@@_environment_str } + } + { + \@@_start:nNNnnn { \exp_not:n {#2} } + \exp_not:c { \l_@@_function_tl \c_space_tl } + \exp_not:c { \l_@@_function_tl \c_space_tl code } + } + { \exp_not:o \l_@@_signature_tl } + { + \bool_if:NT \l_@@_defaults_bool + { \exp_not:o \l_@@_defaults_tl } + } + { + \bool_if:NT \l_@@_process_some_bool + { \exp_not:o \l_@@_process_all_tl } + } + } + } +% \end{macrocode} +% Expandable functions and functions whose arguments can be grabbed +% expandably call \cs{@@_start_expandable:nNNNNn}, which receives the +% argument specification, four auxiliaries (two for grabbing arguments, one for +% the code, and one for default arguments), and finally the signature. +% Non-expandable functions that take this branch should nevertheless +% be protected, as well as their \texttt{code} function. They will +% only be expanded in contexts such as constructing a csname. +% The two grabbers (named after the function with one or two spaces) +% are needed when there are both short and long arguments; otherwise +% the same grabber is included twice in the definition. If all +% arguments are long or all are short the (only) grabber is defined +% correspondingly to be long/short. Otherwise two grabbers are +% defined, one long, one short. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_code_expandable:Nnn #1#2#3 + { + \exp_args:Ncc \cs_generate_from_arg_count:NNnn + { \l_@@_function_tl \c_space_tl code } + { cs_set \bool_if:NF \l_@@_expandable_bool { _protected } :Npn } + \l_@@_current_arg_int {#3} + \bool_if:NT \l_@@_defaults_bool + { + \use:x + { + \cs_generate_from_arg_count:cNnn + { \l_@@_function_tl \c_space_tl defaults } + \cs_set:Npn \l_@@_current_arg_int + { \exp_not:o \l_@@_defaults_tl } + } + } + \bool_if:NTF \l_@@_expandable_bool + { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1 + { + \exp_not:N \@@_start_expandable:nNNNNn + { \exp_not:n {#2} } + \exp_not:c { \l_@@_function_tl \c_space_tl } + \exp_not:c + { + \l_@@_function_tl \c_space_tl + \bool_if:NT \l_@@_some_short_bool + { \bool_if:NT \l_@@_some_long_bool { \c_space_tl } } + } + \exp_not:c { \l_@@_function_tl \c_space_tl code } + \bool_if:NTF \l_@@_defaults_bool + { \exp_not:c { \l_@@_function_tl \c_space_tl defaults } } + { ? } + { \exp_not:o \l_@@_signature_tl } + } + \bool_if:NTF \l_@@_some_long_bool + { + \bool_if:NT \l_@@_some_short_bool + { + \cs_set_nopar:cpx { \l_@@_function_tl \c_space_tl \c_space_tl } + ##1##2 { ##1 {##2} } + } + \cs_set:cpx + } + { \cs_set_nopar:cpx } + { \l_@@_function_tl \c_space_tl } ##1##2 { ##1 {##2} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_declare_env:nnnn} +% \begin{macro}{\@@_declare_env_internal:nnnn} +% The lead-off to creating an environment is much the same as that for +% creating a command: issue the appropriate message, store the argument +% specification then hand off to an internal function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_env:nnnn #1#2 + { + \str_set:Nx \l_@@_environment_str {#1} + \str_set:Nx \l_@@_environment_str + { \tl_trim_spaces:o { \l_@@_environment_str } } + \cs_if_exist:cTF { \l_@@_environment_str } + { + \msg_info:nnxx { cmd } { redefine-environment } + { \l_@@_environment_str } { \tl_to_str:n {#2} } + } + { + \msg_info:nnxx { cmd } { define-environment } + { \l_@@_environment_str } { \tl_to_str:n {#2} } + } + \bool_set_false:N \l_@@_expandable_bool + \bool_set_true:N \l_@@_environment_bool + \exp_args:NV \@@_declare_env_internal:nnnn + \l_@@_environment_str {#2} + } +% \end{macrocode} +% Creating a document environment requires a few more steps than creating +% a single command. In order to pass the arguments of the command to the +% end of the function, it is necessary to store the grabbed arguments. +% To do that, the function used at the end of the environment has to be +% redefined to contain the appropriate information. To minimize the amount +% of expansion at point of use, the code here is expanded now as well as +% when used. +% The last argument of \cs{@@_declare_cmd_internal:Nnnn} is only run +% if the definition succeeded. In package mode this ensures that the +% original definition of the environment is not changed if the +% definition fails for any reason. This also avoids an error when +% defining the \verb*|end aux | function when the user asks for more +% than $9$ arguments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_env_internal:nnnn #1#2#3#4 + { + \@@_declare_cmd_internal:cnxn { environment~ #1 } {#2} + { + \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux } + { + \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ } + \exp_not:n { \exp_not:o \l_@@_args_tl } + } + \exp_not:n {#3} + } + { + \cs_set_nopar:cpx { environment~ #1 ~end } + { \exp_not:c { environment~ #1 ~end~aux } } + \cs_generate_from_arg_count:cNnn + { environment~ #1 ~end~aux~ } \cs_set:Npn + \l_@@_current_arg_int {#4} + \cs_set_eq:cc {#1} { environment~ #1 } + \cs_set_eq:cc { end #1 } { environment~ #1 ~end } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Structure of \pkg{xparse} commands} +% +% \begin{macro}{\@@_start_env:nnnnn, \@@_start:nNNnnn} +% For error messages that occur during run-time when getting arguments +% of environments it is necessary to keep track of the environment +% name. We begin non-expandable commands with a token equal to +% \cs{scan_stop:}, whose name gives a reasonable error message if the +% command is used inside a csname and protects against +% \texttt{f}-expansion. This is useless for environments since +% \cs{begin} is already not expandable. Both the command and +% environment codes start with \cs{group_align_safe_begin:}, then +% \cs{@@_run_code:} (used by both) does \cs{group_align_safe_end:}, so +% that delimited arguments may be grabbed in alignments if they +% contain and alignment tab token (see latex3/latex3/issues/839). +% \begin{macrocode} +\cs_new_protected:Npn \@@_start_env:nnnnn #1#2 + { + \conditionally@traceoff + \group_align_safe_begin: + \str_set:Nn \l_@@_environment_str {#2} + \bool_set_true:N \l_@@_environment_bool + \@@_start_aux:ccnnnn + { environment~ \l_@@_environment_str \c_space_tl } + { environment~ \l_@@_environment_str \c_space_tl code } + {#1} + } +\cs_new_protected:Npx \@@_start:nNNnnn #1#2#3 + { + \exp_not:c { xparse~function~is~not~expandable } + \exp_not:N \conditionally@traceoff + \exp_not:N \group_align_safe_begin: + \exp_not:n { \bool_set_false:N \l_@@_environment_bool } + \exp_not:N \@@_start_aux:NNnnnn + #2 #3 {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_start_aux:NNnnnn, \@@_start_aux:ccnnnn} +% This sets up a few variables to minimize the boilerplate code +% included in all \pkg{xparse}-defined commands. It then runs the +% grabbers~|#4|. Again, the argument specification |#1| is only for +% diagnostics. +% \begin{macrocode} +\cs_new_protected:Npn \@@_start_aux:NNnnnn #1#2#3#4#5#6 + { + \tl_clear:N \l_@@_args_tl + \tl_set:Nn \l_@@_fn_tl {#1} + \tl_set:Nn \l_@@_fn_code_tl {#2} + \tl_set:Nn \l_@@_defaults_tl {#5} + \tl_set:Nn \l_@@_process_all_tl {#6} + #4 \@@_run_code: + } +\cs_generate_variant:Nn \@@_start_aux:NNnnnn { cc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_run_code:} +% After arguments are grabbed, this function is responsible for +% inserting default values, running processors, and finally doing +% \cs{group_align_safe_end:} as promised, and running the code. +% \begin{macrocode} +\cs_new_protected:Npn \@@_run_code: + { + \tl_if_empty:NF \l_@@_defaults_tl { \@@_defaults: } + \tl_if_empty:NF \l_@@_process_all_tl { \@@_args_process: } + \group_align_safe_end: + \conditionally@traceon + \exp_after:wN \l_@@_fn_code_tl \l_@@_args_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_defaults:} +% \begin{macro}{\@@_defaults_def:, \@@_defaults_def:nn, \@@_defaults_def:nnn} +% \begin{macro}{\@@_defaults_aux:, \@@_defaults_error:w} +% First construct \cs{@@_tmp:w} (see below) that will receive +% the arguments found so far and determine default values for any +% missing argument. Then call it repeatedly until the set of +% arguments stabilizes. Since that could lead to an infinite loop we +% only call it up to nine times, the maximal number needed for +% stabilization if there is a chain of arguments that depend on each +% other. If that fails to stabilize raise an error. +% \begin{macrocode} +\cs_new_protected:Npn \@@_defaults: + { + \@@_defaults_def: + \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_tl + \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux: + \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux: + \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux: + \@@_defaults_error:w + \q_recursion_stop + \tl_set_eq:NN \l_@@_args_tl \l_@@_args_i_tl + } +\cs_new_protected:Npn \@@_defaults_aux: + { + \tl_set:Nx \l_@@_args_ii_tl + { \exp_after:wN \@@_tmp:w \l_@@_args_i_tl } + \tl_if_eq:NNT \l_@@_args_ii_tl \l_@@_args_i_tl + { \use_none_delimit_by_q_recursion_stop:w } + \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_ii_tl + } +\cs_new_protected:Npn \@@_defaults_error:w \q_recursion_stop + { + \msg_error:nnx { cmd } { loop-in-defaults } + { \@@_environment_or_command: } + } +% \end{macrocode} +% 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 +% default will not be used) and otherwise +% |{|\cs{exp_not:n}\Arg{default}|}| for arguments whose default will +% be used. +% \begin{macrocode} +\cs_new_protected:Npn \@@_defaults_def: + { + \tl_clear:N \l_@@_tmpa_tl + \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 + \l_@@_current_arg_int \l_@@_tmpa_tl + } +\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo } +\cs_new_protected:Npn \@@_defaults_def:nn + { + \int_incr:N \l_@@_current_arg_int + \exp_args:NV \@@_defaults_def:nnn \l_@@_current_arg_int + } +\cs_new_protected:Npn \@@_defaults_def:nnn #1#2#3 + { + \tl_put_right:Nx \l_@@_tmpa_tl + { + { + \exp_not:N \exp_not:n + { + \tl_if_novalue:nTF {#2} + { \exp_not:o {#3} } + { \exp_not:n { ## #1 } } + } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_args_process:} +% \begin{macro}{\@@_args_process_loop:nn, \@@_args_process_aux:n} +% Loop through arguments (stored in \cs{l_@@_args_tl}) and the +% corresponding processors (in \cs{l_@@_process_all_tl}) +% simultaneously, apply all processors for each argument and store the +% result back into \cs{l_@@_args_tl}. To allow processors to depend +% on other arguments, for every processor define a temporary auxiliary +% that receives all arguments \cs{l_@@_args_tl}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_args_process: + { + \tl_clear:N \l_@@_args_ii_tl + \@@_tl_mapthread_function:NNN + \l_@@_args_tl + \l_@@_process_all_tl + \@@_args_process_loop:nn + \tl_set_eq:NN \l_@@_args_tl \l_@@_args_ii_tl + } +\cs_new_protected:Npn \@@_args_process_loop:nn #1#2 + { + \tl_set:Nn \ProcessedArgument {#1} + \tl_if_novalue:nF {#1} + { \tl_map_function:nN {#2} \@@_args_process_aux:n } + \tl_put_right:No \l_@@_args_ii_tl + { \exp_after:wN { \ProcessedArgument } } + } +\cs_new_protected:Npn \@@_args_process_aux:n #1 + { + \cs_generate_from_arg_count:NNnn \@@_tmp:w \cs_set:Npn + { \tl_count:N \l_@@_args_tl } {#1} + \exp_args:NNNo \exp_after:wN \@@_tmp:w \l_@@_args_tl + { \ProcessedArgument } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_start_expandable:nNNNNn} +% This is called for all expandable commands. |#6| is the signature, +% responsible for grabbing arguments. |#5| is used to determine +% default values (or is |?| if there are none). |#4| is the code to run. +% |#2|~and~|#3| are functions (named after the command) that grab a single +% argument in the input stream (|#3|~is~short). The argument specification |#1| is +% only used by diagnostic functions. Same as for the non-expandable +% version, this starts with \cs{group_align_safe_begin:}, which +% expands to nothing, so may be safely used in an expandable context. +% \begin{macrocode} +\cs_new:Npn \@@_start_expandable:nNNNNn #1#2#3#4#5#6 + { + \group_align_safe_begin: + #6 \@@_end_expandable:NNw #5 #4 \q_@@ #2#3 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_end_expandable:NNw} +% \begin{macro}[EXP]{\@@_end_expandable_aux:w} +% \begin{macro}[EXP]{\@@_end_expandable_aux:nNNNN} +% \begin{macro}[EXP]{\@@_end_expandable_defaults:nnnNNn} +% \begin{macro}[EXP]{\@@_end_expandable_defaults:nnw} +% \begin{macro}[EXP]{\@@_end_expandable_defaults:nw} +% Followed by a function |#1| to determine default values (or |?| if +% there are no defaults), the code +% |#2|, arguments that have been grabbed, then \cs{q_@@} and two generic +% grabbers. The idea to find default values is similar to the +% non-expandable case but we cannot define an auxiliary function, so +% at every step in the loop we need to go through all arguments +% searching for which ones started out as |-NoValue-| and replacing +% these by the newly computed values. In fact we need to keep track +% of three versions of all arguments: the original version, the +% previous version with default values, and the currently built +% version (first argument of \cs{@@_end_expandable_defaults:nnnNNn}). +% \begin{macrocode} +\cs_new:Npn \@@_end_expandable:NNw #1#2 + { \@@_end_expandable_aux:w #1#2 \prg_do_nothing: } +\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@ + { \exp_args:No \@@_end_expandable_aux:nNNNN {#3} #1 #2 } +\cs_new:Npn \@@_end_expandable_aux:nNNNN #1#2#3#4#5 + { + \token_if_eq_charcode:NNT ? #2 { \exp_after:wN \use_iv:nnnn } + \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3 + { } { } { } { } { } { } { } { } { } { } + { + \msg_expandable_error:nnf { cmd } { loop-in-defaults } + { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } } + \use_iv:nnnn + } + \q_stop + } +\cs_new:Npn \@@_end_expandable_defaults:nnnNNn #1#2#3#4#5#6 + { + #6 + \str_if_eq:nnTF {#1} {#2} + { \use_i_delimit_by_q_stop:nw { \group_align_safe_end: #5 #1 } } + { + \exp_args:No \@@_tl_mapthread_function:nnN + { #4 #1 } {#3} + \@@_end_expandable_defaults:nnw + \@@_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5 + } + } +\cs_new:Npn \@@_end_expandable_defaults:nnw #1#2 + { + \tl_if_novalue:nTF {#2} + { \exp_args:No \@@_end_expandable_defaults:nw {#1} } + { \@@_end_expandable_defaults:nw {#2} } + } +\cs_new:Npn \@@_end_expandable_defaults:nw + #1#2 \@@_end_expandable_defaults:nnnNNn #3 + { #2 \@@_end_expandable_defaults:nnnNNn { #3 {#1} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Normalizing the argument specifications} +% +% The goal here is to expand aliases and check that the argument +% specification is valid before the main parsing run. If it is not +% valid the entire set up is abandoned to avoid any strange internal +% errors. A function is provided for each argument type that will grab +% any extra data items and call the loop function after performing the +% following checks and tasks. +% \begin{itemize} +% \item Check that each argument has the correct number of data items +% associated with it, and that where a single character is required, +% one has actually been supplied. +% \item Check that processors and the markers~|+| and~|!| are followed +% by an argument for which they make sense, and are not redundant. +% \item Check the absence of forbidden types for expandable commands, +% namely \texttt{G}/\texttt{v} always, and \texttt{l}/\texttt{u} +% after optional arguments (\pkg{xparse} may have inserted braces +% due to a failed search for an optional argument). +% \item Check that no optional argument is followed by a mandatory +% argument with the same delimiter, as otherwise the optional +% argument could never be omitted. +% \item Keep track in \cs{l_@@_some_long_bool} and +% \cs{l_@@_some_short_bool} of whether the command has some +% long/short arguments. +% \item Keep track in \cs{l_@@_grab_expandably_bool} of whether all +% arguments are \texttt{m}/\texttt{l}/\texttt{u} type and short +% arguments appear before long ones, in which case they can be +% grabbed expandably just as safely as they could be grabbed +% nonexpandably. Regardless of that, arguments of expandable +% commands will be grabbed expandably and arguments of environments +% will not (because the list of arguments built by non-expandable +% grabbing is used to pass them to the end-environment code). +% \end{itemize} +% Further checks happen at the end of the loop: +% \begin{itemize} +% \item that there are at most $9$ arguments; +% \item that an expandable command does not end with an optional +% argument (this case is detected by using the fact that +% \cs{l_@@_last_delimiters_tl} is cleared by every mandatory argument +% and filled by every optional argument). +% \end{itemize} +% +% \begin{macro}{\@@_normalize_arg_spec:n} +% \begin{macro}{\@@_normalize_arg_spec_loop:n} +% Loop through the argument specification, calling an auxiliary +% specific to each argument type. If any argument is unknown stop the +% definition. +% \begin{macrocode} +\cs_new_protected:Npn \@@_normalize_arg_spec:n #1 + { + \int_zero:N \l_@@_current_arg_int + \tl_clear:N \l_@@_last_delimiters_tl + \tl_clear:N \l_@@_arg_spec_tl + \bool_set_true:N \l_@@_grab_expandably_bool + \bool_set_false:N \l_@@_obey_spaces_bool + \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_some_obey_spaces_bool + \bool_set_false:N \l_@@_some_long_bool + \bool_set_false:N \l_@@_some_short_bool + \@@_normalize_arg_spec_loop:n #1 + \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop + \int_compare:nNnT \l_@@_current_arg_int > 9 + { + \msg_error:nnxx { cmd } { too-many-arguments } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + \bool_if:NT \l_@@_expandable_bool + { + \tl_if_empty:NF \l_@@_last_delimiters_tl + { + \msg_error:nnxx { cmd } { expandable-ending-optional } + { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + } + \bool_if:NT \l_@@_expandable_bool + { \bool_set_true:N \l_@@_grab_expandably_bool } + \bool_if:NT \l_@@_environment_bool + { \bool_set_false:N \l_@@_grab_expandably_bool } + } +\cs_new_protected:Npn \@@_normalize_arg_spec_loop:n #1 + { + \quark_if_recursion_tail_stop:n {#1} + \int_incr:N \l_@@_current_arg_int + \cs_if_exist_use:cF { @@_normalize_type_ \tl_to_str:n {#1} :w } + { + \bool_lazy_any:nTF + { + { \str_if_eq_p:nn {#1} { G } } + { \str_if_eq_p:nn {#1} { g } } + { \str_if_eq_p:nn {#1} { l } } + { \str_if_eq_p:nn {#1} { u } } + } + { + \msg_error:nnxx { cmd } { xparse-argument-type } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + } + { + \msg_error:nnxx { cmd } { unknown-argument-type } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + } + \@@_bad_def:wn + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \@@_normalize_type_d:w, +% \@@_normalize_type_e:w, +% \@@_normalize_type_o:w, +% \@@_normalize_type_O:w, +% \@@_normalize_type_r:w, +% \@@_normalize_type_s:w, +% } +% These argument types are aliases of more general ones, for example +% with the default argument |-NoValue-|. To easily insert that marker +% expanded in the definitions we call \cs{@@_tmp:w} with the argument +% |-NoValue-|. For argument types that need additional data, check +% that the data is present (not \cs{q_recursion_tail}) before +% proceeding. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new_protected:Npn \@@_normalize_type_d:w ##1##2 + { + \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn } + \@@_normalize_type_D:w {##1} {##2} {#1} + } + \cs_new_protected:Npn \@@_normalize_type_e:w ##1 + { + \quark_if_recursion_tail_stop_do:nn {##1} { \@@_bad_arg_spec:wn } + \@@_normalize_type_E:w {##1} { } + } + \cs_new_protected:Npn \@@_normalize_type_o:w + { \@@_normalize_type_D:w [ ] {#1} } + \cs_new_protected:Npn \@@_normalize_type_O:w + { \@@_normalize_type_D:w [ ] } + \cs_new_protected:Npn \@@_normalize_type_r:w ##1##2 + { + \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn } + \@@_normalize_type_R:w {##1} {##2} {#1} + } + \cs_new_protected:Npn \@@_normalize_type_s:w + { \@@_normalize_type_t:w * } + } +\exp_args:No \@@_tmp:w { \c_novalue_tl } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_normalize_type_>:w, +% \@@_normalize_type_+:w, +% \@@_normalize_type_!:w, +% } +% Check that these prefixes have arguments, namely that the next token +% is not \cs{q_recursion_tail}, and remember to leave it after the +% looping macro. Processors are forbidden in expandable commands. +% If all is good, store the prefix in the cleaned up +% \cs{l_@@_arg_spec_tl}, and decrement the argument number as prefixes +% do not correspond to arguments. +% \begin{macrocode} +\cs_new_protected:cpn { @@_normalize_type_>:w } #1#2 + { + \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn } + \bool_if:NT \l_@@_expandable_bool + { + \msg_error:nnxx { cmd } { processor-in-expandable } + { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + \tl_put_right:Nx \l_@@_arg_spec_tl { > { \tl_trim_spaces:n {#1} } } + \int_decr:N \l_@@_current_arg_int + \bool_set_false:N \l_@@_grab_expandably_bool + \@@_normalize_arg_spec_loop:n {#2} + } +\cs_new_protected:cpn { @@_normalize_type_+:w } #1 + { + \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } + \bool_if:NT \l_@@_long_bool + { + \msg_error:nnxx { cmd } { two-markers } + { \@@_environment_or_command: } { + } + \@@_bad_def:wn + } + \bool_set_true:N \l_@@_long_bool + \int_decr:N \l_@@_current_arg_int + \@@_normalize_arg_spec_loop:n {#1} + } +\cs_new_protected:cpn { @@_normalize_type_!:w } #1 + { + \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn } + \bool_if:NT \l_@@_obey_spaces_bool + { + \msg_error:nnxx { cmd } { two-markers } + { \@@_environment_or_command: } { ! } + \@@_bad_def:wn + } + \bool_set_true:N \l_@@_obey_spaces_bool + \bool_set_true:N \l_@@_some_obey_spaces_bool + \int_decr:N \l_@@_current_arg_int + \@@_normalize_arg_spec_loop:n {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_normalize_type_D:w, +% \@@_normalize_type_E:w, +% \@@_normalize_type_t:w, +% } +% \begin{macro}{\@@_normalize_E_unique_check:w} +% Optional argument types. Check that all required data is present +% (and consists of single characters if applicable) and check for +% forbidden types for expandable commands. For \texttt{E}-type +% require that there is at least one embellishment, that each one is a +% single character, and that there aren't more optional arguments than +% embellishments; also remember that each embellishment counts as one +% argument for \cs{l_@@_current_arg_int}. Then in each case +% store the data in \cs{l_@@_arg_spec_tl}, and +% for later checks store in \cs{l_@@_last_delimiters_tl} the tokens +% whose presence determines whether there is an optional argument (for +% braces store |{}|, seen later as an empty delimiter). +% \begin{macrocode} +\cs_new_protected:Npn \@@_normalize_type_D:w #1#2#3 + { + \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn } + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 + \@@_single_token_check:n {#2} + \@@_add_arg_spec:n { D #1 #2 {#3} } + \tl_put_right:Nn \l_@@_last_delimiters_tl {#1} + \bool_set_false:N \l_@@_grab_expandably_bool + \@@_normalize_arg_spec_loop:n + } +\cs_new_protected:Npn \@@_normalize_type_E:w #1#2 + { + \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn } + \tl_if_blank:nT {#1} { \@@_bad_arg_spec:wn } + \tl_map_function:nN {#1} \@@_single_token_check:n + \tl_map_function:nN {#1} \@@_allowed_token_check:N + \@@_normalize_E_unique_check:w #1 \q_nil \q_stop + \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} } + { \@@_bad_arg_spec:wn } + \@@_add_arg_spec:n { E {#1} {#2} } + \tl_put_right:Nn \l_@@_last_delimiters_tl {#1} + \bool_set_false:N \l_@@_grab_expandably_bool + \int_add:Nn \l_@@_current_arg_int { \tl_count:n {#1} - 1 } + \@@_normalize_arg_spec_loop:n + } +\cs_new_protected:Npn \@@_normalize_E_unique_check:w #1#2 \q_stop + { + \quark_if_nil:NF #1 + { + \tl_if_in:nnT {#2} {#1} { \@@_bad_arg_spec:wn } + \@@_normalize_E_unique_check:w #2 \q_stop + } + } +\cs_new_protected:Npn \@@_normalize_type_t:w #1 + { + \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn } + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 + \tl_put_right:Nx \l_@@_arg_spec_tl + { + \bool_if:NT \l_@@_obey_spaces_bool { ! } + t \exp_not:n {#1} + } + \tl_put_right:Nn \l_@@_last_delimiters_tl {#1} + \bool_set_false:N \l_@@_grab_expandably_bool + \bool_set_false:N \l_@@_obey_spaces_bool + \bool_set_false:N \l_@@_long_bool + \@@_normalize_arg_spec_loop:n + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \@@_normalize_type_m:w, +% \@@_normalize_type_R:w, +% \@@_normalize_type_v:w +% } +% Mandatory arguments. First check the required data is present, +% consists of single characters where applicable, and that the argument +% type is allowed for expandable commands if applicable. For the +% \texttt{m} and \texttt{R} argument types check that they do not +% follow some optional argument with that delimiter as otherwise the +% optional argument could not be omitted. Then save data in +% \cs{l_@@_arg_spec_tl}, count the mandatory argument, and empty the +% list of last delimiters. +% \begin{macrocode} +\cs_new_protected:Npn \@@_normalize_type_m:w + { + \@@_delimiter_check:nnn { } { m } { \iow_char:N \{ } + \@@_add_arg_spec_mandatory:n { m } + \@@_normalize_arg_spec_loop:n + } +\cs_new_protected:Npn \@@_normalize_type_R:w #1#2#3 + { + \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn } + \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1 + \@@_single_token_check:n {#2} + \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} } + \bool_set_false:N \l_@@_grab_expandably_bool + \@@_add_arg_spec_mandatory:n { R #1 #2 {#3} } + \@@_normalize_arg_spec_loop:n + } +\cs_new_protected:Npn \@@_normalize_type_v:w + { + \@@_normalize_check_gv:N v + \@@_add_arg_spec_mandatory:n { v } + \@@_normalize_arg_spec_loop:n + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalize_type_b:w} +% This argument type is not allowed for commands. This is only +% allowed at the end of the argument specification, hence we check +% that |#1| is the end. +% \begin{macrocode} +\cs_new_protected:Npn \@@_normalize_type_b:w #1 + { + \bool_if:NF \l_@@_environment_bool + { + \msg_error:nnxx { cmd } { invalid-command-arg } + { \@@_environment_or_command: } { b } + \@@_bad_def:wn + } + \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec:n { b } + \quark_if_recursion_tail_stop:n {#1} + \msg_error:nnxx { cmd } { arg-after-body } + { \@@_environment_or_command: } + { \tl_to_str:n {#1} } + \@@_bad_def:wn + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_single_token_check:n} +% Checks that the argument is a single (non-space) token (possibly +% surrounded by spaces), and aborts the definition otherwise. +% \begin{macrocode} +\cs_new_protected:Npn \@@_single_token_check:n #1 + { + \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nF + { + \msg_error:nnxx { cmd } { not-single-token } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_allowed_token_check:N} +% Some tokens are now allowed as delimiters for some argument types, +% notably implicit begin/end-group tokens (|\bgroup|/|\egroup|). +% The major problem with these tokens is that for |\peek_...| functions, +% a literal~|{|$_1$. is virtually indistinguishable from a |\bgroup| or +% other token which was |\let| to a~|{|$_1$, and the same goes +% for~|}|$_2$. All other tokens can be easily distingushed from their +% implicit counterparts by grabbing them and looking at the string +% length (see \cs{@@_token_if_cs:NTF}), but for begin/end group tokens +% that is not possible without the risk of mistakenly grabbing the +% entire brace group (potentially leading to a~\texttt{!~Runaway argument} +% error) or trying to grab a |}|$_2$, leading to +% an~\verb|! Argument of \dots has an extra }| error. +% \begin{macrocode} +\cs_new_protected:Npn \@@_allowed_token_check:N #1 + { + \token_if_eq_meaning:NNTF #1 \c_group_begin_token + { \use:n } + { + \token_if_eq_meaning:NNTF #1 \c_group_end_token + { \use:n } + { \use_none:n } + } + { + \msg_error:nnxxx { cmd } { forbidden-implicit-group-token } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + { + \token_if_eq_meaning:NNTF #1 \c_group_begin_token + { begin } { end } + } + \@@_bad_def:wn + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalize_check_gv:N, \@@_normalize_check_lu:N} +% Called for arguments that are always forbidden, or forbidden after +% an optional argument, for expandable commands. +% \begin{macrocode} +\cs_new_protected:Npn \@@_normalize_check_gv:N #1 + { + \bool_if:NT \l_@@_expandable_bool + { + \msg_error:nnxx { cmd } { invalid-expandable-argument-type } + { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + \bool_set_false:N \l_@@_grab_expandably_bool + } +\cs_new_protected:Npn \@@_normalize_check_lu:N #1 + { + \bool_if:NT \l_@@_expandable_bool + { + \tl_if_empty:NF \l_@@_last_delimiters_tl + { + \msg_error:nnxx { cmd } { invalid-after-optional-expandably } + { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_delimiter_check:nnn} +% Called for \texttt{m} and \texttt{R} arguments. Checks that the +% leading token does not coincide with the token denoting the presence +% of a previous optional argument. Instead of dealing with braces for +% the \texttt{m}-type we use an empty delimiter to denote that case. +% \begin{macrocode} +\cs_new_protected:Npn \@@_delimiter_check:nnn #1#2#3 + { + \tl_map_inline:Nn \l_@@_last_delimiters_tl + { + \tl_if_eq:nnT {##1} {#1} + { + \msg_warning:nnxx { cmd } { optional-mandatory } + {#2} {#3} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_bad_arg_spec:wn, \@@_bad_def:wn} +% If the argument specification is wrong, this provides an escape from +% the entire definition process. +% \begin{macrocode} +\cs_new_protected:Npn \@@_bad_arg_spec:wn #1 \@@_break_point:n #2 + { + \msg_error:nnxx { cmd } { bad-arg-spec } + { \@@_environment_or_command: } { \tl_to_str:n {#2} } + } +\cs_new_protected:Npn \@@_bad_def:wn #1 \@@_break_point:n #2 { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_arg_spec:n, \@@_add_arg_spec_mandatory:n} +% When adding an argument to the argument specification, set the +% \texttt{some_long} or \texttt{some_short} booleans as appropriate +% and clear the booleans keeping track of |+| and |!| markers. +% Before that, test for a short argument following some long +% arguments: this is forbidden for expandable commands and prevents +% grabbing arguments expandably. +% +% For mandatory arguments do some more work, in particular complain if +% they were preceeded by~|!|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_arg_spec:n #1 + { + \bool_lazy_and:nnT + { ! \l_@@_long_bool } + { \l_@@_some_long_bool } + { + \bool_if:NT \l_@@_expandable_bool + { + \msg_error:nnx { cmd } { inconsistent-long } + { \iow_char:N \\ \l_@@_function_tl } + \@@_bad_def:wn + } + \bool_set_false:N \l_@@_grab_expandably_bool + } + \bool_if:NTF \l_@@_long_bool + { \bool_set_true:N \l_@@_some_long_bool } + { \bool_set_true:N \l_@@_some_short_bool } + \tl_put_right:Nx \l_@@_arg_spec_tl + { + \bool_if:NT \l_@@_long_bool { + } + \bool_if:NT \l_@@_obey_spaces_bool { ! } + \exp_not:n {#1} + } + \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_obey_spaces_bool + } +\cs_new_protected:Npn \@@_add_arg_spec_mandatory:n #1 + { + \bool_if:NT \l_@@_some_obey_spaces_bool + { + \msg_error:nnxx { cmd } { non-trailing-obey-spaces } + { \@@_environment_or_command: } { \tl_to_str:n {#1} } + \@@_bad_def:wn + } + \tl_clear:N \l_@@_last_delimiters_tl + \@@_add_arg_spec:n {#1} + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Preparing the signature: general mechanism} +% +% \begin{macro}{\@@_prepare_signature:n} +% \begin{macro}{\@@_prepare_signature:N} +% \begin{macro}{\@@_prepare_signature_bypass:N} +% Actually creating the signature uses the same loop approach as +% normalizing the signature. There are first a number of variables which need +% to be set to track what is going on. Many of these variables are unused +% when defining expandable commands. +% \begin{macrocode} +\cs_new_protected:Npn \@@_prepare_signature:n #1 + { + \int_zero:N \l_@@_current_arg_int + \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_obey_spaces_bool + \int_zero:N \l_@@_m_args_int + \bool_set_false:N \l_@@_defaults_bool + \tl_clear:N \l_@@_defaults_tl + \tl_clear:N \l_@@_process_all_tl + \tl_clear:N \l_@@_process_one_tl + \bool_set_false:N \l_@@_process_some_bool + \tl_clear:N \l_@@_signature_tl + \@@_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop + \bool_if:NF \l_@@_expandable_bool { \@@_flush_m_args: } + } +% \end{macrocode} +% The main looping function does not take an argument, but carries out the +% reset on the processor boolean. This is split off from the rest of the +% process so that when actually setting up processors the flag-reset can +% be bypassed. +% +% For each known argument type there is an appropriate function to actually +% do the addition to the signature. These are separate for expandable and +% standard functions, as the approaches are different. +% \begin{macrocode} +\cs_new_protected:Npn \@@_prepare_signature:N + { + \bool_set_false:N \l_@@_prefixed_bool + \@@_prepare_signature_bypass:N + } +\cs_new_protected:Npn \@@_prepare_signature_bypass:N #1 + { + \quark_if_recursion_tail_stop:N #1 + \use:c + { + @@_add + \bool_if:NT \l_@@_grab_expandably_bool { _expandable } + _type_ \token_to_str:N #1 :w + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Setting up a standard signature} +% +% Each argument-adding function appends to the signature a grabber (and +% for some types, the delimiters or default value), except the one for +% \texttt{m} arguments. These are collected and added to the signature +% all at once by \cs{@@_flush_m_args:}, called for every other argument +% type. All of the functions then call the loop function +% \cs{@@_prepare_signature:N}. Default values of arguments are +% collected by \cs{@@_add_default:n} rather than being stored with the +% argument; this function and \cs{@@_add_default:} are also responsible +% for keeping track of \cs{l_@@_current_arg_int}. +% +% \begin{macro}{\@@_add_type_+:w} +% Making the next argument long means setting the flag. The \texttt{m} +% arguments are recorded here as +% this has to be done for every case where there is then a long argument. +% \begin{macrocode} +\cs_new_protected:cpn { @@_add_type_+:w } + { + \@@_flush_m_args: + \bool_set_true:N \l_@@_long_bool + \bool_set_true:N \l_@@_prefixed_bool + \@@_prepare_signature_bypass:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_!:w} +% Much the same for controlling trailing optional arguments. +% \begin{macrocode} +\cs_new_protected:cpn { @@_add_type_!:w } + { + \@@_flush_m_args: + \bool_set_true:N \l_@@_obey_spaces_bool + \bool_set_true:N \l_@@_prefixed_bool + \@@_prepare_signature_bypass:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_>:w} +% When a processor is found, the processor code is stored. It will be +% used by \cs{@@_args_process:} once arguments are all found. Here too +% the loop calls \cs{@@_prepare_signature_bypass:N} rather than +% \cs{@@_prepare_signature:N} so that the flag is not reset. +% \begin{macrocode} +\cs_new_protected:cpn { @@_add_type_>:w } #1 + { + \@@_flush_m_args: + \bool_set_true:N \l_@@_prefixed_bool + \bool_set_true:N \l_@@_process_some_bool + \tl_put_left:Nn \l_@@_process_one_tl { {#1} } + \@@_prepare_signature_bypass:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_b:w} +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_b:w + { + \@@_flush_m_args: + \@@_add_default: + \@@_add_grabber:N b + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_D:w} +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_D:w #1#2#3 + { + \@@_flush_m_args: + \@@_add_default:n {#3} + \@@_add_grabber:N D + \tl_put_right:Nn \l_@@_signature_tl { #1 #2 } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_E:w} +% The \texttt{E}-type argument needs a special handling of default +% values. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_E:w #1#2 + { + \@@_flush_m_args: + \@@_add_default_E:nn {#1} {#2} + \@@_add_grabber:N E + \tl_put_right:Nn \l_@@_signature_tl { {#1} } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_m:w} +% The \texttt{m} type is special as short arguments which are not +% post-processed are simply counted at this stage. Thus there is a check +% to see if either of these cases apply. If so, a one-argument grabber +% is added to the signature. On the other hand, if a standard short +% argument is required it is simply counted at this stage, to be +% added later using \cs{@@_flush_m_args:}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_m:w + { + \@@_add_default: + \bool_if:NTF \l_@@_prefixed_bool + { \@@_add_grabber:N m } + { \int_incr:N \l_@@_m_args_int } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_R:w} +% The \texttt{R}-type argument is very similar to the \texttt{D}-type. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_R:w #1#2#3 + { + \@@_flush_m_args: + \@@_add_default:n {#3} + \@@_add_grabber:N R + \tl_put_right:Nn \l_@@_signature_tl { #1 #2 } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_t:w} +% Setting up a \texttt{t} argument means collecting one token for the test, +% and adding it along with the grabber to the signature. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_t:w #1 + { + \@@_flush_m_args: + \@@_add_default: + \@@_add_grabber:N t + \tl_put_right:Nn \l_@@_signature_tl {#1} + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_type_v:w} +% At this stage, the \texttt{v} argument is identical to \texttt{l} +% except that since the grabber may fail to read a verbatim argument +% we need a default value. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_type_v:w + { + \@@_flush_m_args: + \exp_args:No \@@_add_default:n \c_novalue_tl + \@@_add_grabber:N v + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_flush_m_args:} +% As \texttt{m} arguments are simply counted, there is a need to add +% them to the token register in a block. As this function can only +% be called if something other than \texttt{m} turns up, the flag can +% be switched here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_flush_m_args: + { + \int_compare:nNnT \l_@@_m_args_int > 0 + { + \tl_put_right:Nx \l_@@_signature_tl + { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } } + \tl_put_right:Nx \l_@@_process_all_tl + { \prg_replicate:nn { \l_@@_m_args_int } { { } } } + } + \int_zero:N \l_@@_m_args_int + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_grabber:N} +% To keep the various checks needed in one place, adding the grabber +% to the signature is done here. The only questions are whether the +% grabber should be long or not, and whether to obey spaces. The +% \cs{l_@@_obey_spaces_bool} boolean can only be \texttt{true} for +% trailing optional arguments. In that case spaces will not be +% ignored when looking for that optional argument. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_grabber:N #1 + { + \tl_put_right:Nx \l_@@_signature_tl + { + \exp_not:c + { + @@_grab_ #1 + \bool_if:NT \l_@@_long_bool { _long } + \bool_if:NT \l_@@_obey_spaces_bool { _obey_spaces } + :w + } + } + \bool_set_false:N \l_@@_long_bool + \bool_set_false:N \l_@@_obey_spaces_bool + \tl_put_right:Nx \l_@@_process_all_tl + { { \exp_not:o \l_@@_process_one_tl } } + \tl_clear:N \l_@@_process_one_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn} +% Store the default value of an argument, or rather code that gives +% that default value (it may involve other arguments). This is +% \cs{c_novalue_tl} for arguments with no actual default or with +% default |-NoValue-|; and (in a brace group) \cs{prg_do_nothing:} +% followed by a default value for others. For \texttt{E}-type +% arguments, pad the defaults |#2| with some \cs{c_novalue_tl} +% until there are as many as embellishments~|#1|. These functions are +% also used when defining expandable commands. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_default:n #1 + { + \tl_if_novalue:nTF {#1} + { \@@_add_default: } + { + \int_incr:N \l_@@_current_arg_int + \bool_set_true:N \l_@@_defaults_bool + \tl_put_right:Nn \l_@@_defaults_tl { { \prg_do_nothing: #1 } } + } + } +\cs_new_protected:Npn \@@_add_default: + { + \int_incr:N \l_@@_current_arg_int + \tl_put_right:Nn \l_@@_defaults_tl { \c_novalue_tl } + } +\cs_new_protected:Npn \@@_add_default_E:nn #1#2 + { + \tl_map_function:nN {#2} \@@_add_default:n + \prg_replicate:nn + { \tl_count:n {#1} - \tl_count:n {#2} } + { \@@_add_default: } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Setting up expandable types} +% +% The approach here is not dissimilar to that for standard types, but fewer types +% are supported. There is +% also a need to define the per-function auxiliaries: this is done here, while +% the general grabbers are dealt with later. +% +% \begin{macro}{\@@_add_expandable_type_+:w} +% We have already checked that short arguments are before long +% arguments, so \cs{l_@@_long_bool} only changes from \texttt{false} +% to \texttt{true} once (and there is no need to reset it after each +% argument). Also knock back the argument count because |+| is not an +% argument. Continue the loop. +% \begin{macrocode} +\cs_new_protected:cpn { @@_add_expandable_type_+:w } + { + \bool_set_true:N \l_@@_long_bool + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_type_D:w} +% \begin{macro}{\@@_add_expandable_type_D_aux:NNNn} +% \begin{macro}{\@@_add_expandable_type_D_aux:NNN} +% \begin{macro}{\@@_add_expandable_type_D_aux:NN} +% The set up for \texttt{D}-type arguments involves constructing a +% rather complex auxiliary which is used +% repeatedly when grabbing. There is an auxiliary here so that the +% \texttt{R}-type can share code readily: |#1| is |D| or~|R|. +% The |_aux:NN| auxiliary is needed if the two delimiting tokens are +% identical: in contrast to the non-expandable route, the grabber here +% has to act differently for this case. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_type_D:w + { \@@_add_expandable_type_D_aux:NNNn D } +\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNNn #1#2#3#4 + { + \@@_add_default:n {#4} + \tl_if_eq:nnTF {#2} {#3} + { \@@_add_expandable_type_D_aux:NN #1 #2 } + { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 } + \@@_prepare_signature:N + } +\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3 + { + \bool_if:NTF \l_@@_long_bool + { \cs_set:cpx } + { \cs_set_nopar:cpx } + { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3 + { ##1 {##2} {##3} {##4} } + \@@_add_expandable_grabber:nn {#1} + { + \exp_not:c { \l_@@_expandable_aux_name_tl } + \exp_not:n { #2 #3 } + } + } +\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2 + { + \bool_if:NTF \l_@@_long_bool + { \cs_set:cpx } + { \cs_set_nopar:cpx } + { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2 + { ##1 {##2} } + \@@_add_expandable_grabber:nn { #1_alt } + { + \exp_not:c { \l_@@_expandable_aux_name_tl } + \exp_not:n {#2} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_type_E:w} +% \begin{macro}{\@@_add_expandable_type_E_aux:n} +% For each embellishment, use \cs{@@_get_grabber:NN} to obtain an +% auxiliary delimited by that token and store a pair constituted of +% the auxiliary and the token in \cs{l_@@_tmpb_tl}, before appending +% the whole set of these pairs to the signature, and an equal number +% of |-NoValue-| markers (regardless of the default values of +% arguments). Set the current argument appropriately. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2 + { + \@@_add_default_E:nn {#1} {#2} + \tl_clear:N \l_@@_tmpb_tl + \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n + \@@_add_expandable_grabber:nn + { E \bool_if:NT \l_@@_long_bool { _long } } + { + { \exp_not:o \l_@@_tmpb_tl } + { + \prg_replicate:nn { \tl_count:n {#1} } + { { \c_novalue_tl } } + } + } + \@@_prepare_signature:N + } +\cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1 + { + \@@_get_grabber:NN #1 \l_@@_tmpa_tl + \tl_put_right:Nx \l_@@_tmpb_tl + { \exp_not:o \l_@@_tmpa_tl \exp_not:N #1 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_type_m:w} +% Unlike the standard case, when working expandably each argument is always +% grabbed separately. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_type_m:w + { + \@@_add_default: + \@@_add_expandable_grabber:nn + { m \bool_if:NT \l_@@_long_bool { _long } } { } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_type_R:w} +% The \texttt{R}-type is very similar to the \texttt{D}-type +% argument, and so the same internals are used. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_type_R:w + { \@@_add_expandable_type_D_aux:NNNn R } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_type_t:w} +% An auxiliary delimited by |#1| is built now. It will be used to +% test for the presence of that token. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_type_t:w #1 + { + \@@_add_default: + \@@_get_grabber:NN #1 \l_@@_tmpa_tl + \@@_add_expandable_grabber:nn { t } + { + \exp_not:o \l_@@_tmpa_tl + \exp_not:N #1 + } + \@@_prepare_signature:N + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_expandable_grabber:nn} +% This is called for all arguments to place the right grabber in the +% signature. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_expandable_grabber:nn #1#2 + { + \tl_put_right:Nx \l_@@_signature_tl + { \exp_not:c { @@_expandable_grab_ #1 :w } #2 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_get_grabber:NN} +% \begin{macro}{\@@_get_grabber_auxi:NN} +% \begin{macro}{\@@_get_grabber_auxii:NN} +% Given a token |#1|, defines an expandable function delimited by that +% token and stores it in the token list~|#2|. The function is named +% after the token, unless that function name is already taken by some +% other grabber (this can happen in the rare case where delimiters +% with different category codes are used in the same document): in +% that case use a global counter to get a unique name. Since the +% grabbers are not named after \pkg{xparse} commands they should not +% be used to get material from the input stream. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_grabber:NN #1#2 + { + \cs_set:Npn \@@_tmp:w ##1 #1 {##1} + \exp_args:Nc \@@_get_grabber_auxi:NN + { @@_grabber_ \token_to_str:N #1 :w } #2 + } +\cs_new_protected:Npn \@@_get_grabber_auxi:NN #1#2 + { + \cs_if_eq:NNTF \@@_tmp:w #1 + { \tl_set:Nn #2 {#1} } + { + \cs_if_exist:NTF #1 + { + \int_gincr:N \g_@@_grabber_int + \exp_args:Nc \@@_get_grabber_auxi:NN + { + @@_grabber_ + - \int_use:N \g_@@_grabber_int :w + } + #2 + } + { \@@_get_grabber_auxii:NN #1 #2 } + } + } +\cs_new_protected:Npn \@@_get_grabber_auxii:NN #1#2 + { + \cs_set_eq:NN #1 \@@_tmp:w + \tl_set:Nn #2 {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Grabbing arguments} +% +% All of the grabbers follow the same basic pattern. The initial +% function stores in \cs{l_@@_signature_tl} the code to grab further +% arguments, defines (the function in) \cs{l_@@_fn_tl} that will grab +% the argument, and calls it. +% +% Defining \cs{l_@@_fn_tl} means determining whether to use +% \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for optional arguments +% whether to skip spaces. Once the argument is found, \cs{l_@@_fn_tl} +% calls \cs{@@_add_arg:n}, responsible for calling processors and +% grabbing further arguments. +% +% \begin{macro} +% { +% \@@_grab_b:w, +% \@@_grab_b_long:w, +% \@@_grab_b_obey_spaces:w, +% \@@_grab_b_long_obey_spaces:w, +% \@@_grab_b_aux:NNw, +% \@@_grab_b_end:Nw +% } +% This uses the well-tested code of \texttt{D}-type arguments, +% skipping the peeking step because the \texttt{b}-type argument is +% always present, and adding a cleanup stage at the end by hijacking +% the signature. The clean-up consists of properly +% dealing with \cs{l_@@_args_tl} and also putting back the \cs{end} +% that served as an end-delimiter: this \cs{end} receives the +% environment name as its argument and is run normally. The +% \texttt{D}-type code stores the argument found (body of the +% environment) as a brace group in \cs{l_@@_args_tl} and depending on +% the presence of a prefix~|!| we trim spaces or not before adding +% this braced argument into the saved \cs{l_@@_args_tl}. +% The strange \verb*|\begin | control sequence is there for display +% purposes only: it has to look like |\begin| in the terminal but +% not to delimited arguments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_b:w + { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \tl_trim_spaces:n } +\cs_new_protected:Npn \@@_grab_b_long:w + { \@@_grab_b_aux:NNw \cs_set_protected:Npn \tl_trim_spaces:n } +\cs_new_protected:Npn \@@_grab_b_obey_spaces:w + { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \exp_not:n } +\cs_new_protected:Npn \@@_grab_b_long_obey_spaces:w + { \@@_grab_b_aux:NNw \cs_set_protected:Npn \exp_not:n } +\cs_new_protected:Npn \@@_grab_b_aux:NNw #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnN \begin \end {#3} #1 + \tl_put_left:Nn \l_@@_signature_tl { \@@_grab_b_end:Nw #2 } + \tl_set_eq:NN \l_@@_saved_args_tl \l_@@_args_tl + \tl_clear:N \l_@@_args_tl + \exp_args:Nc \l_@@_fn_tl { begin ~ } + } +\cs_new_protected:Npn \@@_grab_b_end:Nw #1#2 \@@_run_code: + { + \tl_set:Nx \l_@@_args_tl + { + \exp_not:V \l_@@_saved_args_tl + { \exp_after:wN #1 \l_@@_args_tl } + } + #2 + \@@_run_code: + \end + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_grab_D:w} +% \begin{macro}{\@@_grab_D_long:w} +% \begin{macro}{\@@_grab_D_obey_spaces:w} +% \begin{macro}{\@@_grab_D_long_obey_spaces:w} +% The generic delimited argument grabber. The auxiliary function does +% a peek test before calling \cs{@@_grab_D_call:Nw}, so that the +% optional nature of the argument works as expected. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_D:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn + \@@_peek_nonspace_remove:NTF + } +\cs_new_protected:Npn \@@_grab_D_long:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn + \@@_peek_nonspace_remove:NTF + } +\cs_new_protected:Npn \@@_grab_D_obey_spaces:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn + \@@_peek_meaning_remove:NTF + } +\cs_new_protected:Npn \@@_grab_D_long_obey_spaces:w #1#2#3 \@@_run_code: + { + \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn + \@@_peek_meaning_remove:NTF + } +% \end{macrocode} +% \begin{macro}{\@@_grab_D_aux:NNnNN} +% \begin{macro}{\@@_grab_D_aux:NNnN} +% This is a bit complicated. The idea is that, in order to check for +% nested optional argument tokens (\texttt{[[...]]} and so on) the +% argument needs to be grabbed without removing any braces at all. If +% this is not done, then cases like |[{[}]| fail. So after testing for +% an optional argument, it is collected piece-wise. Inserting a quark +% prevents loss of braces, and there is then a test to see if there are +% nested delimiters to handle. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_D_aux:NNnNN #1#2#3#4#5 + { + \@@_grab_D_aux:NNnN #1#2 {#3} #4 + #5 #1 + { \@@_grab_D_call:Nw #1 } + { \@@_add_arg:o \c_novalue_tl } + } +% \end{macrocode} +% Inside the \enquote{standard} grabber, there is a test to see if the +% grabbed argument is entirely enclosed by braces. There are a couple of +% extra factors to allow for: the argument might be entirely empty, and +% spaces at the start and end of the input must be retained around a brace +% group. Also notice that a \emph{blank} argument might still contain +% spaces. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_D_aux:NNnN #1#2#3#4 + { + \tl_set:Nn \l_@@_signature_tl {#3} + \exp_after:wN #4 \l_@@_fn_tl ##1 #2 + { + \tl_if_in:nnTF {##1} {#1} + { \@@_grab_D_nested:NNnN #1 #2 {##1} #4 } + { + \tl_if_blank:oTF { \use_none:n ##1 } + { \@@_add_arg:o { \use_none:n ##1 } } + { + \str_if_eq:eeTF + { \exp_not:o { \use_none:n ##1 } } + { { \exp_not:o { \use_ii:nnn ##1 \q_nil } } } + { \@@_add_arg:o { \use_ii:nn ##1 } } + { \@@_add_arg:o { \use_none:n ##1 } } + } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\@@_grab_D_nested:NNnN} +% \begin{macro}{\@@_grab_D_nested:w} +% \begin{macro}{\l_@@_nesting_a_tl} +% \begin{macro}{\l_@@_nesting_b_tl} +% \begin{macro}{\q_@@} +% Catching nested optional arguments means more work. The aim here is +% to collect up each pair of optional tokens without \TeX{} helping out, +% and without counting anything. The code above will already have +% removed the leading opening token and a closing token, but the +% wrong one. The aim is then to work through the material grabbed +% so far and divide it up on each opening token, grabbing a closing +% token to match (thus working in pairs). Once there are no opening +% tokens, then there is a second check to see if there are any +% opening tokens in the second part of the argument (for things +% like |[][]|). Once everything has been found, the entire collected +% material is added to the output as a single argument. The only tricky part +% here is ensuring that any grabbing function that might run away is named +% after the function currently being parsed and not after \pkg{xparse}. That +% leads to some rather complex nesting! There is also a need to prevent the +% loss of any braces, hence the insertion and removal of quarks along the +% way. +% \begin{macrocode} +\tl_new:N \l_@@_nesting_a_tl +\tl_new:N \l_@@_nesting_b_tl +\quark_new:N \q_@@ +\cs_new_protected:Npn \@@_grab_D_nested:NNnN #1#2#3#4 + { + \tl_clear:N \l_@@_nesting_a_tl + \tl_clear:N \l_@@_nesting_b_tl + \exp_after:wN #4 \l_@@_fn_tl ##1 #1 ##2 \q_@@ ##3 #2 + { + \tl_put_right:No \l_@@_nesting_a_tl { \use_none:n ##1 #1 } + \tl_put_right:No \l_@@_nesting_b_tl { \use_i:nn #2 ##3 } + \tl_if_in:nnTF {##2} {#1} + { + \l_@@_fn_tl + \q_nil ##2 \q_@@ \ERROR + } + { + \tl_put_right:Nx \l_@@_nesting_a_tl + { \@@_grab_D_nested:w \q_nil ##2 \q_stop } + \tl_if_in:NnTF \l_@@_nesting_b_tl {#1} + { + \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_nesting_b_tl + \tl_clear:N \l_@@_nesting_b_tl + \exp_after:wN \l_@@_fn_tl \exp_after:wN + \q_nil \l_@@_tmpa_tl \q_nil \q_@@ \ERROR + } + { + \tl_put_right:No \l_@@_nesting_a_tl + \l_@@_nesting_b_tl + \@@_add_arg:V \l_@@_nesting_a_tl + } + } + } + \l_@@_fn_tl #3 \q_nil \q_@@ \ERROR + } +\cs_new:Npn \@@_grab_D_nested:w #1 \q_nil \q_stop + { \exp_not:o { \use_none:n #1 } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\@@_grab_D_call:Nw} +% For \texttt{D} and \texttt{R}-type arguments, to avoid losing any +% braces, a token needs to be inserted before the argument to be grabbed. +% If the argument runs away because the closing token is missing then this +% inserted token shows up in the terminal. Ideally, |#1| would therefore be +% used directly, but that is no good as it will mess up the rest of the +% grabber. Instead, a copy of |#1| with an altered category code is used, +% as this will look right in the terminal but will not mess up the grabber. +% The only issue then is that the category code of |#1| is unknown. So there +% is a quick test to ensure that the inserted token can never be matched by +% the grabber. (This assumes that the open and close delimiters are not the +% same character with different category codes, but that really should not +% happen in any sensible document-level syntax.) +% An exception is when |#1| is a control sequence token, in which case the +% character-token treatment is no good because if hit with \cs{token_to_str:N} +% it would add sputios tokens to the argument. In this case a different +% branch is taken. The token inserted is then the same \meta{csname} as |#1|, +% but with a space appended, so that the grabber don't see it as another +% of the same delimiter. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_grab_D_call:Nw #1 + { + \token_if_eq_catcode:NNTF + #1 + { + \exp_after:wN \exp_after:wN \exp_after:wN + \l_@@_fn_tl \char_generate:nn { `#1 } { 11 } + } + { + \@@_token_if_cs:NTF #1 + { + \exp_after:wN \l_@@_fn_tl + \cs:w \cs_to_str:N #1 ~ \cs_end: + } + { + \exp_after:wN \l_@@_fn_tl + \token_to_str:N #1 + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_grab_E:w, \@@_grab_E_long:w, +% \@@_grab_E_obey_spaces:w, \@@_grab_E_long_obey_spaces:w +% } +% \begin{macro}{\@@_grab_E:nnNN} +% \begin{macro}{\@@_grab_E_loop:NnN} +% \begin{macro}{\@@_grab_E_finalise:} +% Everything here needs to point to a loop. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_E:w #1#2 \@@_run_code: + { + \@@_grab_E:nnNN {#1} {#2} + \cs_set_protected_nopar:Npn + \@@_peek_nonspace_remove:NTF + } +\cs_new_protected:Npn \@@_grab_E_long:w #1#2 \@@_run_code: + { + \@@_grab_E:nnNN {#1} {#2} + \cs_set_protected:Npn + \@@_peek_nonspace_remove:NTF + } +\cs_new_protected:Npn \@@_grab_E_obey_spaces:w #1#2 \@@_run_code: + { + \@@_grab_E:nnNN {#1} {#2} + \cs_set_protected_nopar:Npn + \@@_peek_meaning_remove:NTF + } +\cs_new_protected:Npn \@@_grab_E_long_obey_spaces:w #1#2 \@@_run_code: + { + \@@_grab_E:nnNN {#1} {#2} + \cs_set_protected:Npn + \@@_peek_meaning_remove:NTF + } +% \end{macrocode} +% A loop is needed here to allow a random ordering of keys. These are +% searched for one at a time, with any not found needing to be tracked: +% they can appear later. The grabbed values are held in a property list +% which is then turned into an ordered list to be passed back to the user. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_E:nnNN #1#2#3#4 + { + \exp_after:wN #3 \l_@@_fn_tl ##1##2##3 + { + \prop_put:Nnn \l_@@_tmp_prop {##1} {##3} + \@@_grab_E_loop:NnN #4 { } ##2 \q_recursion_stop + } + \prop_clear:N \l_@@_tmp_prop + \tl_set:Nn \l_@@_signature_tl {#2} + \cs_set_protected:Npn \@@_grab_E_finalise: + { + \tl_map_inline:nn {#1} + { + \prop_get:NnNF \l_@@_tmp_prop {####1} \l_@@_tmpb_tl + { \tl_set_eq:NN \l_@@_tmpb_tl \c_novalue_tl } + \tl_put_right:Nx \l_@@_args_tl + { { \exp_not:V \l_@@_tmpb_tl } } + } + \l_@@_signature_tl \@@_run_code: + } + \@@_grab_E_loop:NnN #4 { } #1 \q_recursion_tail \q_recursion_stop + } +\cs_new_protected:Npn \@@_grab_E_loop:NnN #1#2#3#4 \q_recursion_stop + { + \cs_if_eq:NNTF #3 \q_recursion_tail + { \@@_grab_E_finalise: } + { + #1 #3 + { \l_@@_fn_tl #3 {#2#4} } + { \@@_grab_E_loop:NnN #1 {#2#3} #4 \q_recursion_stop } + } + } +\cs_new_protected:Npn \@@_grab_E_finalise: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@@_grab_m:w} +% \begin{macro}{\@@_grab_m_long:w} +% Collecting a single mandatory argument is quite easy. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_m:w #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl ##1 + { \@@_add_arg:n {##1} } + \l_@@_fn_tl + } +\cs_new_protected:Npn \@@_grab_m_long:w #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl ##1 + { \@@_add_arg:n {##1} } + \l_@@_fn_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_m_1:w} +% \begin{macro}{\@@_grab_m_2:w} +% \begin{macro}{\@@_grab_m_3:w} +% \begin{macro}{\@@_grab_m_4:w} +% \begin{macro}{\@@_grab_m_5:w} +% \begin{macro}{\@@_grab_m_6:w} +% \begin{macro}{\@@_grab_m_7:w} +% \begin{macro}{\@@_grab_m_8:w} +% \begin{macro}{\@@_grab_m_9:w} +% \begin{macro}{\@@_grab_m_aux:Nnnnnnnnn} +% Grabbing 1--8 mandatory arguments is done by giving 8--1 known +% arguments to a 9-argument function that stores them in +% \cs{l_@@_args_tl}. For simplicity, grabbing 9 mandatory arguments +% is done by grabbing 5 then 4 arguments. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_grab_m_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9 + { + \tl_put_right:No \l_@@_args_tl + { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} } + \l_@@_signature_tl \@@_run_code: + } +\cs_new_protected:cpn { @@_grab_m_1:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nnnnnnn { } { } { } { } { } { } { } + } +\cs_new_protected:cpn { @@_grab_m_2:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nnnnnn { } { } { } { } { } { } + } +\cs_new_protected:cpn { @@_grab_m_3:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nnnnn { } { } { } { } { } + } +\cs_new_protected:cpn { @@_grab_m_4:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nnnn { } { } { } { } + } +\cs_new_protected:cpn { @@_grab_m_5:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nnn { } { } { } + } +\cs_new_protected:cpn { @@_grab_m_6:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:nn { } { } + } +\cs_new_protected:cpn { @@_grab_m_7:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \use_none:n { } + } +\cs_new_protected:cpn { @@_grab_m_8:w } #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn + \l_@@_fn_tl \prg_do_nothing: + } +\cs_new_protected:cpx { @@_grab_m_9:w } + { + \exp_not:c { @@_grab_m_5:w } + \exp_not:c { @@_grab_m_4:w } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_R:w, \@@_grab_R_long:w} +% \begin{macro}{\@@_grab_R_aux:NNnN} +% The grabber for \texttt{R}-type arguments is basically the same as +% that for \texttt{D}-type ones, but always skips spaces (as it is mandatory) +% and has a hard-coded error message. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_R:w #1#2#3 \@@_run_code: + { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected_nopar:Npn } +\cs_new_protected:Npn \@@_grab_R_long:w #1#2#3 \@@_run_code: + { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected:Npn } +\cs_new_protected:Npn \@@_grab_R_aux:NNnN #1#2#3#4 + { + \@@_grab_D_aux:NNnN #1 #2 {#3} #4 + \@@_peek_nonspace_remove:NTF #1 + { \@@_grab_D_call:Nw #1 } + { + \msg_error:nnxx { cmd } { missing-required } + { \@@_environment_or_command: } + { \token_to_str:N #1 } + \@@_add_arg:o \c_novalue_tl + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_t:w} +% \begin{macro}{\@@_grab_t_obey_spaces:w} +% \begin{macro}{\@@_grab_t_aux:NNw} +% Dealing with a token is quite easy. Check the match, remove the +% token if needed and add a flag to the output. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_t:w + { \@@_grab_t_aux:NNw \@@_peek_nonspace_remove:NTF } +\cs_new_protected:Npn \@@_grab_t_obey_spaces:w + { \@@_grab_t_aux:NNw \@@_peek_meaning_remove:NTF } +\cs_new_protected:Npn \@@_grab_t_aux:NNw #1#2#3 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#3} + \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl + { + #1 #2 + { \@@_add_arg:n { \BooleanTrue } } + { \@@_add_arg:n { \BooleanFalse } } + } + \l_@@_fn_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\l_@@_v_arg_tl} +% \begin{macrocode} +\tl_new:N \l_@@_v_arg_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_grab_v:w} +% \begin{macro}{\@@_grab_v_long:w} +% \begin{macro}{\@@_grab_v_aux:w} +% \begin{macro}{\@@_grab_v_group_end:} +% 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 +% already read and tokenized that token when looking for the optional +% argument. The first thing is thus to check is that this delimiter +% is a character, and to distinguish the case of a left brace (in that +% case, \cs{group_align_safe_end:} is needed to compensate for the +% begin-group character that was just seen). Then set verbatim +% catcodes with \cs{@@_grab_v_aux_catcodes:}. +% +% The group keep catcode changes local, and +% \cs{group_align_safe_begin/end:} allow to use a character +% with category code~$4$ (normally |&|) as the delimiter (all commands +% do \cs{group_align_safe_begin/end:}, so there's no need to do that +% again here). +% It is ended by \cs{@@_grab_v_group_end:}, which smuggles +% the collected argument out of the group. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_v:w + { + \bool_set_false:N \l_@@_long_bool + \@@_grab_v_aux:w + } +\cs_new_protected:Npn \@@_grab_v_long:w + { + \bool_set_true:N \l_@@_long_bool + \@@_grab_v_aux:w + } +\cs_new_protected:Npn \@@_grab_v_aux:w #1 \@@_run_code: + { + \tl_set:Nn \l_@@_signature_tl {#1} + \group_begin: + \tex_escapechar:D = 92 \scan_stop: + \tl_clear:N \l_@@_v_arg_tl + \peek_remove_spaces:n + { + \peek_meaning_remove:NTF \c_group_begin_token + { + \group_align_safe_end: + \@@_grab_v_bgroup: + } + { + \peek_N_type:TF + { \@@_grab_v_aux_test:N } + { \@@_grab_v_aux_abort:n { } } + } + } + } +\cs_new_protected:Npn \@@_grab_v_group_end: + { + \exp_args:NNNo + \group_end: + \tl_set:Nn \l_@@_v_arg_tl { \l_@@_v_arg_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_v_aux_test:N} +% \begin{macro} +% { +% \@@_grab_v_aux_loop:N, +% \@@_grab_v_aux_loop:NN, +% \@@_grab_v_aux_loop_end: +% } +% Check that the opening delimiter is a character, setup category codes, +% then start reading tokens one by one, keeping the delimiter as an argument. +% If the verbatim was not nested, we will be grabbing one character +% at each step. Unfortunately, it can happen that what follows the +% verbatim argument is already tokenized. Thus, we check at each step +% that the next token is indeed a \enquote{nice} +% character, \emph{i.e.}, is not a character with +% category code $1$ (begin-group), $2$ (end-group) +% or $6$ (macro parameter), nor the space character, +% with category code~$10$ and character code~$32$, +% nor a control sequence. +% The partially built argument is stored in \cs{l_@@_v_arg_tl}. +% If we ever meet a token which we cannot grab (non-N-type), +% or which is not a character according to +% \cs{@@_grab_v_token_if_char:NTF}, then we bail out with +% \cs{@@_grab_v_aux_abort:n}. Otherwise, we stop at the first +% character matching the delimiter. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_v_aux_test:N #1 + { + \@@_grab_v_token_if_char:NTF #1 + { + \@@_grab_v_aux_put:N #1 + \@@_grab_v_aux_catcodes: + \@@_grab_v_aux_loop:N #1 + } + { \@@_grab_v_aux_abort:n {#1} #1 } + } +\cs_new_protected:Npn \@@_grab_v_aux_loop:N #1 + { + \peek_N_type:TF + { \@@_grab_v_aux_loop:NN #1 } + { \@@_grab_v_aux_abort:n { } } + } +\cs_new_protected:Npn \@@_grab_v_aux_loop:NN #1#2 + { + \@@_grab_v_token_if_char:NTF #2 + { + \token_if_eq_charcode:NNTF #1 #2 + { \@@_grab_v_aux_loop_end: } + { + \@@_grab_v_aux_put:N #2 + \@@_grab_v_aux_loop:N #1 + } + } + { \@@_grab_v_aux_abort:n {#2} #2 } + } +\cs_new_protected:Npn \@@_grab_v_aux_loop_end: + { + \@@_grab_v_group_end: + \@@_add_arg:x { \tl_tail:N \l_@@_v_arg_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\l_@@_v_nesting_int} +% \begin{macrocode} +\int_new:N \l_@@_v_nesting_int +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_grab_v_bgroup:} +% \begin{macro}{\@@_grab_v_bgroup_loop:} +% \begin{macro}{\@@_grab_v_bgroup_loop:N} +% If the opening delimiter is a left brace, we keep track of +% how many left and right braces were encountered so far in +% \cs{l_@@_v_nesting_int} (the methods used for optional +% arguments cannot apply here), and stop as soon as it reaches~$0$. +% +% Some care was needed when removing the opening delimiter, which +% has already been assigned category code~$1$: using +% \cs{peek_meaning_remove:NTF} in the \cs{@@_grab_v_aux:w} +% function would break within alignments. Instead, we first +% convert that token to a string, and remove the result as a +% normal undelimited argument. +% \begin{macrocode} +\cs_new_protected:Npx \@@_grab_v_bgroup: + { + \exp_not:N \@@_grab_v_aux_catcodes: + \exp_not:n { \int_set:Nn \l_@@_v_nesting_int { 1 } } + \exp_not:N \@@_grab_v_aux_put:N \iow_char:N \{ + \exp_not:N \@@_grab_v_bgroup_loop: + } +\cs_new_protected:Npn \@@_grab_v_bgroup_loop: + { + \peek_N_type:TF + { \@@_grab_v_bgroup_loop:N } + { \@@_grab_v_aux_abort:n { } } + } +\cs_new_protected:Npn \@@_grab_v_bgroup_loop:N #1 + { + \@@_grab_v_token_if_char:NTF #1 + { + \token_if_eq_charcode:NNTF \c_group_end_token #1 + { + \int_decr:N \l_@@_v_nesting_int + \int_compare:nNnTF \l_@@_v_nesting_int > 0 + { + \@@_grab_v_aux_put:N #1 + \@@_grab_v_bgroup_loop: + } + { \@@_grab_v_aux_loop_end: } + } + { + \token_if_eq_charcode:NNT \c_group_begin_token #1 + { \int_incr:N \l_@@_v_nesting_int } + \@@_grab_v_aux_put:N #1 + \@@_grab_v_bgroup_loop: + } + } + { \@@_grab_v_aux_abort:n {#1} #1 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_v_aux_catcodes:} +% \begin{macro}{\@@_grab_v_aux_abort:n} +% The approach for short verbatim arguments is to make the end-line +% character a macro parameter character: this is forbidden by the +% rest of the code. Then the error branch can check what caused the +% bail out and give the appropriate error message. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_v_aux_catcodes: + { + \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 } } + } +\cs_new_protected:Npn \@@_grab_v_aux_abort:n #1 + { + \@@_grab_v_group_end: + \exp_after:wN \exp_after:wN \exp_after:wN + \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 } + { + \msg_error:nnxxx { cmd } { verbatim-newline } + { \@@_environment_or_command: } + { \tl_to_str:N \l_@@_v_arg_tl } + { \tl_to_str:n {#1} } + \@@_add_arg:o \c_novalue_tl + } + { + \msg_error:nnxxx { cmd } { verbatim-tokenized } + { \@@_environment_or_command: } + { \tl_to_str:N \l_@@_v_arg_tl } + { \tl_to_str:n {#1} } + \@@_add_arg:o \c_novalue_tl + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_grab_v_aux_put:N} +% Storing one token in the collected argument. Most tokens are +% converted to category code $12$, with the exception of active +% characters, and spaces (not sure what should be done for those). +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_v_aux_put:N #1 + { + \tl_put_right:Nx \l_@@_v_arg_tl + { + \token_if_active:NTF #1 + { \exp_not:N #1 } { \token_to_str:N #1 } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_grab_v_token_if_char:NTF} +% This function assumes that the escape character is printable. +% Then the string representation of control sequences is at least +% two characters, and \cs{str_tail:n} only removes the escape +% character. Macro parameter characters are doubled by +% \cs{tl_to_str:n}, and will also yield a non-empty result, +% hence are not considered as characters. +% \begin{macrocode} +\cs_new_protected:Npn \@@_grab_v_token_if_char:NTF #1 + { \str_if_eq:eeTF { } { \str_tail:n {#1} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_add_arg:n, \@@_add_arg:V, \@@_add_arg:o, \@@_add_arg:x} +% When an argument is found it is stored, then further arguments are +% grabbed by calling \cs{l_@@_signature_tl}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_arg:n #1 + { + \tl_put_right:Nn \l_@@_args_tl { {#1} } + \l_@@_signature_tl \@@_run_code: + } +\cs_generate_variant:Nn \@@_add_arg:n { V , o , x } +% \end{macrocode} +% \end{macro} +% +% \subsection{Grabbing arguments expandably} +% +% \begin{macro}[EXP]{\@@_expandable_grab_D:w} +% \begin{macro}[EXP]{\@@_expandable_grab_D:NNNwNNn} +% \begin{macro}[EXP]{\@@_expandable_grab_D:NNNwNNnnn} +% \begin{macro}[EXP]{\@@_expandable_grab_D:Nw} +% \begin{macro}[EXP]{\@@_expandable_grab_D:nnNNNwNN} +% The first step is to grab the first token or group. The generic grabbers +% \cs{\meta{function}}\verb*| | and \cs{\meta{function}}\verb*| | are just after \cs{q_@@}, we go and find +% them (and use the long one). +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_D:NNNwNNn #1 \q_@@ #2 #3 } } +% \end{macrocode} +% We then wish to test whether |#7|, which we just grabbed, is exactly |#2|. +% A preliminary test is whether their string representations coincide, then +% expand the only grabber function we have, |#1|, once: the two strings below +% are equal if and only if |#7| matches |#2| exactly.\footnote{It is obvious +% that if \texttt{\#7} matches \texttt{\#2} then the strings are equal. We +% must check the converse. The right-hand-side of \cs{str_if_eq:onTF} does +% not end with \texttt{\#3}, implying that the grabber function took +% everything as its arguments. The first brace group can only be empty if +% \texttt{\#7} starts with \texttt{\#2}, otherwise the brace group preceding +% \texttt{\#7} would not vanish. The third brace group is empty, thus the +% \cs{q_@@} that was used by our grabber \texttt{\#1} must be the one +% that we inserted (not some token in \texttt{\#7}), hence the second brace +% group contains the end of \texttt{\#7} followed by \texttt{\#2}. Since this +% is \texttt{\#2} on the right-hand-side, and no brace can be lost there, +% \texttt{\#7} must contain nothing else than its leading \texttt{\#2}.} +% The preliminary test is needed as |#7| could validly contain +% \tn{par} (because a later mandatory argument could be long) and our +% grabber may be short. If +% |#7| does not match |#2|, then the optional argument is missing, we use the +% default |-NoValue-|, and put back the argument |#7| in the input stream. +% +% If it does match, then interesting things need to be done. We will grab the +% argument piece by piece, with the following pattern: +% \begin{quote} +% \meta{grabber} \Arg{tokens} \\ +% ~~\cs{q_nil} \Arg{piece 1} \meta{piece 2} \cs{ERROR} \cs{q_@@}\\ +% ~~\cs{q_nil} \meta{input stream} +% \end{quote} +% The \meta{grabber} will find an opening delimiter in \meta{piece 2}, take +% the \cs{q_@@} as a second delimiter, and find more material delimited +% by the closing delimiter in the \meta{input stream}. We then move the part +% before the opening delimiter from \meta{piece 2} to \meta{piece 1}, and the +% material taken from the \meta{input stream} to the \meta{piece 2}. Thus, +% the argument moves gradually from the \meta{input stream} to the +% \meta{piece 2}, then to the \meta{piece 1} when we have made sure to find +% all opening and closing delimiters. This two-step process ensures that +% nesting works: the number of opening delimiters minus closing delimiters in +% \meta{piece 1} is always equal to the number of closing delimiters in +% \meta{piece 2}. We stop grabbing arguments once the \meta{piece 2} contains +% no opening delimiter any more, hence the balance is reached, and the final +% argument is \meta{piece 1} \meta{piece 2}. +% The indirection via \cs{@@_tmp:w} allows to insert |-NoValue-| expanded. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn \@@_expandable_grab_D:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7 + { + \str_if_eq:nnTF {##2} {##7} + { + \str_if_eq:onTF + { ##1 { } { } ##7 ##2 \q_@@ ##3 } + { { } {##2} { } } + } + { \use_ii:nn } + { + ##1 + { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 } + \q_nil { } ##2 \ERROR \q_@@ \ERROR + } + { ##4 {#1} \q_@@ ##5 ##6 {##7} } + } + } +\exp_args:No \@@_tmp:w { \c_novalue_tl } +% \end{macrocode} +% At this stage, |#7| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1}, +% and we want to concatenate all that, removing \cs{q_nil}, and keeping the +% opening delimiter |#2|. Simply use \cs{use_ii:nn}. Also, |#8| is +% \meta{remainder of piece 2} \cs{ERROR}, and |#9| is \cs{ERROR} \meta{more +% for piece 2}. We concatenate those, replacing the two \cs{ERROR} by the +% closing delimiter |#3|. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_D:NNNwNNnnn #1#2#3#4 \q_@@ #5#6#7#8#9 + { + \exp_args:Nof \@@_expandable_grab_D:nnNNNwNN + { \use_ii:nn #7 #2 } + { \@@_expandable_grab_D:Nw #3 \exp_stop_f: #8 #9 } + #1#2#3 #4 \q_@@ #5 #6 + } +\cs_new:Npn \@@_expandable_grab_D:Nw #1#2 \ERROR \ERROR { #2 #1 } +% \end{macrocode} +% Armed with our two new \meta{pieces}, we are ready to loop. However, we +% must first see if \meta{piece 2} (here |#2|) contains any opening +% delimiter |#4|. Again, we expand |#3|, this time removing its whole output +% with \cs{use_none:nnn}. The test is similar to \cs{tl_if_in:nnTF}. The +% token list is empty if and only if |#2| does not contain the opening +% delimiter. In that case, we are done, and put the argument (from which we +% remove a spurious pair of delimiters coming from how we started the loop). +% Otherwise, we go back to looping with +% \cs{@@_expandable_grab_D:NNNwNNnnn}. The code to deal with brace stripping +% is much the same as for the non-expandable case. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_D:nnNNNwNN #1#2#3#4#5#6 \q_@@ #7#8 + { + \exp_args:No \tl_if_empty:oTF + { #3 { \use_none:nnn } #2 \q_@@ #5 #4 \q_@@ #5 } + { + \tl_if_blank:oTF { \use_none:nn #1#2 } + { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } } + { + \str_if_eq:eeTF + { \exp_not:o { \use_none:nn #1#2 } } + { { \exp_not:o { \use_iii:nnnn #1#2 \q_nil } } } + { \@@_put_arg_expandable:ow { \use_iii:nnn #1#2 } } + { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } } + } + #6 \q_@@ #7 #8 + } + { + #3 + { \@@_expandable_grab_D:NNNwNNnnn #3#4#5#6 \q_@@ #7 #8 } + \q_nil {#1} #2 \ERROR \q_@@ \ERROR + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:w} +% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNNn} +% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nwn} +% When the delimiters are identical, nesting is not possible and a simplified +% approach is used. The test concept here is the same as for the case where +% the delimiters are different but there cannot be any nesting. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_D_alt:NNwNNn #1 \q_@@ #2 #3 } } +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn \@@_expandable_grab_D_alt:NNwNNn ##1##2##3 \q_@@ ##4##5##6 + { + \str_if_eq:nnTF {##6} {##2} + { + \str_if_eq:onTF + { ##1 { } ##6 ##2 ##2 } + { { } ##2 } + } + { \use_ii:nn } + { + ##1 + { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ } + ##6 \ERROR + } + { ##3 {#1} \q_@@ ##4 ##5 {##6} } + } + } +\exp_args:No \@@_tmp:w { \c_novalue_tl } +\cs_new:Npn \@@_expandable_grab_D_alt:NNwn #1#2#3 \q_@@ #4 + { + \tl_if_blank:oTF { \use_none:n #4 } + { \@@_put_arg_expandable:ow { \use_none:n #4 } } + { + \str_if_eq:eeTF + { \exp_not:o { \use_none:n #4 } } + { { \exp_not:o { \use_ii:nnn #4 \q_nil } } } + { \@@_put_arg_expandable:ow { \use_ii:nn #4 } } + { \@@_put_arg_expandable:ow { \use_none:n #4 } } + } + #3 \q_@@ #1 #2 + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_E:w, \@@_expandable_grab_E_long:w} +% \begin{macro}[EXP]{\@@_expandable_grab_E_aux:w} +% \begin{macro}[EXP]{\@@_expandable_grab_E_test:nnw} +% \begin{macro}[EXP]{\@@_expandable_grab_E_loop:nnnNNw} +% \begin{macro}[EXP]{\@@_expandable_grab_E_find:w} +% \begin{macro}[EXP]{\@@_expandable_grab_E_find:nnw} +% \begin{macro}[EXP]{\@@_expandable_grab_E_end:nnw} +% We keep track of long/short by placing the appropriate grabber as +% the third token after \cs{q_@@}; it is eventually removed by the +% \texttt{end:nnw} auxiliary. The \texttt{aux:w} auxiliary will be +% called repeatedly with two arguments: the set +% of pairs \meta{parser} \meta{token}, and the set of arguments found +% so far (initially all |{-NoValue-}|). At each step, grab what +% follows in the input stream then call the \texttt{loop:nnnNNw} +% auxiliary to compare it with each possible embellishment in turn. +% This auxiliary's |#1| is what was found in the input, |#2| collects +% \meta{parser} \meta{token} pairs that did not match, |#3| collects +% the corresponding arguments found previously, |#4| and |#5| is the +% current pair, |#6| is the remaining pairs, |#7| is empty or two +% \cs{q_nil}, and |#8| is the current argument. If none of the pairs +% matched (determined by \cs{quark_if_nil:NTF}) then call the +% \texttt{end} auxiliary to stop looking for embellishments, +% remembering to put what was grabbed in the input back where it +% belongs, and storing the arguments found just before \cs{q_@@}. If +% the current argument |#8| is not |-NoValue-| or if the input |#1| +% does not match |#5| (see \texttt{t}-type arguments below for a +% similar \cs{str_if_eq:onTF} test) then carry on the loop. +% Otherwise, we found a new embellishment: grab the corresponding +% argument in the input using the \texttt{find:w} auxiliary. To avoid +% losing braces around that auxiliary's argument we include a +% space, which will be eliminated in the next loop through +% embellishments. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_E:w #1 \q_@@ #2#3 + { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #3 } +\cs_new:Npn \@@_expandable_grab_E_long:w #1 \q_@@ #2#3 + { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #2 } +\cs_new:Npn \@@_expandable_grab_E_aux:w #1 \q_@@ #2#3#4 + { #2 { \@@_expandable_grab_E_test:nnw #1 \q_@@ #2 #3 #4 } } +\cs_new:Npn \@@_expandable_grab_E_test:nnw #1#2#3 \q_@@ #4#5#6#7 + { + \@@_expandable_grab_E_loop:nnnNNw {#7} { } { } + #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil + #3 \q_@@ #4 #5 #6 + } +\cs_new:Npn \@@_expandable_grab_E_loop:nnnNNw + #1#2#3#4#5#6 \q_nil #7 \q_mark #8 + { + \quark_if_nil:NTF #4 + { \@@_expandable_grab_E_end:nnw {#1} {#3} } + { + \tl_if_novalue:nTF {#8} + { \str_if_eq:onTF { #4 { } #1 #5 } {#5} } + { \use_ii:nn } + { \@@_expandable_grab_E_find:w { #2 #4 #5 #6 } {#3} ~ } + { + \@@_expandable_grab_E_loop:nnnNNw + {#1} { #2 #4 #5 } { #3 {#8} } + #6 \q_nil #7 \q_mark + } + } + } +\cs_new:Npn \@@_expandable_grab_E_find:w #1 \q_@@ #2#3#4 + { #4 { \@@_expandable_grab_E_find:nnw #1 \q_@@ #2 #3 #4 } } +\cs_new:Npn \@@_expandable_grab_E_find:nnw #1#2#3 \q_nil #4 \q_@@ #5#6#7#8 + { \@@_expandable_grab_E_aux:w {#1} { #2 {#8} #3 } #4 \q_@@ #5 #6 #7 } +\cs_new:Npn \@@_expandable_grab_E_end:nnw #1#2#3 \q_@@ #4#5#6 + { #3 #2 \q_@@ #4 #5 {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_m:w, \@@_expandable_grab_m_long:w} +% \begin{macro}[EXP]{\@@_expandable_grab_m_aux:wNn} +% The mandatory case is easy: find the auxiliary after the \cs{q_@@}, +% and use it directly to grab the argument, then correctly position +% the argument before \cs{q_@@}. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_m:w #1 \q_@@ #2#3 + { #3 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } } +\cs_new:Npn \@@_expandable_grab_m_long:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } } +\cs_new:Npn \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2#3#4 + { #1 {#4} \q_@@ #2 #3 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_R:w} +% \begin{macro}[EXP]{\@@_expandable_grab_R_aux:NNNwNNn} +% Much the same as for the \texttt{D}-type argument, with only the lead-off +% function varying. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_R_aux:NNNwNNn #1 \q_@@ #2#3 } } +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7 + { + \str_if_eq:nnTF {##7} {##2} + { + \str_if_eq:onTF + { ##1 { } { } ##7 ##2 \q_@@ ##3 } + { { } {##2} { } } + } + { \use_ii:nn } + { + ##1 + { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 } + \q_nil { } ##2 \ERROR \q_@@ \ERROR + } + { + \msg_expandable_error:nnff { cmd } { missing-required } + { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##5 } } + { \tl_to_str:n {##2} } + ##4 {#1} \q_@@ ##5 ##6 {##7} + } + } + } +\exp_args:No \@@_tmp:w { \c_novalue_tl } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_R_alt:w} +% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNNn} +% When the delimiters are identical, nesting is not possible and a simplified +% approach is used. The test concept here is the same as for the case where +% the delimiters are different. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_R_alt_aux:NNwNNn #1 \q_@@ #2#3 } } +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNNn ##1##2##3 \q_@@ ##4##5##6 + { + \str_if_eq:nnTF {##6} {##2} + { + \str_if_eq:onTF + { ##1 { } ##6 ##2 ##2 } + { { } ##2 } + } + { \use_ii:nn } + { + ##1 + { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ } + ##6 \ERROR + } + { + \msg_expandable_error:nnff { cmd } { missing-required } + { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##4 } } + { \tl_to_str:n {##2} } + ##3 {#1} \q_@@ ##4 ##5 {##6} + } + } + } +\exp_args:No \@@_tmp:w { \c_novalue_tl } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_expandable_grab_t:w} +% \begin{macro}[EXP]{\@@_expandable_grab_t_aux:NNwn} +% As for a \texttt{D}-type argument, here we compare the grabbed tokens using +% the only parser we have in order to work out if |#2| is exactly equal to +% the output of the grabber. +% \begin{macrocode} +\cs_new:Npn \@@_expandable_grab_t:w #1 \q_@@ #2#3 + { #2 { \@@_expandable_grab_t_aux:NNwn #1 \q_@@ #2 #3 } } +\cs_new:Npn \@@_expandable_grab_t_aux:NNwn #1#2#3 \q_@@ #4#5#6 + { + \str_if_eq:onTF { #1 { } #6 #2 } {#2} + { #3 { \BooleanTrue } \q_@@ #4 #5 } + { #3 { \BooleanFalse } \q_@@ #4 #5 {#6} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP] +% {\@@_put_arg_expandable:nw, \@@_put_arg_expandable:ow} +% A useful helper, to store arguments when they are ready. +% \begin{macrocode} +\cs_new:Npn \@@_put_arg_expandable:nw #1#2 \q_@@ { #2 {#1} \q_@@ } +\cs_generate_variant:Nn \@@_put_arg_expandable:nw { o } +% \end{macrocode} +% \end{macro} +% +% \subsection{Argument processors} +% +% \begin{macro}{\@@_bool_reverse:N} +% A simple reversal. +% \begin{macrocode} +\cs_new_protected:Npn \@@_bool_reverse:N #1 + { + \bool_if:NTF #1 + { \tl_set:Nn \ProcessedArgument { \c_false_bool } } + { \tl_set:Nn \ProcessedArgument { \c_true_bool } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\l_@@_split_list_seq, \l_@@_split_list_tl} +% \begin{macro}{\@@_split_list:nn} +% \begin{macro}{\@@_split_list_multi:nn, \@@_split_list_multi:nV} +% \begin{macro}{\@@_split_list_single:Nn} +% Splitting can take place either at a single token or at a longer +% identifier. To deal with single active tokens, a two-part procedure is +% needed. +% \begin{macrocode} +\seq_new:N \l_@@_split_list_seq +\tl_new:N \l_@@_split_list_tl +\cs_new_protected:Npn \@@_split_list:nn #1#2 + { + \tl_if_single:nTF {#1} + { + \token_if_cs:NTF #1 + { \@@_split_list_multi:nn {#1} {#2} } + { \@@_split_list_single:Nn #1 {#2} } + } + { \@@_split_list_multi:nn {#1} {#2} } + } +\cs_new_protected:Npn \@@_split_list_multi:nn #1#2 + { + \seq_set_split:Nnn \l_@@_split_list_seq {#1} {#2} + \tl_clear:N \ProcessedArgument + \seq_map_inline:Nn \l_@@_split_list_seq + { \tl_put_right:Nn \ProcessedArgument { {##1} } } + } +\cs_generate_variant:Nn \@@_split_list_multi:nn { nV } +\group_begin: +\char_set_catcode_active:N \^^@ +\cs_new_protected:Npn \@@_split_list_single:Nn #1#2 + { + \tl_set:Nn \l_@@_split_list_tl {#2} + \group_begin: + \char_set_lccode:nn { `\^^@ } { `#1 } + \tex_lowercase:D + { + \group_end: + \tl_replace_all:Nnn \l_@@_split_list_tl { ^^@ } + } {#1} + \@@_split_list_multi:nV {#1} \l_@@_split_list_tl + } +\group_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{variable} +% +% \begin{macro}{\@@_split_argument:nnn} +% \begin{macro}{\@@_split_argument_aux:nnnn} +% \begin{macro}[EXP]{\@@_split_argument_aux:n} +% \begin{macro}[rEXP]{\@@_split_argument_aux:wn} +% Splitting to a known number of items is a special version of splitting +% a list, in which the limit is hard-coded and where there will always be +% exactly the correct number of output items. An auxiliary function is +% used to save on working out the token list length several times. +% \begin{macrocode} +\cs_new_protected:Npn \@@_split_argument:nnn #1#2#3 + { + \@@_split_list:nn {#2} {#3} + \exp_args:Nf \@@_split_argument_aux:nnnn + { \tl_count:N \ProcessedArgument } + {#1} {#2} {#3} + } +\cs_new_protected:Npn \@@_split_argument_aux:nnnn #1#2#3#4 + { + \int_compare:nNnF {#1} = { #2 + 1 } + { + \int_compare:nNnTF {#1} > { #2 + 1 } + { + \tl_set:Nx \ProcessedArgument + { + \exp_last_unbraced:NnNo + \@@_split_argument_aux:n + { #2 + 1 } + \use_none_delimit_by_q_stop:w + \ProcessedArgument + \q_stop + } + \msg_error:nnxxx { cmd } { split-excess-tokens } + { \tl_to_str:n {#3} } { \int_eval:n { #2 + 1 } } + { \tl_to_str:n {#4} } + } + { + \tl_put_right:Nx \ProcessedArgument + { + \prg_replicate:nn { #2 + 1 - (#1) } + { { \exp_not:V \c_novalue_tl } } + } + } + } + } +% \end{macrocode} +% Auxiliaries to leave exactly the correct number of arguments in +% \cs{ProcessedArgument}. +% \begin{macrocode} +\cs_new:Npn \@@_split_argument_aux:n #1 + { \prg_replicate:nn {#1} { \@@_split_argument_aux:wn } } +\cs_new:Npn \@@_split_argument_aux:wn #1 \use_none_delimit_by_q_stop:w #2 + { + \exp_not:n { {#2} } + #1 + \use_none_delimit_by_q_stop:w + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_trim_spaces:n} +% This one is almost trivial. +% \begin{macrocode} +\cs_new_protected:Npn \@@_trim_spaces:n #1 + { \tl_set:Nx \ProcessedArgument { \tl_trim_spaces:n {#1} } } +% \end{macrocode} +% \end{macro} +% +% \subsection{Access to the argument specification} +% +% \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n} +% \begin{macro}{\@@_get_arg_spec_error_aux:n} +% Provide an informative error when trying to get the argument +% specification of a non-\pkg{xparse} command or environment. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_arg_spec_error:N #1 + { + \bool_set_false:N \l_@@_environment_bool + \tl_set:Nn \l_@@_fn_tl {#1} + \@@_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 } + } +\cs_new_protected:Npn \@@_get_arg_spec_error:n #1 + { + \bool_set_true:N \l_@@_environment_bool + \str_set:Nx \l_@@_environment_str {#1} + \@@_get_arg_spec_error_aux:n + { \cs_if_exist:cTF { \l_@@_environment_str } } + } +\cs_new_protected:Npn \@@_get_arg_spec_error_aux:n #1 + { + #1 + { + \msg_error:nnx { cmd } { non-xparse } + { \@@_environment_or_command: } + } + { + \msg_error:nnx { cmd } { unknown } + { \@@_environment_or_command: } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_get_arg_spec:NTF} +% If the command is not an \pkg{xparse} command, complain. If it is, +% its second \enquote{item} is the argument specification. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3 + { + \__kernel_cmd_if_xparse:NTF #1 + { + \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } } + #2 + } + {#3} + } +% \end{macrocode} +% \end{macro} +% +% Rolling forward from 2020-10-01 is tricky because the entire |ltcmd| +% module is new, but the user-level commands have the same name, so only +% these will clash. To work around that, in |latexrelease| mode we will +% (temporarily) disable \cs{__kernel_chk_if_free_cs:N} for this final +% part of the code, then restore at the end. +% \begin{macrocode} +%\cs_new_eq:NN \@@_chk_if_free_cs:N \__kernel_chk_if_free_cs:N +%\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \use_none:n +% \end{macrocode} +% +% \begin{variable}{\ArgumentSpecification} +% \begin{macrocode} +\tl_new:N \ArgumentSpecification +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_get_arg_spec:N} +% \begin{macro}{\@@_get_arg_spec:n} +% Recovering the argument specification is now trivial. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_arg_spec:N #1 + { + \@@_get_arg_spec:NTF #1 { } + { \@@_get_arg_spec_error:N #1 } + } +\cs_new_protected:Npn \@@_get_arg_spec:n #1 + { + \exp_args:Nc \@@_get_arg_spec:NTF + { environment~ \tl_to_str:n {#1} } + { } + { \@@_get_arg_spec_error:n {#1} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_show_arg_spec:N} +% \begin{macro}{\@@_show_arg_spec:n} +% Showing the argument specification simply means finding it and then +% calling the \cs{tl_show:N} function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_arg_spec:N #1 + { + \@@_get_arg_spec:NTF #1 + { \tl_show:N \ArgumentSpecification } + { \@@_get_arg_spec_error:N #1 } + } +\cs_new_protected:Npn \@@_show_arg_spec:n #1 + { + \exp_args:Nc \@@_get_arg_spec:NTF + { environment~ \tl_to_str:n {#1} } + { \tl_show:N \ArgumentSpecification } + { \@@_get_arg_spec_error:n {#1} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Utilities} +% +% \begin{macro}{\@@_check_definable:nNT, \@@_check_definable_aux:nN} +% Check that a token list is appropriate as a first argument of +% \cs{NewDocumentCommand} and similar functions and otherwise +% produce an error. First trim whitespace to allow for spaces around +% the actual command to be defined. If the result has multiple +% tokens, it is not a valid argument. The single token is a control +% sequence exactly if its string representation has more than one +% character (using \cs{token_to_str:N} rather than \cs{tl_to_str:n} +% to avoid problems with macro parameter characters, and setting +% \cs{tex_escapechar:D} to prevent it from being non-printable). +% Finally, check for an active character: this is done by lowercasing +% the token to fix its character code (arbitrarily to that of~|?|) +% and comparing the result to an active~|?|. Both control sequences +% and active characters are valid arguments, and non-active character +% tokens are not. In all cases, the group opened to keep assignments +% local must be closed. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_definable:nNT #1 + { \tl_trim_spaces_apply:nN {#1} \@@_check_definable_aux:nN } +\group_begin: + \char_set_catcode_active:n { `? } + \cs_new_protected:Npn \@@_check_definable_aux:nN #1#2 + { + \group_begin: + \tl_if_single_token:nTF {#1} + { + \int_set:Nn \tex_escapechar:D { 92 } + \exp_args:Nx \tl_if_empty:nTF + { \exp_args:No \str_tail:n { \token_to_str:N #1 } } + { + \exp_args:Nx \char_set_lccode:nn + { ` \str_head:n {#1} } { `? } + \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { ? } + { \group_end: \use_iii:nnn } + { \group_end: \use_i:nnn } + } + { \group_end: \use_iii:nnn } + } + { \group_end: \use_ii:nnn } + { + \msg_error:nnxx { cmd } { not-definable } + { \tl_to_str:n {#1} } { \token_to_str:N #2 } + } + { + \msg_error:nnxx { cmd } { not-one-token } + { \tl_to_str:n {#1} } { \token_to_str:N #2 } + } + } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_token_if_cs:NTF} +% Based on the definition of \cs{@@_check_definable_aux:nN} above, but +% only checks for an actual control sequence (\emph{i.e.}, +% \cs[no-index]{\meta{anything}}). \cs{tex_escapechar:D} is +% temporarily changed to a known value and then it checks if +% |\string#1| contains more than one character: if it does, it's a +% control sequence. This test differs from \cs{token_if_cs:NTF} for +% example in \verb|\token_if_cs:NTF \c_group_begin_token {T}{F}|, +% where \cs{token_if_cs:NTF} returns false. +% \begin{macrocode} +\cs_new_protected:Npn \@@_token_if_cs:NTF #1 + { + \group_begin: + \int_set:Nn \tex_escapechar:D { 92 } + \exp_args:Nx \tl_if_empty:nTF + { \exp_args:No \str_tail:n { \token_to_str:N #1 } } + { \group_end: \use_ii:nn } + { \group_end: \use_i:nn } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_tl_mapthread_function:NNN, \@@_tl_mapthread_function:nnN} +% \begin{macro}{\@@_tl_mapthread_loop:w} +% Analogue of \cs{seq_mapthread_function:NNN} for token lists. +% \begin{macrocode} +\cs_new:Npn \@@_tl_mapthread_function:NNN #1#2#3 + { + \exp_after:wN \exp_after:wN + \exp_after:wN \@@_tl_mapthread_loop:w + \exp_after:wN \exp_after:wN + \exp_after:wN #3 + \exp_after:wN #1 + \exp_after:wN \q_recursion_tail + \exp_after:wN \q_mark + #2 + \q_recursion_tail + \q_recursion_stop + } +\cs_new:Npn \@@_tl_mapthread_function:nnN #1#2#3 + { + \@@_tl_mapthread_loop:w #3 + #1 \q_recursion_tail \q_mark + #2 \q_recursion_tail \q_recursion_stop + } +\cs_new:Npn \@@_tl_mapthread_loop:w #1#2#3 \q_mark #4 + { + \quark_if_recursion_tail_stop:n {#2} + \quark_if_recursion_tail_stop:n {#4} + #1 {#2} {#4} + \@@_tl_mapthread_loop:w #1#3 \q_mark + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\__kernel_cmd_if_xparse:NTF} +% \changes{v1.0d}{2021/04/19}{Renamed \cs{__cmd_cmd_if_xparse:NTF} to +% \cs{__kernel_cmd_if_xparse:NTF} for cross-module usage} +% \begin{macro}{\@@_cmd_if_xparse_aux:N} +% +% To determine whether the command is an \pkg{xparse} command check +% that its |arg_spec| is empty (this also excludes non-macros) and +% that its |replacement_spec| starts with either +% \cs{@@_start:nNNnnn} (non-expandable command) or +% \cs{@@_start_expandable:nNNNNn} (expandable command) or +% \cs{@@_start_env:nnnnn} (environment). +% +% This conditional is needed in several kernel modules and is +% therefore has a kernel-internal name. +% \begin{macrocode} +\cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1 + { + \exp_args:Nf \str_case_e:nnTF + { + \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 } + { + \exp_last_unbraced:Nf \@@_cmd_if_xparse_aux:w + { \cs_replacement_spec:N #1 } ~ \q_stop + } + } + { + { \token_to_str:N \@@_start:nNNnnn } { } + { \token_to_str:N \@@_start_expandable:nNNNNn } { } + { \token_to_str:N \@@_start_env:nnnnn } { } + } + } +\cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_peek_nonspace:NTF, \@@_peek_nonspace_remove:NTF, \@@_peek_nonspace_aux:nNNTF} +% Collect spaces in a loop, and put the collected spaces back in the +% false branch of a call to \cs{peek_meaning:NTF} or +% \cs{peek_meaning_remove:NTF}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_peek_nonspace:NTF + { \@@_peek_nonspace_aux:nNNTF { } \@@_peek_meaning:NTF } +\cs_new_protected:Npn \@@_peek_nonspace_remove:NTF + { \@@_peek_nonspace_aux:nNNTF { } \@@_peek_meaning_remove:NTF } +\cs_new_protected:Npn \@@_peek_nonspace_aux:nNNTF #1#2#3#4#5 + { + \peek_meaning_remove:NTF \c_space_token + { \@@_peek_nonspace_aux:nNNTF { #1 ~ } #2 #3 {#4} {#5} } + { #2 #3 { #4 } { #5 #1 } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_peek_meaning:NTF, \@@_peek_meaning_remove:NTF} +% \begin{macro}{\@@_peek_cs_check_equal:NNN, \@@_peek_meaning_aux:NNTF, \@@_peek_true_remove:NNw} +% Peek ahead for a token with a given meaning. In case the search +% token is a control sequence, also check that the \meta{csname} is +% the same as the control sequence peeked at. This extra verification +% is necessary when the command is delimited by control sequence tokens +% (as opposed to character tokens), and we want the the exact same +% control sequence to match. +% \begin{macrocode} +\cs_new_protected:Npn \@@_peek_meaning:NTF + { \@@_peek_meaning_aux:NNTF \c_false_bool } +\cs_new_protected:Npn \@@_peek_meaning_remove:NTF + { \@@_peek_meaning_aux:NNTF \c_true_bool } +\cs_new_protected:Npn \@@_peek_meaning_aux:NNTF #1#2#3#4 + { + \tl_set:Nn \l_@@_tmpa_tl {#3} + \tl_set:Nn \l_@@_tmpb_tl {#4} + \peek_meaning:NTF #2 + { + \token_if_eq_meaning:NNTF #2 \c_group_begin_token + { \@@_peek_true_remove:Nw #1 } + { + \@@_token_if_cs:NTF #2 + { \@@_peek_cs_check_equal:NNN #1 #2 } + { \@@_peek_true_remove:Nw #1 } + } + } + { \l_@@_tmpb_tl } + } +\cs_new_protected:Npn \@@_peek_cs_check_equal:NNN #1#2#3 + { + \str_if_eq:nnTF {#2} {#3} + { \@@_peek_true_remove:Nw #1 } + { \l_@@_tmpb_tl } + #3 + } +\cs_new_protected:Npn \@@_peek_true_remove:Nw #1 + { + \bool_if:NTF #1 + { + \tex_afterassignment:D \l_@@_tmpa_tl + \cs_set_eq:NN \@@_tmp:w + } + { \l_@@_tmpa_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{variable}{\c_@@_ignore_def_tl} +% \begin{macrocode} +\tl_const:Nn \c_@@_ignore_def_tl + { \\ \\ LaTeX~will~ignore~this~entire~definition. } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_environment_or_command:} +% Two texts used in several messages. +% \begin{macrocode} +\cs_new:Npn \@@_environment_or_command: + { + \bool_if:NTF \l_@@_environment_bool + { environment ~ ' \l_@@_environment_str ' } + { + command ~ ' + \exp_args:Nf \tl_trim_spaces:n + { \exp_after:wN \token_to_str:N \l_@@_fn_tl } + ' + } + } +% \end{macrocode} +% \end{macro} +% +% Some messages intended as errors when defining commands/environments. +% \begin{macrocode} +\msg_new:nnnn { cmd } { arg-after-body } + { In~the~definition~of~#1,~b~(body)~argument~must~be~last. } + { + The~'body'~argument~type~is~followed~by~'#2'~in~the~argument~ + specification~of~the~#1.~This~is~not~allowed. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { bad-arg-spec } + { Bad~argument~specification~'#2'~for~#1. } + { + The~argument~specification~provided~was~not~valid:~ + one~or~more~mandatory~pieces~of~information~were~missing. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { command-already-defined } + { Command~'#1'~already~defined! } + { + You~have~used~#2~ + with~a~command~that~already~has~a~definition. \\ \\ + The~existing~definition~of~'#1'~will~not~be~altered. + } +\msg_new:nnnn { cmd } { command-not-yet-defined } + { Command ~'#1'~not~yet~defined! } + { + You~have~used~#2~ + with~a~command~that~was~never~defined. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { environment-already-defined } + { Environment~'#1'~already~defined! } + { + You~have~used~\NewDocumentEnvironment + with~an~environment~that~already~has~a~definition. \\ \\ + The~existing~definition~of~'#1'~will~not~be~altered. + } +\msg_new:nnnn { cmd } { environment-not-yet-defined } + { Environment~'#1'~not~yet~defined! } + { + You~have~used~\RenewDocumentEnvironment + with~an~environment~that~was~never~defined. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { expandable-ending-optional } + { + Argument~specification~'#2'~for~expandable~command~'#1'~ + ends~with~optional~argument. + } + { + Expandable~commands~must~have~a~final~mandatory~argument~ + (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~ + argument~with~expandable~commands. + } +\msg_new:nnnn { cmd } { inconsistent-long } + { Inconsistent~long~arguments~for~expandable~command~'#1'. } + { + The~arguments~for~an~expandable~command~must~not~involve~short~ + arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types. + } +\msg_new:nnnn { cmd } { invalid-command-arg } + { Argument~type~'#2'~not~available~for~#1. } + { + The~letter~'#2'~can~only~be~used~in~environment~argument~ + specifications,~not~for~commands. + \\ \\ + LaTeX~will~ignore~this~entire~definition. + } +\msg_new:nnnn { cmd } { invalid-expandable-argument-type } + { Argument~type~'#2'~not~available~for~expandable~command~'#1'. } + { + The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~ + in~an~expandable~command. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { invalid-after-optional-expandably } + { + Argument~type~'#2'~not~available~after~optional~argument~ + for~expandable~command~'#1'. + } + { + The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~ + in~an~expandable~command~after~an~optional~argument. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { non-trailing-obey-spaces } + { Prefix~'!'~used~before~mandatory~argument~'#2'~of~#1. } + { + The~prefix~'!'~can~only~apply~to~trailing~optional~arguments. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { not-definable } + { First~argument~of~'#2'~must~be~a~command. } + { + The~first~argument~of~'#2'~should~be~the~document~command~that~will~ + be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~ + backslash~is~missing? + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { not-one-token } + { First~argument~of~'#2'~must~be~a~command. } + { + The~first~argument~of~'#2'~should~be~the~document~command~that~will~ + be~defined.~The~provided~argument~'#1'~contains~more~than~one~ + token.~Perhaps~a~backslash~is~missing? + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { not-single-token } + { + Argument~delimiter~'#2'~for~the~#1~should~be~ + a~single~non-space~token. + } + { + The~argument~specification~provided~was~not~valid:~in~a~place~ + where~a~single~token~is~required,~LaTeX~found~'#2'. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { forbidden-implicit-group-token } + { Argument~delimiter~'#2'~for~the~#1~is~not~allowed. } + { + The~argument~specification~provided~was~not~valid:~the~implicit~ + #3-group~token~'#2'~is~not~allowed~as~an~argument~delimiter. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { processor-in-expandable } + { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. } + { + The~argument~specification~for~#1~contains~a~processor~function:~ + this~is~only~supported~for~standard~robust~commands. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { too-many-arguments } + { Too~many~arguments~in~argument~specification~'#2'~of~#1. } + { + The~argument~specification~provided~has~more~than~9~arguments.~ + This~cannot~be~implemented. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { two-markers } + { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~#1. } + { + The~argument~specification~provided~has~two~markers~'#2'~applying~ + to~the~same~argument;~these~are~redundant. + } +\msg_new:nnnn { cmd } { unknown-argument-type } + { Unknown~argument~type~'#2'~for~the~#1. } + { + The~letter~'#2'~does~not~specify~a~known~argument~type. + \c_@@_ignore_def_tl + } +\msg_new:nnnn { cmd } { xparse-argument-type } + { Deprecated~argument~type~'#2'~for~the~#1~requires~xparse. } + { + The~letter~'#2'~specifies~a~known~argument~type~that~requires~ + the~xparse~package. + \c_@@_ignore_def_tl + } +% \end{macrocode} +% +% Errors when using commands/environments. The \texttt{if-boolean} +% message is always used in expandable errors. The +% \texttt{loop-in-defaults} and \texttt{missing-required} messages can +% be expandable or not expandable. +% \begin{macrocode} +\msg_new:nnn { cmd } { if-boolean } + { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} } +\msg_new:nnnn { cmd } { loop-in-defaults } + { Defaults~of~#1~have~circular~dependency. } + { + The~default~values~of~two~or~more~arguments~of~the~#1~ + depend~on~each~other~in~a~way~that~cannot~be~resolved. + } +\msg_new:nnnn { cmd } { missing-required } + { Missing~required~argument~for~#1. } + { + The~current~#1~expects~an~argument~starting~with~'#2'.~ + LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed. + } +\msg_new:nnnn { cmd } { non-xparse } + { \str_uppercase:n #1~not~defined~using~xparse. } + { + You~have~asked~for~the~argument~specification~for~the~#1,~ + but~this~was~not~defined~using~xparse. + } +\msg_new:nnnn { cmd } { split-excess-tokens } + { Too~many~'#1'~tokens~when~trying~to~split~argument. } + { + LaTeX~was~asked~to~split~the~input~'#3'~ + at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~ + There~were~too~many~'#1'~tokens. + } +\msg_new:nnnn { cmd } { unknown } + { Unknown~document~#1. } + { + You~have~asked~for~the~argument~specification~for~the~#1,~ + but~it~is~not~defined. + } +\msg_new:nnnn { cmd } { verbatim-newline } + { Verbatim~argument~of~#1~ended~by~end~of~line. } + { + The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~ + but~the~end~ + of~the~current~line~has~been~reached.~You~may~have~forgotten~the~ + closing~delimiter. + \\ \\ + LaTeX~will~ignore~'#2'. + } +\msg_new:nnnn { cmd } { verbatim-tokenized } + { The~verbatim~#1~cannot~be~used~inside~an~argument. } + { + The~#1~takes~a~verbatim~argument.~ + It~may~not~appear~within~the~argument~of~another~function.~ + It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } . + \\ \\ + LaTeX~will~ignore~'#2'. + } +% \end{macrocode} +% +% Intended more for information. +% \begin{macrocode} +\msg_new:nnn { cmd } { define-command } + { + Defining~command~#1~ + with~sig.~'#2'~\msg_line_context:. + } +\msg_new:nnn { cmd } { define-environment } + { + Defining~environment~'#1'~ + with~sig.~'#2'~\msg_line_context:. + } +\msg_new:nnn { cmd } { redefine-command } + { + Redefining~command~#1~ + with~sig.~'#2'~\msg_line_context:. + } +\msg_new:nnn { cmd } { redefine-environment } + { + Redefining~environment~'#1'~ + with~sig.~'#2'~\msg_line_context:. + } +\msg_new:nnn { cmd } { optional-mandatory } + { + Since~the~mandatory~argument~'#1'~has~the~same~delimiter~'#2'~ + as~a~previous~optional~argument,~it~will~not~be~possible~to~ + omit~all~optional~arguments~when~calling~this~command. + } +\msg_new:nnn { cmd } { unsupported-let } + { + The~command~'#1'~was~undefined~but~not~the~associated~commands~ + '#1~code'~and/or~'#1~defaults'.~Maybe~you~tried~using~ + \iow_char:N\\let.~This~may~lead~to~an~infinite~loop. + } +% \end{macrocode} +% +% \subsection{User functions} +% +% The user functions are more or less just the internal functions +% renamed. +% +% \begin{macro}{\BooleanFalse} +% \begin{macro}{\BooleanTrue} +% Design-space names for the Boolean values. +% \begin{macrocode} +\cs_new_eq:NN \BooleanFalse \c_false_bool +\cs_new_eq:NN \BooleanTrue \c_true_bool +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\NewDocumentCommand} +% \begin{macro}{\RenewDocumentCommand} +% \begin{macro}{\ProvideDocumentCommand} +% \begin{macro}{\DeclareDocumentCommand} +% The user macros are pretty simple wrappers around the internal ones. +% There is however a check that the first argument is a single token, +% possibly surrounded by spaces (hence the strange \cs{use:nnn}), and +% is definable. +% \begin{macrocode} +\cs_new_protected:Npn \NewDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \NewDocumentCommand + { + \cs_if_exist:NTF #1 + { + \msg_error:nnxx { cmd } { command-already-defined } + { \use:nnn \token_to_str:N #1 { } } + { \token_to_str:N \NewDocumentCommand } + } + { \@@_declare_cmd:Nnn #1 {#2} {#3} } + } + } +\cs_new_protected:Npn \RenewDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \RenewDocumentCommand + { + \cs_if_exist:NTF #1 + { \@@_declare_cmd:Nnn #1 {#2} {#3} } + { + \msg_error:nnxx { cmd } { command-not-yet-defined } + { \use:nnn \token_to_str:N #1 { } } + { \token_to_str:N \RenewDocumentCommand } + } + } + } +\cs_new_protected:Npn \ProvideDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \ProvideDocumentCommand + { \cs_if_exist:NF #1 { \@@_declare_cmd:Nnn #1 {#2} {#3} } } + } +\cs_new_protected:Npn \DeclareDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \DeclareDocumentCommand + { \@@_declare_cmd:Nnn #1 {#2} {#3} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\NewDocumentEnvironment} +% \begin{macro}{\RenewDocumentEnvironment} +% \begin{macro}{\ProvideDocumentEnvironment} +% \begin{macro}{\DeclareDocumentEnvironment} +% Very similar for environments. +% \begin{macrocode} +\cs_new_protected:Npn \NewDocumentEnvironment #1#2#3#4 + { + \cs_if_exist:cTF {#1} + { \msg_error:nnx { cmd } { environment-already-defined } {#1} } + { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } + } +\cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4 + { + \cs_if_exist:cTF {#1} + { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } + { \msg_error:nnx { cmd } { environment-not-yet-defined } {#1} } + } +\cs_new_protected:Npn \ProvideDocumentEnvironment #1#2#3#4 + { \cs_if_exist:cF {#1} { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } } +\cs_new_protected:Npn \DeclareDocumentEnvironment #1#2#3#4 + { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\NewExpandableDocumentCommand} +% \begin{macro}{\RenewExpandableDocumentCommand} +% \begin{macro}{\ProvideExpandableDocumentCommand} +% \begin{macro}{\DeclareExpandableDocumentCommand} +% The expandable versions are essentially the same as the basic +% functions. The strange \cs{use:nnn} is there in case |#1| is +% surrounded with spaces, as can happen with usual document catcodes +% in \cs{RenewExpandableDocumentCommand} |{| |\!| |}| \ldots{} +% \begin{macrocode} +\cs_new_protected:Npn \NewExpandableDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \NewExpandableDocumentCommand + { + \cs_if_exist:NTF #1 + { + \msg_error:nnxx { cmd } { command-already-defined } + { \use:nnn \token_to_str:N #1 { } } + { \token_to_str:N \NewExpandableDocumentCommand } + } + { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + } + } +\cs_new_protected:Npn \RenewExpandableDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \RenewExpandableDocumentCommand + { + \cs_if_exist:NTF #1 + { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + { + \msg_error:nnxx { cmd } { command-not-yet-defined } + { \use:nnn \token_to_str:N #1 { } } + { \token_to_str:N \RenewExpandableDocumentCommand } + } + } + } +\cs_new_protected:Npn \ProvideExpandableDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \ProvideExpandableDocumentCommand + { + \cs_if_exist:NF #1 + { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + } + } +\cs_new_protected:Npn \DeclareExpandableDocumentCommand #1#2#3 + { + \@@_check_definable:nNT {#1} \DeclareExpandableDocumentCommand + { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\IfBooleanT, \IfBooleanF, \IfBooleanTF} +% The logical \meta{true} and \meta{false} statements are just the +% normal \cs{c_true_bool} and \cs{c_false_bool} so \cs{bool_if:NTF} is +% almost enough. However, this code-level function blows up badly +% when passed invalid input. We want \cs{IfBooleanTF} to accept a +% single (non-space) token equal to \cs{c_true_bool} or +% \cs{c_false_bool}, possibly surrounded by spaces. If the input is +% blank or multiple items, jump to the error and pick the false +% branch. If the input, ignoring spaces (we do this by omitting +% braces in the \cs{tl_if_single_token:nF} test), is not a single +% token then jump to the error as well. It is then safe to compare +% the token to the two booleans, picking the appropriate branch. If +% neither matches, we jump to the error as well. +% \begin{macrocode} +\cs_new:Npn \IfBooleanTF #1 + { + \tl_if_single:nF {#1} + { \prg_break:n { \use:n } } + \tl_if_single_token:nF #1 + { \prg_break:n { \use:n } } + \token_if_eq_meaning:NNT #1 \c_true_bool + { \prg_break:n { \use_ii:nnn } } + \token_if_eq_meaning:NNT #1 \c_false_bool + { \prg_break:n { \use_iii:nnn } } + \prg_break:n { \use:n } + \prg_break_point: + { + \msg_expandable_error:nnn { cmd } { if-boolean } {#1} + \use_ii:nn + } + } +\cs_new:Npn \IfBooleanT #1#2 { \IfBooleanTF {#1} {#2} { } } +\cs_new:Npn \IfBooleanF #1 { \IfBooleanTF {#1} { } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IfNoValueT, \IfNoValueF, \IfNoValueTF} +% Simple re-naming. +% \begin{macrocode} +\cs_new_eq:NN \IfNoValueF \tl_if_novalue:nF +\cs_new_eq:NN \IfNoValueT \tl_if_novalue:nT +\cs_new_eq:NN \IfNoValueTF \tl_if_novalue:nTF +% \end{macrocode} +% \end{macro} +% \begin{macro}{\IfValueT, \IfValueF, \IfValueTF} +% Inverted logic. +% \begin{macrocode} +\cs_new:Npn \IfValueF { \tl_if_novalue:nT } +\cs_new:Npn \IfValueT { \tl_if_novalue:nF } +\cs_new:Npn \IfValueTF #1#2#3 { \tl_if_novalue:nTF {#1} {#3} {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ProcessedArgument} +% Processed arguments are returned using this name, which is reserved +% here although the definition will change. +% \begin{macrocode} +\tl_new:N \ProcessedArgument +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ReverseBoolean, \SplitArgument, \SplitList, \TrimSpaces} +% Simple copies. +% \begin{macrocode} +\cs_new_eq:NN \ReverseBoolean \@@_bool_reverse:N +\cs_new_eq:NN \SplitArgument \@@_split_argument:nnn +\cs_new_eq:NN \SplitList \@@_split_list:nn +\cs_new_eq:NN \TrimSpaces \@@_trim_spaces:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ProcessList} +% To support \cs{SplitList}. +% \begin{macrocode} +\cs_new_eq:NN \ProcessList \tl_map_function:nN +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GetDocumentCommandArgSpec} +% \begin{macro}{\GetDocumentEnvironmentArgSpec} +% \begin{macro}{\ShowDocumentCommandArgSpec} +% \begin{macro}{\ShowDocumentEnvironmentArgSpec} +% More simple mappings, with a check that the argument is a single +% control sequence or active character. +% \begin{macrocode} +\cs_new_protected:Npn \GetDocumentCommandArgSpec #1 + { + \@@_check_definable:nNT {#1} \GetDocumentCommandArgSpec + { \@@_get_arg_spec:N #1 } + } +\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \@@_get_arg_spec:n +\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1 + { + \@@_check_definable:nNT {#1} \ShowDocumentCommandArgSpec + { \@@_show_arg_spec:N #1 } + } +\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \@@_show_arg_spec:n +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Finally as promised, restore \cs{__kernel_chk_if_free_cs:N}: +% \begin{macrocode} +%\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \@@_chk_if_free_cs:N +%\cs_undefine:N \@@_chk_if_free_cs:N +% \end{macrocode} +% +% \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}{ltcmd}% +% {Document~command~parser}% +% +%\EndModuleRelease +\ExplSyntaxOff +%\@ifundefined{ExplSyntaxOff}{}{\latexrelease@postexpl} +%\catcode`\^^@=\@latexrelease@catcode@null\relax +% +% \end{macrocode} +% +% We need to stop DocStrip treating |@@| in a special way at this point. +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \Finale diff --git a/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx new file mode 100644 index 00000000000..40cd55e52c7 --- /dev/null +++ b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx @@ -0,0 +1,1094 @@ +% \iffalse meta-comment +% +%% File: ltcmdhooks.dtx (C) Copyright 2020-2021 +%% Frank Mittelbach, Phelype Oleinik, LaTeX Team +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +%%% From File: ltcmdhooks.dtx +% +\def\ltcmdhooksversion{v1.0b} +\def\ltcmdhooksdate{2021/05/26} +% +% +% +%<*driver> +\documentclass{l3doc} +%\usepackage{ltcmdhooks} +\makeatletter +\providecommand\footref[1]{% + \begingroup + \unrestored@protected@xdef\@thefnmark{\ref{#1}}% + \endgroup + \@footnotemark} +\makeatother +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltcmdhooks.dtx} +\end{document} +% +% +% \fi +% +% +% \providecommand\hook[1]{\texttt{#1}} +% \providecommand\fmi[1]{\marginpar{\footnotesize FMi: #1}} +% \providecommand\pho[1]{\marginpar{\footnotesize PhO: #1}} +% \providecommand\phoinline[1]{\begin{quote}\itshape\footnotesize PhO: #1\end{quote}} +% +% \title{The \texttt{ltcmdhooks} module\thanks{This file has version +% \ltcmdhooksversion\ dated \ltcmdhooksdate, \copyright\ \LaTeX\ +% Project.}} +% \author{Frank Mittelbach \and Phelype Oleinik} +% +% \maketitle +% +% +% \tableofcontents +% +% +% \section{Introduction} +% +% 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 +% 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 +% \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}. +% +% \item[\hook{cmd/\meta{name}/after}] +% +% This hook is similar to \hook{cmd/\meta{name}/before}, but it is +% executed at the very end of the command body. This hook is +% implemented as a reversed hook. +% \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 +% example, if we have the following definition +%\begin{verbatim} +% \newcommand\foo[2]{Code #1 for #2!} +%\end{verbatim} +% then executing \verb=\foo{A}{B}= will simply run +% \verb*=Code A for B!= +% as it was always the case. However, if somebody, somewhere (e.g., +% in a package) adds +%\begin{verbatim} +% \AddToHook{cmd/foo/before}{} +%\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!} +%\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}} +%\end{verbatim} +% +% In other words, the mechanism is similar to what \pkg{etoolbox} +% offers with \tn{pretocmd} and \tn{apptocmd} with the important +% 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 +% +% \item +% +% and that by using the hook management interface it is now +% possible to define how the code chunks added in these places +% are ordered, if different packages want to add code at these +% points. +% +% \end{itemize} +% +% +% +% +% \section{Restrictions and Operational details} +% \label{sec:restrictions} +% +% Adding arbitrary material to commands is tricky because most of the +% time we do not know what the macro expects as arguments when expanding +% and \TeX{} doesn't have a reliable way to see that, so some guesswork +% has to be employed. +% +% \subsection{Patching} +% +% The code here tries to find out if a command was defined with +% \tn{newcommand} or \tn{DeclareRobustCommand} or +% \tn{NewDocumentCommand}, and if so it \emph{assumes} that the argument +% specification of the command is as expected (which is not fail-proof, +% if someone redefines the internals of these commands in devious ways, +% but is a reasonable assumption). +% +% If the command is one of the defined types, the code here does a +% sandboxed expansion of the command such that it can be redefined again +% exactly as before, but with the hook code added. +% +% If however the command is not a known type (it was defined with +% \tn{def}, for example), then the code uses an approach similar to +% \pkg{etoolbox}'s \tn{patchcmd} to retokenize the command with the hook +% code in place. This procedure, however, is more likely to fail if the +% catcode settings are not the same as the ones at the time of command's +% definition, so not always adding a hook to a command will work. +% +% \subsubsection{Timing} +% +% When \cs{AddToHook} (or its \pkg{expl3} equivalent) is called with +% a generic |cmd| hook, say, \hook{cmd/foo/before}, for the first time +% (that is, no code was added to that same hook before), in the preamble +% of a document, it will store a patch instruction for that command +% until |\begin{document}|, and only then all the commands which had +% hooks added will be patched in one go. That means that no command in +% the preamble will have hooks patched into them. +% +% At |\begin{document}| all the delayed patches will be executed, and +% if the command doesn't exist the code is still added to the hook, +% but it will not be executed. After |\begin{document}|, when +% \cs{AddToHook} is called with a generic |cmd| hook the first time, +% the command will be immediately patched to include the hook, and if +% it doesn't exist or if it can't be patched for any reason, an error +% is thrown; if \cs{AddToHook} was already used in the preamble no new +% patching is attempted. +% +% This has the consequence that a command defined or redefined after +% |\begin{document}| only uses generic |cmd| hook code if +% \cs{AddToHook} is called for the first time after the definition is +% made, or if the command explicitly uses the generic hook in its +% definition by declaring it with \cs{NewHookPair} adding \cs{UseHook} as +% part of the code.\footnote{We might change this behavior in the main +% document slightly after gaining some usage experience.} +% +% +% \subsection{Commands that look ahead} +% \label{sec:look-ahead} +% +% Some commands are defined in different ``steps'' and they look ahead +% in the input stream to find more arguments. If you try to add some +% code to the \hook{cmd/\meta{name}/after} hook of such command, it will +% not work, and it is not possible to detect that programmatically, so +% the user has to know (or find out) which commands can or cannot have +% hooks attached to them. +% +% One good example is the \tn{section} command. You can add something +% to the \hook{cmd/section/before} hook, but if you try to add something +% to the \hook{cmd/section/after} hook, \tn{section} will no longer +% work. That happens because the \tn{section} macro takes no argument, +% but instead calls a few internal \LaTeX{} macros to look for the +% optional and mandatory arguments. By adding code to the +% \hook{cmd/section/after} hook, you get in the way of that scanning. +% +% +% +% \section{Package Author Interface} +% +% The \hook{cmd} hooks are, by default, available for all commands +% that can be patched to add the hooks. For some commands, however, +% the very beginning or the very end of the code is not the best place +% to put the hooks, for example, if the command looks ahead for +% arguments (see section~\ref{sec:look-ahead}). +% +% 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, +% 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 +% given in parentheses: +% \begin{verbatim} +% \newcommand\fancybox{\@ifnextchar({\@fancybox}{\@fancybox(5cm)}} +% \def\@fancybox(#1)#2{\fbox{\parbox{#1}{#2}}} +% \end{verbatim} +% If you try that definition, then add some code after it with +% \begin{verbatim} +% \AddToHook{cmd/fancybox/after}{} +% \end{verbatim} +% and then use the \cs[no-index]{fancybox} command you will see that it +% will be completely broken, because the hook will get executed in the +% middle of parsing for optional \texttt{(...)} argument. +% +% If, on the other hand, you want to add hooks to your command you can +% do something like: +% \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} +% \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 +% 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 +% 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 +% 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 +% \cs{NewHook} and never use it. +% +% +% The above approach is useful for really complex commands where for +% one or the other reason the hooks can't be placed at the very +% beginning and end of the command body and some hand-crafting is +% needed. However, in the example above the real (and in fact only) +% issue is the cascading argument parsing in the style developed long +% ago in \LaTeX~2.09. Thus, a much simpler solution for this case is +% to replace it with the modern \cs{NewDocumentCommand} syntax and +% define the command as follows: +% \begin{verbatim} +% \DeclareDocumentCommand\fancybox{D(){5cm}m}{\fbox{\parbox{#1}{#2}}} +% \end{verbatim} +% If you do that then both hooks automatically work and are patched +% into the right places. +% +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% +% \section{The Implementation} +% +% \subsection{Execution plan} +% +% To add |before| and |after| hooks to a command we will need to peek +% into the definition of a command, which is always a tricky thing to +% do. Some cases are easy because we know how the command was defined, +% so we can assume how its \meta{parameter text} looks like (for example +% a command defined with \tn{newcommand} may have an optional argument +% followed by a run of mandatory arguments), so we can just expand that +% command and make it grab |#1|, |#2|, etc.\@ as arguments and +% define it all back with the hooks added. +% +% Life's usually not that easy, so with some commands we can't do that +% (a |#1| might as well be |#|$_{12}$|1|$_{12}$ instead of the expected +% |#|$_{6}$|1|$_{12}$, for example) so we need to resort to ``patching'' +% the command: read its \tn{meaning}, and tokenize it again with +% \tn{scantokens} and hope for the best. +% +% So the overall plan is: +% \begin{enumerate} +% \item +% Check if a command is of a known type (that is, defined with +% \tn{newcommand}\footnote{It's not always possible to reliably +% detect this case because a command defined with no optional +% argument is indistinguishable from a \tn{def}ed command.}, +% \cs[no-index]{DeclareRobustCommand}, or +% \cs[no-index]{New(Expandable)DocumentCommand}), and if is, take +% appropriate action. +% \item +% If the command is not a known type, we'll check if the command can +% be patched. Two things will prevent a command from being +% patched: if it was defined in a nonstandard catcode setting, or +% if it is an internal expl3 command with |__|\meta{module} in its +% name, in which case we refuse to patch. +% \item +% If the command was defined in nonstandard catcode settings, we +% will try a few standard ones to try our best to carry out the +% pathing. If this doesn't help either, the code will give up and +% throw an error. +% \end{enumerate} +% +% +% \begin{macrocode} +%<@@=hook> +% \end{macrocode} +% +% \changes{v1.0b}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +\ExplSyntaxOn +%\NewModuleRelease{2021/06/01}{ltcmdhooks} +% {The~hook~management~system~for~commands} +% \end{macrocode} +% +% \subsection{Variables} +% +% \begin{macro}[int]{\g_hook_patch_action_list_tl} +% Pairs of |\if..\patch| to be used with +% \tn{robust@command@act} when looking for a known patching +% rule. This token list is exposed because we see some future +% applications (with very specialized packages, such as +% \pkg{etoolbox} that may want to extend the pairs processed. It is +% not meant for general use which is why it is not documented in +% the interface documentation above. +% \begin{macrocode} +\tl_new:N \g_hook_patch_action_list_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_@@_patch_num_args_int} +% The number of arguments in a macro being patched. +% \begin{macrocode} +\int_new:N \l_@@_patch_num_args_int +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\l_@@_patch_prefixes_tl} +% \begin{macro}{\l_@@_patch_param_text_tl} +% \begin{macro}{\l_@@_patch_replacement_tl} +% The prefixes and parameters of the definition for the macro being +% patched. +% \begin{macrocode} +\tl_new:N \l_@@_patch_prefixes_tl +\tl_new:N \l_@@_patch_param_text_tl +\tl_new:N \l_@@_patch_replacement_tl +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\g_@@_delayed_patches_prop} +% A list containing the patches delayed to |\begin{document}|, so that +% patching is not attempted twice. +% \begin{macrocode} +\prop_new:N \g_@@_delayed_patches_prop +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_debug:x} +% A helper for patching debug info. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_debug:x #1 + { \@@_debug:n { \iow_term:x { [lthooks]~#1 } } } +% \end{macrocode} +% \end{macro} +% +% \subsection{Variants} +% +% \begin{macro}[int]{\tl_rescan:nV} +% \pkg{expl3} function variants used throughout the code. +% \begin{macrocode} +\cs_generate_variant:Nn \tl_rescan:nn { nV } +% \end{macrocode} +% \end{macro} +% +% \subsection{Patching or delaying} +% +% \begin{macro}{\@@_try_put_cmd_hook:n,\@@_try_put_cmd_hook:w} +% Before |\begin{document}| all patching is delayed. +% This function is called from within \cs{AddToHook}, when code is +% added to a generic |cmd| hook is newly declared. It checks whether +% the patch position is valid, then proceeds to trying to patch or +% delaying to |\begin{document}| if in the preamble. +% \begin{macrocode} +\cs_new_protected:Npn \@@_try_put_cmd_hook:n #1 + { \@@_try_put_cmd_hook:w #1 / / / \s_@@_mark {#1} } +\cs_new_protected:Npn \@@_try_put_cmd_hook:w + #1 / #2 / #3 / #4 \s_@@_mark #5 + { + \@@_debug:n { \iow_term:n { ->~Adding~cmd~hook~to~'#2'~(#3): } } + \str_case:nnTF {#3} + { { before } { } { after } { } } + { \exp_args:Nc \@@_patch_cmd_or_delay:Nnn {#2} {#2} {#3} } + { \msg_error:nnnn { hooks } { wrong-cmd-hook } {#2} {#3} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_patch_cmd_or_delay:Nnn} +% \begin{macro}{\@@_cmd_begindocument_code:} +% In the preamble, \cs{@@_patch_cmd_or_delay:Nnn} just adds the patch +% instruction to a property list to be executed later. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_cmd_or_delay:Nnn #1 #2 #3 + { + \@@_debug:n { \iow_term:n { ->~Add~generic~cmd~hook~for~#2~(#3). } } + \@@_debug:n + { \iow_term:n { !~In~the~preamble:~delaying. } } + \prop_gput:Nnn \g_@@_delayed_patches_prop { #2 / #3 } + { \@@_cmd_try_patch:nn {#2} {#3} } + } +% \end{macrocode} +% +% The delayed patches are added to a property list to prevent +% duplication, and the code stored in the property list for each +% key is executed. The function \cs{@@_patch_cmd_or_delay:Nnn} is +% also redefined to be \cs{@@_patch_command:Nnn} so that no further +% delaying is attempted. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cmd_begindocument_code: + { + \cs_gset_eq:NN \@@_patch_cmd_or_delay:Nnn \@@_patch_command:Nnn + \prop_map_function:NN \g_@@_delayed_patches_prop { \use_ii:nn } + \prop_gclear:N \g_@@_delayed_patches_prop + \cs_undefine:N \@@_cmd_begindocument_code: + } +\g@addto@macro \@kernel@after@begindocument + { \@@_cmd_begindocument_code: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_cmd_try_patch:nn} +% At |\begin{document}| tries patching the command if the hook +% was not manually created in the meantime. If the document does not +% exist, no error is raised here as it may hook into a package that +% wasn't loaded. Hooks added to commands in the document body still +% raise an error if the command is not defined. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cmd_try_patch:nn #1 #2 + { + \@@_debug:n + { \iow_term:x { ->~\string\begin{document}~try~cmd / #1 / #2. } } + \@@_if_declared:nTF { cmd / #1 / #2 } + { + \@@_debug:n + { \iow_term:n { .->~Giving~up:~hook~already~created. } } + } + { + \cs_if_exist:cT {#1} + { \exp_args:Nc \@@_patch_command:Nnn {#1} {#1} {#2} } + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Patching commands} +% +% \begin{macro}{\@@_patch_command:Nnn} +% \begin{macro}{\@@_patch_check:NNnn} +% \begin{macro}[TF]{\@@_if_public_command:N} +% \begin{macro}{\@@_if_public_command:w} +% \cs{@@_patch_command:Nnn} will do some sanity checks on the +% argument to detect if it is possible to add hooks to the command, +% and raises an error otherwise. If the command can contain hooks, +% then it uses \tn{robust@command@act} to find out what type is the +% command, and patch it accordingly. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_command:Nnn #1 #2 #3 + { + \@@_patch_debug:x { analyzing~'\token_to_str:N #1' } + \@@_patch_debug:x { \token_to_str:N #1 = \token_to_meaning:N #1 } + \@@_patch_check:NNnn \cs_if_exist:NTF #1 { undef } + { + \@@_patch_debug:x { ++~control~sequence~is~defined } + \@@_patch_check:NNnn \token_if_macro:NTF #1 { macro } + { + \@@_patch_debug:x { ++~control~sequence~is~a~macro } + \@@_patch_check:NNnn \@@_if_public_command:NTF #1 { expl3 } + { + \@@_patch_debug:x { ++~macro~is~not~private } + \robust@command@act + \g_hook_patch_action_list_tl #1 + \@@_retokenize_patch:Nnn { #1 {#2} {#3} } + } + } + } + } +% \end{macrocode} +% +% And here's the auxiliary used above: +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_check:NNnn #1 #2 #3 #4 + { + #1 #2 {#4} + { + \msg_error:nnxx { hooks } { cant-patch } + { \token_to_str:N #2 } {#3} + } + } +% \end{macrocode} +% and a conditional \cs{@@_if_public_command:N} to check if a command +% has |__| in its name (no other checking is performed). Primitives +% with |:D| in their name could be included here, but they are already +% discarded in the \cs{token_if_macro:NTF} test above. +% \begin{macrocode} +\use:x + { + \prg_new_protected_conditional:Npnn + \exp_not:N \@@_if_public_command:N ##1 { TF } + { + \exp_not:N \exp_last_unbraced:Nf + \exp_not:N \@@_if_public_command:w + { \exp_not:N \cs_to_str:N ##1 } + \tl_to_str:n { _ _ } \s_@@_mark + } + } +\exp_last_unbraced:NNNNo +\cs_new_protected:Npn \@@_if_public_command:w + #1 \tl_to_str:n { _ _ } #2 \s_@@_mark + { + \tl_if_empty:nTF {#2} + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% +% \subsubsection{Patching by expansion and redefinition} +% +% \begin{macro}[int]{\g_hook_patch_action_list_tl} +% This is the list of known command types and the function that +% patches the command hooks into them. The conditionals are taken +% from \tn{ShowCommand}, \tn{NewCommandCopy} and +% \cs{__kernel_cmd_if_xparse:NTF} defined in \texttt{ltcmd}. +% \begin{macrocode} +\tl_gset:Nn \g_hook_patch_action_list_tl + { + { \@if@DeclareRobustCommand \@@_patch_DeclareRobustCommand:Nnn } + { \@if@newcommand \@@_patch_newcommand:Nnn } + { \__kernel_cmd_if_xparse:NTF \@@_cmd_patch_xparse:Nnn } + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\@@_patch_DeclareRobustCommand:Nnn} +% At this point we know that the commands can be patched by expanding +% then redefining. These are the cases of commands defined with +% \tn{newcommand} with an optional argument or with +% \tn{DeclareRobustCommand}. +% +% With \cs{@@_patch_DeclareRobustCommand:Nnn} we check if the command +% has an optional argument (with a test counter-intuitively called +% \tn{@if@newcommand}). If so, we forward the action to +% \cs{@@_patch_newcommand:Nnn}, otherwise call the patching engine +% \cs{@@_patch_expand_redefine:NNnn} with a \cs{c_false_bool} to +% indicate that there is no optional argument. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_DeclareRobustCommand:Nnn #1 + { + \exp_args:Nc \@if@newcommand { \cs_to_str:N #1 ~ } + { \exp_args:Nc \@@_patch_newcommand:Nnn } + { \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_false_bool } + { \cs_to_str:N #1 ~ } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_patch_newcommand:Nnn} +% If the command was defined with \tn{newcommand} and an optional +% argument, call the patching engine with a \cs{c_true_bool} to flag +% the presence of an optional argument, and with +% \cs[no-index]{\string\command} to patch the actual code for +% \cs[no-index]{command}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_newcommand:Nnn #1 + { + \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_true_bool + { \c_backslash_str \cs_to_str:N #1 } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_cmd_patch_xparse:Nnn} +% And for commands defined by the \pkg{xparse} commands use this +% for patching: +% \begin{macrocode} +\cs_new_protected:Npn \@@_cmd_patch_xparse:Nnn #1 + { + \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_false_bool + { \cs_to_str:N #1 ~ code } + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\@@_patch_expand_redefine:NNnn} +% \begin{macro}[EXP]{\@@_make_prefixes:w} +% Now the real action begins. Here we have in |#1| a boolean +% indicating if the command has a |[|\ldots|]|-delimited argument, in +% |#2| the command control sequence, in |#3| the name of the command +% (note that |#1|${}\ne{}$|\csname#2\endcsname| at this point!), and +% in |#4| the hook position, either |before| or |after|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4 + { + \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } +% \end{macrocode} +% We'll start by counting the number of arguments in the command by +% counting the number of characters in the \cs{cs_argument_spec:N} of +% the macro, divided by two, and subtracting one if the command has an +% optional argument (that is, an extra |[]| in its +% \meta{parameter text}). +% \begin{macrocode} + \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 } + } +% \end{macrocode} +% Now build two token lists: +% \begin{description} +% \item[\cs{l_@@_patch_param_text_tl}] will contain the +% \meta{parameter text} to be used when redefining the macro. It +% should be identical to the \meta{parameter text} used when +% originally defining that macro. +% \item[\cs{l_@@_patch_replacement_tl}] will contain braced pairs of +% |#|$_{12}$\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} +% \begin{macrocode} + \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } + { + \tl_set:Nx \l_@@_patch_param_text_tl + { \bool_if:NTF #1 { [####1] } { ####1 } } + \tl_set:Nx \l_@@_patch_replacement_tl + { \bool_if:NTF #1 { [####1] } { {####1} } } + \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } + { + \tl_put_right:Nn \l_@@_patch_param_text_tl { ## ####1 } + \tl_put_right:Nn \l_@@_patch_replacement_tl { { ## ####1 } } + } + } + { + \tl_clear:N \l_@@_patch_param_text_tl + \tl_clear:N \l_@@_patch_replacement_tl + } +% \end{macrocode} +% Finally, before redefining, we need to also get the prefixes used +% when defining the command. Here we ensure that the \tn{escapechar} +% is printable, otherwise a macro defined with prefixes +% |\protected \long| will have it \tn{meaning} printed as +% |protectedlong|, making life unnecessarily complicated. Here the +% \tn{escapechar} is changed to |/|, then we loop between pairs of +% |/|\ldots|/| extracting the prefixes. +% \begin{macrocode} + \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 / / } + } +% \end{macrocode} +% Now that all the needed tools are ready, without further ado we'll +% redefine the command |#2|. The definition uses the prefixes +% gathered in \cs{l_@@_patch_prefixes_tl}, a primitive \cs{tex_def:D} +% to avoid adding extra prefixes, and the \meta{parameter text} from +% \cs{l_@@_patch_param_text_tl}. +% +% Then finally, in the body of the definition, we insert +% \hook{cmd/\#3/before} if |#4| is |before|, the code of the +% command expanded once grabbing the parameters in +% \cs{l_@@_patch_replacement_tl}, and \hook{cmd/\#3/after} if |#4| is +% |after|. +% \begin{macrocode} + \use:x + { + \l_@@_patch_prefixes_tl \tex_def:D + \exp_not:N #2 \exp_not:V \l_@@_patch_param_text_tl + { + \str_if_eq:nnT {#4} { before } + { \exp_not:N \UseHook { cmd / #3 / #4 } } + \exp_args:No \exp_not:o + { \exp_after:wN #2 \l_@@_patch_replacement_tl } + \str_if_eq:nnT {#4} { after } + { \exp_not:N \UseHook { cmd / #3 / #4 } } + } + } + } +% \end{macrocode} +% +% Here's the auxiliary that makes the prefix control sequences for the +% redefinition. Each item has to be \cs{tl_trim_spaces:n}'d because +% the last item (and not any other) has a trailing space. +% \begin{macrocode} +\cs_new:Npn \@@_make_prefixes:w / #1 / + { + \tl_if_empty:nF {#1} + { + \exp_not:c { tex_ \tl_trim_spaces:n {#1} :D } + \@@_make_prefixes:w / + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{Patching by retokenization} +% +% At this point we've drained the possibilities of patching a command by +% expansion-and-redefinition, so we have to resort to patching by +% retokenizing the command. Patching by retokenization is done by +% getting the \tn{meaning} of the command, doing the necessary +% manipulations on the generated string, and the retokenizing that again +% by using \tn{scantokens}. +% +% Patching by retokenization is definitely a riskier business, because +% it relies that the tokens printed by \tn{meaning} produce the exact +% same tokens as the ones in the original definition. That is, the +% catcode régime must be exactly(ish) the same, and there is no way of +% telling except by trial and error. +% +% \begin{macro}{\@@_retokenize_patch:Nnn} +% This is the macro that will control the whole process. First we'll +% try out one final, rather trivial case, of a command with no +% arguments; that is, a token list. This case can be patched with +% the expand-and-redefine routine but it has to be the very last case +% tested for, because most (all?) robust commands start with a +% top-level macro with no arguments, so testing this first would +% short-circuit \tn{robust@command@act} and the top-level macros would +% be incorrectly patched. In that case, we just check if the +% \cs{cs_argument_spec:N} is empty, and call +% \cs{@@_patch_expand_redefine:NNnn}. +% \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} } + { +% \end{macrocode} +% +% Otherwise, we start the actual patching by retokenization job. The +% code calls \cs{@@_try_patch_with_catcodes:Nnnnw} with a different +% catcode setting: +% \begin{itemize} +% \item The current catcode setting; +% \item Switching the catcode of |@|; +% \item Switching the \pkg{expl3} syntax on or off; +% \item Both of the above. +% \end{itemize} +% +% If patching succeeds, \cs{@@_try_patch_with_catcodes:Nnnnw} has the +% side-effect of patching the macro |#1| (which may be an internal +% from the command whose name is~|#2|). +% \begin{macrocode} + \tl_set:Nx \l_@@_tmpa_tl + { + \int_compare:nNnTF { \char_value_catcode:n {`\@ } } = { 12 } + { \exp_not:N \makeatletter } { \exp_not:N \makeatother } + } + \tl_set:Nx \l_@@_tmpb_tl + { + \bool_if:NTF \l__kernel_expl_bool + { \ExplSyntaxOff } { \ExplSyntaxOn } + } + \use:x + { + \exp_not:N \@@_try_patch_with_catcodes:Nnnnw + \exp_not:n { #1 {#2} {#3} } + { \prg_do_nothing: } + { \exp_not:V \l_@@_tmpa_tl } % @ + { \exp_not:V \l_@@_tmpb_tl } % _: + { + \exp_not:V \l_@@_tmpa_tl % @ + \exp_not:V \l_@@_tmpb_tl % _: + } + } + \q_recursion_tail \q_recursion_stop +% \end{macrocode} +% +% If no catcode setting succeeds, give up and raise an error. The +% command isn't changed in any way in that case. +% \begin{macrocode} + { + \msg_error:nnxx { hooks } { cant-patch } + { \c_backslash_str #2 } { retok } + } + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_try_patch_with_catcodes:Nnnnw} +% This function is a simple wrapper around +% \cs{@@_cmd_if_scanable:NnTF} and \cs{@@_patch_retokenize:Nnnn} if +% the former returns \meta{true}, plus some debug messages. +% \begin{macrocode} +\cs_new_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} + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}[int]{\kerneltmpDoNotUse} +% This is an oddity required to be safe (as safe as reasonably +% possible) when patching the command. The entirety of +% \begin{quote} +% \meta{prefixes} \tn{def} \meta{cs} \meta{parameter text} +% |{|\meta{replacement text}|}| +% \end{quote} +% will go through \tn{scantokens}. The \meta{parameter text} and +% \meta{replacement text} are what we are trying to retokenize, so not +% much worry there. The other items, however, should ``just work'', +% so some care is needed to not use too fancy catcode settings. +% Therefore we can't use an \pkg{expl3}-named macro for \meta{cs}, nor +% the \pkg{expl3} versions of \tn{def} or the \meta{prefixes}. +% That is why the definitions that will eventually go into +% \tn{scantokens} will use the oddly (but hopefully clearly)-named +% \cs{kerneltmpDoNotUse}: +% \begin{macrocode} +\cs_new_eq:NN \kerneltmpDoNotUse ! +% \end{macrocode} +% \phoinline{Maybe this can be avoided by running the \meta{parameter text} +% and the \meta{replacement text} separately through \tn{scantokens} +% and then putting everything together at the end.} +% \end{macro} +% +% +% +% \begin{macro}{\@@_patch_required_catcodes:} +% Here are the catcode settings that are \emph{mandatory} when +% retokenizing commands. These are the minimum necessary settings to +% perform the definitions: they identify control sequences, which +% must be escaped with |\|$_0$, delimit the definition with |{|$_1$ +% and |}|$_2$, and mark parameters with |#|$_6$. Everything else may +% be changed, but not these. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_required_catcodes: + { + \char_set_catcode_escape:N \\ + \char_set_catcode_group_begin:N \{ + \char_set_catcode_group_end:N \} + \char_set_catcode_parameter:N \# + % \int_set:Nn \tex_endlinechar:D { -1 } + % \int_set:Nn \tex_newlinechar:D { -1 } + } +% \end{macrocode} +% \phoinline{\pkg{etoolbox} sets the \tn{endlinechar} and \tn{newlinechar} +% when patching, but as far as I tested these didn't make much of +% a difference, so I left them out for now. Maybe +% \tn{newlinechar}|=-1| avoids a space token being added after the +% definition.} +% \phoinline{If the patching is split by \meta{parameter text} and +% \meta{replacement text}, then only \# will have to stay in that +% list.} +% \phoinline{Actually now that we patch +% \texttt{\cs{UseHook}\{cmd/foo/before\}}, all the tokens there need +% to have the right catcodes, so this list now includes all +% lowercase letters, U and H, the slash, and whatever characters in +% the command name\ldots sigh\ldots} +% \end{macro} +% +% +% +% +% \begin{macro}[TF]{\@@_cmd_if_scanable:Nn} +% Here we'll do a quick test if the command being patched can in fact +% be retokenized with the specific catcode setting without changing +% in meaning. The test is straightforward: +% \begin{enumerate} +% \item apply \tn{meaning} to the command; +% \item split the \meta{prefixes}, \meta{parameter text} and +% \meta{replacement text} and arrange them as +% \begin{quote} +% \meta{prefixes}\tn{def}\cs{kerneltmpDoNotUse}%^^A +% \meta{parameter text}|{|\meta{replacement text}|}| +% \end{quote} +% \item rescan that with the given catcode settings, and do +% the definition; then finally +% \item compare \cs{kerneltmpDoNotUse} with the original command. +% \end{enumerate} +% If both are \tn{ifx}-equal, the command can be safely patched. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \@@_cmd_if_scanable:Nn #1 #2 { TF } + { + \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 {####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 { #2 \@@_patch_required_catcodes: } \l_@@_tmpa_tl + \token_if_eq_meaning:NNTF #1 \kerneltmpDoNotUse + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \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} +\cs_new_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4 + { +% \end{macrocode} +% Start off by making some things \tn{relax} to avoid lots of +% \tn{noexpand} below. +% \begin{macrocode} + \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop: + \cs_set_eq:NN \@@_tmp:w \scan_stop: + \use:x + { +% \end{macrocode} +% Now we'll define \cs{@@_tmp:w} such that it splits the \tn{meaning} +% of the macro (|#1|) into its three parts: +% \begin{enumerate} +% \def\makelabel#1{\texttt{\#\#\#\##1}} +% \item \meta{prefixes} +% \item \meta{parameter text} +% \item \meta{replacement text} +% \end{enumerate} +% and arrange that a complete definition, then place the |before| +% or |after| hooks around the \meta{replacement text}: +% accordingly. +% \begin{macrocode} + \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 } } + } + } +% \end{macrocode} +% Now we just have to get the \tn{meaning} of the command being +% patched and pass it through the meat grinder above. +% \begin{macrocode} + \tl_set:Nx \exp_not:N \l_@@_tmpa_tl + { \exp_not:N \@@_tmp:w \token_to_meaning:N #1 \s_@@_mark } + } +% \end{macrocode} +% Now rescan with the given catcode settings (overridden by the +% \cs{@@_patch_required_catcodes:}), and implicitly (by using the +% rescanned token list) carry out the definition from above. +% \begin{macrocode} + \tl_rescan:nV { #4 \@@_patch_required_catcodes: } \l_@@_tmpa_tl +% \end{macrocode} +% And to close, copy the newly-defined command into the old name and +% the patching is finally completed: +% \begin{macrocode} + \cs_set_eq:NN #1 \kerneltmpDoNotUse + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { wrong-cmd-hook } + { + Generic~hook~`cmd/#1/#2'~is~invalid. +% The~hook~should~be~`cmd/#1/before'~or~`cmd/#1/after'. + } + { + You~tried~to~add~a~generic~hook~to~command~\iow_char:N \\#1,~but~`#2'~ + is~an~invalid~component.~Only~`before'~or~`after'~are~allowed. + } +\msg_new:nnnn { hooks } { cant-patch } + { + Generic~hooks~cannot~be~added~to~'#1'. + } + { + You~tried~to~add~a~hook~to~'#1',~but~LaTeX~was~unable~to~ + patch~the~command~because~it~\@@_unpatchable_cases:n {#2}. + } +\cs_new:Npn \@@_unpatchable_cases:n #1 + { + \str_case:nn {#1} + { + { undef } { doesn't~exist } + { macro } { is~not~a~macro } + { expl3 } { is~a~private~expl3~macro } + { retok } { can't~be~retokenized~cleanly } + } + } +% \end{macrocode} +% +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}{ltcmdhooks}% +% {The~hook~management~system~for~commands} +% +% \end{macrocode} +% The command \cs{@@_cmd_begindocument_code:} is used in an +% internal hook, so we need to make sure it has a harmless +% definition after rollback as that will not remove it from the +% kernel hook. +% \begin{macrocode} +%\cs_set_eq:NN \@@_cmd_begindocument_code: \prg_do_nothing: +% +%\EndModuleRelease +\ExplSyntaxOff +% +% \end{macrocode} +% +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex/base/ltcntrl.dtx b/Master/texmf-dist/source/latex/base/ltcntrl.dtx index b779d27fb6c..d65b3aee94f 100644 --- a/Master/texmf-dist/source/latex/base/ltcntrl.dtx +++ b/Master/texmf-dist/source/latex/base/ltcntrl.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltcntrl.dtx} - [2014/04/21 v1.0h LaTeX Kernel (program control)] + [2020/12/04 v1.0h LaTeX Kernel (program control)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltcntrl.dtx} @@ -241,7 +241,7 @@ % % \begin{macro}{\@for} % \changes{v1.0d}{1995/04/24} -% {Dont expand second argument with \cs{edef}: /1317 (DPC)} +% {Don't expand second argument with \cs{edef}: /1317 (DPC)} % \begin{macrocode} \long\def\@for#1:=#2\do#3{% \expandafter\def\expandafter\@fortmp\expandafter{#2}% diff --git a/Master/texmf-dist/source/latex/base/ltcounts.dtx b/Master/texmf-dist/source/latex/base/ltcounts.dtx index 5dc1c8866d7..445cac2f2e4 100644 --- a/Master/texmf-dist/source/latex/base/ltcounts.dtx +++ b/Master/texmf-dist/source/latex/base/ltcounts.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltcounts.dtx} - [2018/04/22 v1.1l LaTeX Kernel (Counters)] + [2020/12/04 v1.1l LaTeX Kernel (Counters)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltcounts.dtx} @@ -630,7 +630,7 @@ % always selects the correct branch in an |\ifmmode| switch with % the usual disadvantage of ruining kerning. For the application we % use it for here that shouldn't matter. The alternative would be -% to mimic |\IeC| from \textsf{inputenc} but then it wil have the +% to mimic |\IeC| from \textsf{inputenc} but then it will have the % disadvantage of choosing the wrong branch if appearing at the % beginning of an alignment cell. However, users of e\TeX\ will be % pleasantly surprised to get the best of both worlds and no bad diff --git a/Master/texmf-dist/source/latex/base/ltdefns.dtx b/Master/texmf-dist/source/latex/base/ltdefns.dtx index 920c1acde6d..4f39d922cce 100644 --- a/Master/texmf-dist/source/latex/base/ltdefns.dtx +++ b/Master/texmf-dist/source/latex/base/ltdefns.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2020/11/25 v1.5o LaTeX Kernel (definition commands)] + [2021/05/27 v1.5p LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -103,7 +103,7 @@ % \end{macrocode} % % -% \subsection{Initex initialisations} +% \subsection{Initex initializations} % % \task{???}{This section needs extension} % @@ -858,7 +858,7 @@ % |\CheckCommand| takes the same arguments as |\newcommand|. If % the command already exists, with the same definition, then % nothing happens, otherwise a warning is issued. Useful for -% checking the current state befor a macro package starts +% checking the current state before a macro package starts % redefining things. Currently two macros are considered to have % the same definition if they are the same except for different % default arguments. That is, if the old definition was: @@ -1217,11 +1217,12 @@ % top-level definition to have the right kind of structure, but % this is somewhat problematical as we then have to distinguish % between \cs{long} macros and others and also take into account -% that sometimes the top-level is deliberately dones manually (like +% that sometimes the top-level is deliberately done manually (like % with \cs{begin}). % % The macro firstly checks if the control sequence in question exists % at all. +% \changes{v1.5p}{2021/05/26}{Normalize error message in \cs{MakeRobust}} % \begin{macrocode} % %\IncludeInRelease{2020/10/01}{\MakeRobust}{\MakeRobust}% @@ -1230,7 +1231,7 @@ \count@=\escapechar \escapechar=`\\ \@ifundefined{\expandafter\@gobble\string#1}{% - \@latex@error{The control sequence `\string#1' is undefined!% + \@latex@error{Command `\string#1' is undefined!% \MessageBreak There is nothing here to make robust}% \@eha }% @@ -1259,7 +1260,7 @@ \noexpand\protect\expandafter\noexpand \csname\expandafter\@gobble\string#1\space\endcsname}% }% - {\@latex@info{The control sequence `\string#1' is already robust}}% + {\@latex@info{Command `\string#1' is already robust}}% }% \escapechar=\count@ }% @@ -1363,12 +1364,12 @@ % \end{macro} % % \begin{macro}{\kernel@make@fragile} -% The opposite of |\MakeRobust| execpt that it doesn't do many +% The opposite of |\MakeRobust| except that it doesn't do many % checks as it is internal to the kernel. Why does one want such a % thing? % Only for compatibility reasons if \texttt{latexrelease} requests % a rollback of the kernel. For this reason we pretend that this -% command existed in all earler versions of \LaTeX{} i.e., we are +% command existed in all earlier versions of \LaTeX{} i.e., we are % not rolling it back since we need it precisely then. But we have % to get it into the \texttt{latexrelease} file so that a roll % forward is possible too. @@ -1452,7 +1453,7 @@ % robust commands. This code will then be used to test if a command is % robust, considered the different types of robustness, and then either copy % that definition, if \cs{DeclareCommandCopy} (or similar) is used, or show -% the definition of the command, if \cs{ShowCommmand} is used. +% the definition of the command, if \cs{ShowCommand} is used. % % \begin{macro}{\robust@command@act} % \changes{v1.5k}{2020/08/19}{Made \cs{robust@command@act} @@ -1471,7 +1472,7 @@ % \ldots % \end{quote} % \cs{robust@command@act} will iterate over the \meta{action-list}, evaluating -% each \meta{if-type-$n$}\meta{robust-cmd}|{|\meta{true}|}{|\meta{false}|}|. +% each \meta{if-type-$n$} \meta{robust-cmd} |{|\meta{true}|}{|\meta{false}|}|. % If the \meta{if-type-$n$} conditional returns \meta{true}, then % \meta{act-type-$n$}\meta{act-arg} is executed, and the loop ends. If the % conditional returns \meta{false}, then \meta{if-type-$n+1$} is executed in @@ -1711,7 +1712,7 @@ % \begin{macro}{\@showcommandlisthook} % The initial definition of \cs{@showcommandlisthook} contains the same tests % as used for copying, but \cs{@show@...} commands instead of \cs{@copy@...}. -% Same as before, it is initialised to cope with \cs{DeclareRobustCommand} and +% Same as before, it is initialized to cope with \cs{DeclareRobustCommand} and % \cs{newcommand} with optional arguments. % \begin{macrocode} \def\@showcommandlisthook{% @@ -2283,7 +2284,7 @@ % % The primitive |\-| command adds a discretionary hyphen using the % current font's |\hyphenchar|. Monospace fonts are usually declared -% with |\hyphenchar| set to $-1$ to suppress hyhenation. +% with |\hyphenchar| set to $-1$ to suppress hyphenation. % % \LaTeX, from \LaTeX2.09 in 1986 defined |\-| by % \begin{verbatim} @@ -2419,7 +2420,8 @@ % % % \begin{macro}{\g@addto@macro} -% Globally add to the end of a macro. +% Globally add to the end of a macro. +% This macro is used by the kernel to add to its internal hooks. % \changes{v0.2a}{1993/11/14}{Made global} % \changes{v0.2w}{1994/01/31} % {Use toks register to avoid `hash' problems} diff --git a/Master/texmf-dist/source/latex/base/ltdirchk.dtx b/Master/texmf-dist/source/latex/base/ltdirchk.dtx index 3abd49aced5..36a1ca616cd 100644 --- a/Master/texmf-dist/source/latex/base/ltdirchk.dtx +++ b/Master/texmf-dist/source/latex/base/ltdirchk.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltdirchk.dtx} - [2020/08/21 v1.3a LaTeX Kernel (System Dependent Parts)] + [2021/01/15 v1.3a LaTeX Kernel (System Dependent Parts)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdirchk.dtx} @@ -63,7 +63,7 @@ % {Add unstripped module, % so that dircheck.dtx may be used with initex} % \changes{v1.0a}{1994/03/08} -% {Reorganise driver module into `new style'} +% {Reorganize driver module into `new style'} % \changes{v1.0b}{1994/03/12} % {Change name from dircheck.dtx} % \changes{v1.0b}{1994/03/12} @@ -81,13 +81,13 @@ % \changes{v1.0w}{1998/08/17}{(RmS) Documentation improvements.} % % -% \section{\LaTeX\ System Dependent Initialisations} +% \section{\LaTeX\ System Dependent Initializations} % % \changes{v0.2g}{1994/01/21} -% {Improve documentation, reorganise docstrip module} +% {Improve documentation, reorganize docstrip module} % % This file implements the semi-automatic determination of various -% system dependent parts of the initialisation. The actual definitions +% system dependent parts of the initialization. The actual definitions % may be placed in a file |texsys.cfg|. Thus for operating systems for % which the tests here do not result in acceptable settings, a `hand % written' |texsys.cfg| may be produced. @@ -127,14 +127,16 @@ % |\input@path| should expand to a list of such directories, each in a % |{}| group. % +% \begin{sloppypar} % \DescribeMacro{\filename@parse} % After a call of the form: |\filename@parse{|\meta{filename}|}|, the -% three macros |\filename@area|,|\filename@base|,|\filename@ext| should +% three macros |\filename@area|, |\filename@base| and |\filename@ext| should % be defined to be the `area' (or directory), basename and % extension respectively. If there was no extension specified in % \meta{filename}, |\filename@ext| should be |\let| to |\relax| (so this % case may be tested with |\@ifundefined{filename@ext}| and, perhaps a % default extension substituted). +% \end{sloppypar} % % Normally one would not need to define this macro in |texsys.cfg| as % the automatic tests can supply parsers that work with UNIX and VMS and @@ -153,7 +155,7 @@ % % \DescribeMacro{\@TeXversion} % \changes{v1.0f}{1994/05/23}{Document \cs{@TeXversion}} -% |\@TeXversion| is now set automatically by the initialisation tests +% |\@TeXversion| is now set automatically by the initialization tests % in this file. You should not need to set it in |texsys.cfg|, however % the following documentation is left for information. \LaTeX\ does % not set this variable exactly, the automatic tests set it to:\\ @@ -206,7 +208,7 @@ % % \StopEventually{} % -% \section{Initialisation} +% \section{Initialization} % As this file is read at a very early stage, some definitions that % are normally considered to be part of the format must be made here. % @@ -470,18 +472,20 @@ % |{}| group. % % +% \begin{sloppypar} % \DescribeMacro{\filename@parse} % After a call of the form: |\filename@parse{|\meta{filename}|}|, the -% three macros |\filename@area|,|\filename@base|,|\filename@ext| should +% three macros |\filename@area|, |\filename@base|, |\filename@ext| should % be defined to be the `area' (or directory), basename and % extension respectively. If there was no extension specified in % \meta{filename}, |\filename@ext| should be |\let| to |\relax| (so this % case may be tested with |\@ifundefined{filename@ext}| and, perhaps a % default extension substituted). +% \end{sloppypar} % % Normally one would not need to define this macro in |texsys.cfg| as % the automatic tests can supply parsers that work with UNIX and VMS -% syntax, as well as a basic parser that willcover many other cases. +% syntax, as well as a basic parser that will cover many other cases. % However some operating systems may need a `hand produced' parser % in which case it should be defined in this file. % @@ -794,7 +798,7 @@ % to supply the correct information to the prompts. Now the interaction % is omitted. After the format is made the installer can attempt to run % the test document |ltxcheck.tex| through \LaTeXe. This will check, -% amongst other things, whether |texsys.cfg| will need to be edited and +% among other things, whether |texsys.cfg| will need to be edited and % the format remade. % % \begin{macro}{\input@path} diff --git a/Master/texmf-dist/source/latex/base/lterror.dtx b/Master/texmf-dist/source/latex/base/lterror.dtx index 9a606ea8c1d..7f480a0171f 100644 --- a/Master/texmf-dist/source/latex/base/lterror.dtx +++ b/Master/texmf-dist/source/latex/base/lterror.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltexpl.dtx b/Master/texmf-dist/source/latex/base/ltexpl.dtx index 7f9019ede31..6d7ec3ff60b 100644 --- a/Master/texmf-dist/source/latex/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex/base/ltexpl.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 2019-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2020/12/18 v1.2h LaTeX Kernel (expl3-dependent code)] + [2021/04/20 v1.3c LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -82,33 +82,60 @@ % \begin{macrocode} %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% -% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% -\let\@kernel@after@enddocument\@empty -\let\@kernel@after@enddocument@afterlastpage\@empty +% {kernel@enddocument hooks}{Define several kernel hooks} +% \end{macrocode} +% We only initialize these kernel hooks if they are not already +% existing. Otherwise they would be set to \cs{@empty} on rollback +% which would be wrong because code that has been added to to them +% may still have to be executed in the rollback situation . Instead +% code that writes to them needs to handle the rollback as needed. +% It is likely that we have to change that approach in the future, +% but for now it should do. +% (It is enough to test only for the existence of one hook, as all +% got added at the same time.) +% \changes{v1.3c}{2021/04/20}{Don't empty kernel hooks on rollback} +% \begin{macrocode} +\ifx\@kernel@after@enddocument\@undefined + \let \@kernel@after@enddocument \@empty + \let \@kernel@after@enddocument@afterlastpage \@empty +% \end{macrocode} +% +% \begin{macro}{\@kernel@before@begindocument,\@kernel@after@begindocument} +% For the similar reasons we also define those that are used in +% \cs{document} because they too get material added to in early modules. +% \begin{macrocode} + \let \@kernel@before@begindocument \@empty + \let \@kernel@after@begindocument \@empty +\fi %\EndIncludeInRelease % \end{macrocode} % % \begin{macrocode} %\IncludeInRelease{0000/00/00}% -% {kernel@enddocument hooks}{Define kernel enddocument Hooks}% +% {kernel@enddocument hooks}{Define several kernel hooks} %\let\@kernel@after@enddocument\@undefined %\let\@kernel@after@enddocument@afterlastpage\@undefined -%\EndIncludeInRelease +%\let\@kernel@before@begindocument\@undefined +%\let\@kernel@after@begindocument\@undefined % +%\EndIncludeInRelease % \end{macrocode} % \end{macro} +% \end{macro} % % First define some blank commands, so that in case something goes wrong while % loading \textsf{expl3}, we won't get strange \texttt{Undefined control % sequence} errors. +% \changes{v1.3a}{2021/01/24}{Define \pkg{expl3} hooks conditionally} % \begin{macrocode} %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% % {\@expl@sys@load@backend@@}{Roll forward support}% -\def\@expl@sys@load@backend@@{} -\def\@expl@push@filename@@{} -\def\@expl@push@filename@aux@@{} -\def\@expl@pop@filename@@{} +\def\reserved@a#1{\ifdefined#1\else\def#1{}\fi} +\reserved@a\@expl@sys@load@backend@@ +\reserved@a\@expl@push@filename@@ +\reserved@a\@expl@push@filename@aux@@ +\reserved@a\@expl@pop@filename@@ %\EndIncludeInRelease % % \end{macrocode} @@ -188,7 +215,9 @@ % In \texttt{2ekernel} mode, an error is fatal and building the format % is aborted. Use \verb=\batchmode \read -1 to \tokenlist=, which errors % with -% \verb=! Emergency stop. (cannot \read from terminal in nonstop modes)= +%\begin{verbatim} +% ! Emergency stop. (cannot \read from terminal in nonstop modes) +%\end{verbatim} % and aborts the \TeX{} run. In \texttt{latexrelease} mode, raise an % error and do nothing. Both ways, the error message shows the minimum % \textsf{expl3} engine requirements. @@ -214,7 +243,7 @@ % % \end{macrocode} % We do not support a roll forward across 2019. You need to start -% with 2019 if you want to get to 2020 or beyond. +% with 2019 if you want to get to 2020 or beyond. % \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)} % \begin{macrocode} %<*latexrelease> @@ -225,21 +254,18 @@ --- I'm giving up!\MessageBreak\MessageBreak Note that manually loading the expl3 package\MessageBreak from your distribution is not enough}% - \@@end % die + \batchmode \read -1 to \reserved@a % }% - {% - \input expl3.ltx - \ifdefined\NewDocumentCommand - \else - \IfFileExists{xparse.ltx} - {\input xparse.ltx } - {}% - \fi - }% + {\input expl3.ltx }% } %\EndIncludeInRelease % +% \end{macrocode} +% To support roll-forward for the case where \textsf{xparse} is fully +% integrated into the kernel, we do not need to repeat the complex test +% above as we can simply look for the marker command. +% \begin{macrocode} %\IncludeInRelease{2020/02/02}% % {expl3}{Pre-load expl3}% %\IfFileExists{expl3.ltx} @@ -262,39 +288,12 @@ %\EndIncludeInRelease % \end{macrocode} % -% -% Starting with 2020-10 the kernel contains most of the -% \texttt{xparse} interfaces loaded above. These interfaces are -% later used to define various user command. However, if somebody -% with an earlier installation tries to roll forward (using a -% \texttt{latexrelease} package from a newer release) this will not -% work as the earlier kernel doesn't contain commands such as -% \cs{NewDocumentCommand}. -% -% We therefore add code into \texttt{latexrelease.sty} to load the -% \texttt{xparse} package of the current installation instead. this -% may not work if the installation is really old, but roll forward -% can't do miracles. -% -% If the kernel is 2020-10 or later \cs{NewDocumentCommand} is -% already known (whether or not you roll forward or back) so -% nothing happens, but if you start from am earlier kernel the -% \texttt{xparse} package gets loaded by \texttt{latexrelease}. -% \changes{v1.2g}{2020/11/24}{Load xparse in latexrelease if needed (gh/434)} -% \begin{macrocode} -%\IncludeInRelease{2020/10/01}% -% {\NewDocumentCommand}{Emergency loading xparse}% -% -%\ifdefined\NewDocumentCommand \else -% \RequirePackage{xparse} -%\fi -% -%\EndIncludeInRelease -% \end{macrocode} +% \changes{v1.3a}{2021/01/21} +% {Move \pkg{xparse} rollback code to \texttt{ltcmd.dtx}} % % \subsection{Using expl3 code} % -% In order to ease the implemantation of some new features in +% In order to ease the implementation of some new features in % \LaTeXe\ we may (temporarily) use some coding based on the % \pkg{expl3}-code. % Such macros will eventually vanish and may be changed diff --git a/Master/texmf-dist/source/latex/base/ltfilehook.dtx b/Master/texmf-dist/source/latex/base/ltfilehook.dtx index b4f716748a8..5d0acc8fdfb 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 -%% -%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach, -%% Phelype Oleinik & LaTeX Team +% +% Copyright (C) 2020-2021 +% Frank Mittelbach, Phelype Oleinik & LaTeX Team % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: ltfilehook.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v1.0e} -\providecommand\ltfilehookdate{2021/01/07} +\providecommand\ltfilehookversion{v1.0k} +\providecommand\ltfilehookdate{2021/05/25} % \end{macrocode} % %<*driver> @@ -55,6 +55,10 @@ } \ExplSyntaxOff +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + + \usepackage{structuredlog} % for demonstration \EnableCrossrefs @@ -75,7 +79,7 @@ % \ltfilehookversion\ dated \ltfilehookdate, \copyright\ \LaTeX\ % Project.}} % -% \author{Frank Mittelbach} +% \author{Frank Mittelbach, Phelype Oleinik, \LaTeX{} Project Team} % % \maketitle % @@ -339,9 +343,12 @@ % % \subsection{High-level interfaces for \LaTeX{}} % -% We do not provide any high-level \LaTeX{} commands (like -% \pkg{filehook} or \pkg{scrlfile} do) but think that for package -% writers the commands from for hook management are sufficient. +% We do not provide any additional wrappers around the hooks (like +% \pkg{filehook} or \pkg{scrlfile} do) because we believe that for +% package writers the high-level commands from the hook management, +% e.g., \cs{AddToHook}, etc.\ +% are sufficient and in fact easier to work with, given that the hooks +% have consistent naming conventions. % % % @@ -371,7 +378,7 @@ % \em % Please do not misuse this functionality and replace a file with % another unless if really needed and only if the new version is -% implementating the same functionality as the original one! +% implementing the same functionality as the original one! % \end{quote} % \end{function} % @@ -447,6 +454,7 @@ % % % \section{The Implementation} +% % \begin{macrocode} %<*2ekernel> % \end{macrocode} @@ -455,6 +463,8 @@ %<@@=filehook> % \end{macrocode} % +% \changes{v1.0k}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} +% % % \subsection{Document and package-level commands} % @@ -517,7 +527,7 @@ % } % A utility macro to trigger \pkg{expl3}'s file-parsing and lookup, % and return a normalized representation of the file name. If the -% queried file doesn't exist, no normalisation takes place. +% queried file doesn't exist, no normalization takes place. % The output of \cs{@@_file_parse_full_name:nN} is passed on to the % |#2|---a 3-argument macro that takes the \meta{path}, \meta{base}, % and \meta{ext} parts of the file name. @@ -578,9 +588,13 @@ % places don't use \cs{InputIfFileExists} directly (\cs{include}) or % need \cs{CurrentFile} earlier (\cs{@onefilewithoptions}), so these % are manually used elsewhere as well. +% \changes{v1.0h}{2021/03/18} +% {Define \cs{g_@@_input_file_seq} to avoid losing data when +% rolling back.} % \begin{macrocode} \tl_new:N \l_@@_internal_tl -\seq_new:N \g_@@_input_file_seq +\seq_if_exist:NF \g_@@_input_file_seq + { \seq_new:N \g_@@_input_file_seq } \cs_new_protected:Npn \@@_file_push: { \seq_gpush:Nx \g_@@_input_file_seq @@ -594,7 +608,7 @@ \seq_gpop:NNTF \g_@@_input_file_seq \l_@@_internal_tl { \exp_after:wN \@@_file_pop_assign:nnnn \l_@@_internal_tl } { - \msg_error:nnn { hooks } { should-not-happen } + \msg_error:nnn { kernel } { should-not-happen } { Tried~to~pop~from~an~empty~file~name~stack. } } } @@ -619,6 +633,7 @@ % When rolling forward the following expl3 functions may not be defined. % If we roll back the code does nothing. % \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} +% \InternalDetectionOff % \begin{macrocode} %\IncludeInRelease{2020/10/01}% % {\file_parse_full_name_apply:nN}{Roll forward help}% @@ -640,7 +655,8 @@ % { % \tl_if_empty:nTF {#3} % { \__file_parse_full_name_base:nw { } #2 . \s__file_stop {#1} } -% { \__file_parse_full_name_area:nw { #1 / #2 } #3 \s__file_stop } +% { \__file_parse_full_name_area:nw { #1 / #2 } +% #3 \s__file_stop } % } %\cs_new:Npn \__file_parse_full_name_base:nw #1 #2 . #3 \s__file_stop % { @@ -654,7 +670,8 @@ % } % { \__file_parse_full_name_tidy:nnnN {#1} { .#2 } } % } -% { \__file_parse_full_name_base:nw { #1 . #2 } #3 \s__file_stop } +% { \__file_parse_full_name_base:nw { #1 . #2 } +% #3 \s__file_stop } % } %\cs_new:Npn \__file_parse_full_name_tidy:nnnN #1 #2 #3 #4 % { @@ -672,6 +689,7 @@ %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} +% \InternalDetectionOn % % \begin{macrocode} %<@@=> @@ -844,6 +862,17 @@ %\long\def \InputIfFileExists#1#2{% % \IfFileExists{#1}% % {#2\@addtofilelist{#1}\@@input \@filef@und}} +% \end{macrocode} +% +% Also undo the internal command as some packages unfortunately test +% for their existence instead of using \cs{IfFormatAtLeastTF}. +% \changes{v1.0g}{2021/02/08}{Undo the internal for robust +% \cs{InputIfFileExists} in rollback (gh/494)} +% \begin{macrocode} +%\expandafter\let\csname InputIfFileExists \endcsname\@undefined +% \end{macrocode} +% +% \begin{macrocode} %\let\@input@file@exists@with@hooks\@undefined %\let\unqu@tefilef@und\@undefined %\EndIncludeInRelease @@ -894,7 +923,8 @@ @file-subst@ \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1} } - { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn {#2} } + { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn + {#2} } \group_end: } \cs_new_protected:Npn \@@_subst_remove:n #1 @@ -957,12 +987,18 @@ %\EndIncludeInRelease % \end{macrocode} % +% We are not fully rolling back the file substitutions in case a +% rollback encounters a package that contains them, but is itself +% not setup for rollback. So we just bypass them and hope for the +% best. +% \changes{v1.0d}{2020/12/04}{Don't drop file substitution commands on +% rollback} % \begin{macrocode} %\IncludeInRelease{0000/00/00}% % {\declare@file@substitution}{File substitution}% % -%\let \declare@file@substitution \@undefined -%\let \undeclare@file@substitution \@undefined +%\let \declare@file@substitution \@gobbletwo +%\let \undeclare@file@substitution \@gobble % %\EndIncludeInRelease %<*2ekernel> @@ -981,6 +1017,7 @@ % \subsection{Selecting a file (\cs{set@curr@file})} % % \begin{macro}{\set@curr@file,\@curr@file,\@curr@file@reqd} +% \changes{v1.0f}{2021/01/31}{set \cs{protect} to \cs{string} gh/481} % Now we hook into \cs{set@curr@file} to resolve a possible file % substitution, and add \cs{@expl@@@filehook@set@curr@file@@nNN} % at the end, after \cs{@curr@file} is set. @@ -988,7 +1025,7 @@ % A file name is built using % \cs{expandafter}\cs{string}\cs{csname}\meta{filename}\cs{endcsname} % to avoid expanding utf8 active characters. The \cs{csname} expands -% the normalisation machinery and the routine to resolve a file +% the normalization machinery and the routine to resolve a file % substitution, returning a control sequence with the same name as the % file. % @@ -1001,14 +1038,18 @@ % false positives. Here we define \cs{csname\cs{endcsname}} to % expand to itself to avoid it matching the definition of some other % control sequence. +% \changes{v1.0i}{2021/04/20} +% {Make \string~ expand to a string (tracks change in l3kernel)} % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/10/01}% +%\IncludeInRelease{2021/06/01}% % {\set@curr@file}{Setting current file name}% \def\set@curr@file#1{% \begingroup \escapechar\m@ne + \let\protect\string + \edef~{\string~}% \expandafter\def\csname\expandafter\endcsname \expandafter{\csname\endcsname}% % \end{macrocode} @@ -1018,7 +1059,7 @@ % actual loaded file. \cs{@curr@file} is resolved first, to check if % a substitution happens. If it doesn't, % \cs{@expl@@@filehook@if@file@replaced@@TF} short-cuts and just copies -% \cs{@curr@file}, otherwise the full normalisation procedure is +% \cs{@curr@file}, otherwise the full normalization procedure is % executed. % % At this stage the file name is parsed and normalized, but if the @@ -1046,6 +1087,29 @@ % \end{macrocode} % % \begin{macrocode} +%\IncludeInRelease{2020/10/01}% +% {\set@curr@file}{Setting current file name}% +%\def\set@curr@file#1{% +% \begingroup +% \escapechar\m@ne +% \expandafter\def\csname\expandafter\endcsname +% \expandafter{\csname\endcsname}% +% \@expl@@@filehook@if@no@extension@@nTF{#1}% +% {\@tempswatrue}{\@tempswafalse}% +% \@kernel@make@file@csname\@curr@file +% \@expl@@@filehook@resolve@file@subst@@w {#1}% +% \@expl@@@filehook@if@file@replaced@@TF +% {\@kernel@make@file@csname\@curr@file@reqd +% \@expl@@@filehook@normalize@file@name@@w{#1}% +% \if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file@reqd \fi}% +% {\if@tempswa \@expl@@@filehook@drop@extension@@N\@curr@file \fi +% \global\let\@curr@file@reqd\@curr@file}% +% \@expl@@@filehook@clear@replacement@flag@@ +% \endgroup} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} %\IncludeInRelease{2019/10/01}% % {\set@curr@file}{Setting current file name}% %\def\set@curr@file#1{% @@ -1097,7 +1161,8 @@ \expandafter\ifx\csname\endcsname#1% .tex\else\string#1\fi} % \end{macrocode} -% +% +% \begin{sloppypar} % Then we call \cs{@expl@@@filehook@set@curr@file@@nNN} once for % \cs{@curr@file} to set \cs[no-index]{CurrentFile(Path)Used} and once for % \cs{@curr@file@reqd} to set \cs[no-index]{CurrentFile(Path)}. @@ -1107,6 +1172,7 @@ % \cs{@curr@file} and \cs{@curr@file@reqd} differ. This macro is % issued separate from \cs{set@curr@file} because it changes % \cs{CurrentFile}, and side-effects would quickly get out of control. +% \end{sloppypar} % \begin{macrocode} \def\@filehook@set@CurrentFile{% \@expl@@@filehook@set@curr@file@@nNN{\@curr@file}% @@ -1170,13 +1236,13 @@ % \begin{macro}{\@@_resolve_file_subst:w} % \begin{macro}{\@@_normalize_file_name:w} % \begin{macro}{\@@_file_name_compose:nnn} -% Start by sanitising the file with \cs{@@_file_parse_full_name:nN} +% Start by sanitizing the file with \cs{@@_file_parse_full_name:nN} % then do \cs{@@_file_subst_begin:nnn}\Arg{path}\Arg{name}\Arg{ext}. % \begin{macrocode} % %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% -% {\@@_resolve_file_subst:w}{Replace files detect loops}% +% {\@@_resolve_file_subst:w}{Replace files detect loops}% \ExplSyntaxOn \cs_new:Npn \@@_resolve_file_subst:w #1 \@nil { \@@_file_parse_full_name:nN {#1} \@@_file_subst_begin:nnn } @@ -1195,7 +1261,7 @@ % a flag to remember if a substitution happened. We use this in % \cs{set@curr@file} to short-circuit some of it in case no % substitution happened (by far the most common case, so it's worth -% optimising). The flag raised during the file substitution algorithm +% optimizing). The flag raised during the file substitution algorithm % must be explicitly cleared after the \cs{@@_if_file_replaced:TF} % conditional is no longer needed, otherwise further uses of % \cs{@@_if_file_replaced:TF} will wrongly return true. @@ -1258,8 +1324,8 @@ % the macro below, \cs{@@_file_subst_loop:cc} is called with % \cs[no-index]{@file-subst@\meta{file}} and % \cs[no-index]{@file-subst@\cs[no-index]{@file-subst@\meta{file}}}; -% that is, the substitution of \meta{file} and the substution of that -% substution: the Tortoise walks one step while the Hare walks two. +% that is, the substitution of \meta{file} and the substitution of that +% substitution: the Tortoise walks one step while the Hare walks two. % % Within \cs{@@_file_subst_loop:NN} the two substitutions are % compared, and if they lead to the same file it means that there is @@ -1275,7 +1341,7 @@ % %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% -% {\@@_file_subst_tortoise_hare:nn}{Tortoise and Hare}% +% {\@@_file_subst_tortoise_hare:nn}{Tortoise and Hare}% \ExplSyntaxOn \cs_new:Npn \@@_file_subst_tortoise_hare:nn #1 #2 #3 { @@ -1428,7 +1494,7 @@ % \begin{macrocode} %<@@=> % \end{macrocode} -% +% \InternalDetectionOff % \begin{macrocode} % %<*2ekernel|latexrelease> @@ -1474,7 +1540,7 @@ % % \begin{macrocode} \cs_new_eq:NN \@expl@@@filehook@file@push@@ - \__filehook_file_push: + \__filehook_file_push: % \end{macrocode} % % \begin{macrocode} @@ -1486,6 +1552,7 @@ \cs_new_eq:NN \@expl@@@filehook@file@pop@assign@@nnnn \__filehook_file_pop_assign:nnnn % \end{macrocode} +% \InternalDetectionOn % % % \begin{macrocode} @@ -1545,7 +1612,7 @@ % \end{macro} % % \begin{macro}{\@@_log_file_record:n} -% This macro is responsible for increasing and decresing the file +% This macro is responsible for increasing and decreasing the file % nesting level, as well as printing to the log. The argument is % either |STOPTART| or |STOP| and the action it takes on the nesting % integer depends on that. @@ -1664,8 +1731,8 @@ % \Finale % % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % diff --git a/Master/texmf-dist/source/latex/base/ltfiles.dtx b/Master/texmf-dist/source/latex/base/ltfiles.dtx index 99be77c8449..bcaac582208 100644 --- a/Master/texmf-dist/source/latex/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex/base/ltfiles.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2020/10/04 v1.2j LaTeX Kernel (File Handling)] + [2021/04/17 v1.2m LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -49,6 +49,9 @@ \providecommand\pkg[1]{\texttt{#1}} +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + \begin{document} \MaintainedByLaTeXTeam{latex} \maketitle @@ -192,19 +195,6 @@ % \end{oldcomments} % % -% \task{???}{Do we use @unused or mainaux?} -% \begin{macro}{\@inputcheck} -% \begin{macro}{\@unused} -% Allocate read stream for testing and output stream. -% \changes{v1.0l}{1994/11/07} -% {move here from ltdefns, remove duplicate \cs{@mainaux}} -% \begin{macrocode} -\newread\@inputcheck -\newwrite\@unused -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \begin{macro}{\@mainaux} % \begin{macro}{\@partaux} % \begin{macrocode} @@ -334,7 +324,7 @@ % locally in the output routine. In particular it allows hyphenation % in the page head even if the page break happens in verbatim. % If this has already been set by a package, set to the value of |\language| -% at this spoint. +% at this point. % \changes{v1.1n}{2017/03/10}{Save language default} % \begin{macrocode} \ifx\document@default@language\m@ne @@ -456,18 +446,25 @@ % harmless), however, in more complicated scenarios where several % full documents are combined to a single document it might get % applied several times with harmful effects. We therefore -% explicitly drop it at this point. the coing is somewhat obscure +% explicitly drop it at this point. the coding is somewhat obscure % due to the name of the macro which requires constructing. +% \InternalDetectionOff % \begin{macrocode} \edef \@kernel@after@begindocument@before {% \let\expandafter\noexpand\csname __hook env/document/begin\endcsname \noexpand\@empty} % \end{macrocode} +% \InternalDetectionOn % +% These internal hooks are already declared earlier (in +% \texttt{ltexpl}) so that other modules could write to them. +% \changes{v1.2m}{2021/04/17}{Move \cs{@kernel@before@begindocument} and +% \cs{@kernel@after@begindocument} init earlier so that other modules can +% write to the hooks} % \begin{macrocode} -\let \@kernel@before@begindocument \@empty -\let \@kernel@after@begindocument \@empty +%\let \@kernel@before@begindocument \@empty +%\let \@kernel@after@begindocument \@empty % \end{macrocode} % % \end{macro} @@ -710,15 +707,15 @@ \@latex@error{\string\include\space cannot be nested}\@eha \else % \end{macrocode} -% Here the normalisation will add |.tex| for all files, (it uses the -% the same normalisation as the hooks), so we need to remove that +% Here the normalization will add |.tex| for all files, (it uses +% the same normalization as the hooks), so we need to remove that % manually. \cs{@strip@tex@ext} does that. % \begin{macrocode} \set@curr@file{#1}% \edef\@curr@file{\@strip@tex@ext\@curr@file}% % \end{macrocode} % For historical reasons \cs{@include} expects an argument -% delimited by a space. This is kept (though uncessary now) to avoid +% delimited by a space. This is kept (though unnecessary now) to avoid % errors in other packages that use \cs{@include} directly. % \begin{macrocode} \expandafter\@include\expandafter{\@curr@file} % deliberate space @@ -726,13 +723,13 @@ % \end{macrocode} % % Here in \cs{includeonly} we also need to strip |.tex| after -% normalisation: +% normalization: % \begin{macrocode} \def\includeonly#1{% \@partswtrue % \end{macrocode} % Because the argument to |\includeonly| is a comma-separated list -% of filenames where there may be comma's precedeing some of the +% of filenames where there may be comma's preceding some of the % filenames or trailing them. Therefore we need to take the list % apart, remove the unwanted spaces while leaving the spaces % \emph{in} the filenames intact. @@ -996,10 +993,11 @@ % A side effect of the new code is that we will see quotes around % file name displays where there haven't been any before. % -% For compatibilty with existing code using |{abc}.tex| or |{one.two}.png| -% an initial brace group is discarded before expansion and |\string| is applied -% The content of the brace group is discarded. This means that a leading space -% will be lost unless protected (by |{ }| or |" "| or |\space|) but filenames +% For compatibility with existing code using |{abc}.tex| or +% |{one.two}.png|, an initial brace group is discarded before +% expansion and |\string| is applied. The content of the brace +% group is discarded. This means that a leading space will be lost +% unless protected (by |{ }| or |" "| or |\space|) but filenames % with a space are hopefully rare. % % \changes{v1.2a}{2019/07/01}{Support UTF-8} @@ -1058,7 +1056,7 @@ % % \changes{v1.2a}{2019/07/01}{Support UTF-8} % \changes{v1.2b}{2019/08/27}{Make command robust} -% \changes{v1.2d}{2019/10/26}{dont quote name} +% \changes{v1.2d}{2019/10/26}{don't quote name} % \begin{macrocode} \DeclareRobustCommand\IfFileExists[1]{% \set@curr@file{#1}% @@ -1066,30 +1064,114 @@ % \end{macrocode} % \end{macro} % +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\quote@name}{Quote file names}% +% +%\let\quote@name\@undefined +%\let\quote@@name\@undefined +%\let\unquote@name\@undefined +% +%\long\def \IfFileExists#1#2#3{% +% \openin\@inputcheck#1 % +% \ifeof\@inputcheck +% \ifx\input@path\@undefined +% \def\reserved@a{#3}% +% \else +% \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}% +% \fi +% \else +% \closein\@inputcheck +% \edef\@filef@und{#1 }% +% \def\reserved@a{#2}% +% \fi +% \reserved@a} +% +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% +% +% % \begin{macro}{\IfFileExists@} % \changes{v0.9b}{1993/12/04}{Macro added} % \changes{v0.9p}{1994/01/18}{New Definition} % \changes{v1.0t}{1995/05/25}{(CAR) added \cs{long}} -% \changes{v1.2d}{2019/10/26}{quote on openin}% +% \changes{v1.2d}{2019/10/26}{quote on openin} +% \changes{v1.2k}{2021/03/12}{Allow unbalanced conditionals (gh/530)} % Argument |#1| is |\@curr@file| so catcode 12 string with no quotes. +% +% The original definition picked up arguments |#2| and |#3| in a +% way that they couldn't contain unbalanced conditionals. A better +% implementation would have been not to pick up the arguments at +% all but instead use the usual \cs{@firstoftwo} and +% \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. % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\IfFileExists@}{manage unbalanced conditionals} \long\def \IfFileExists@#1#2#3{% \openin\@inputcheck"#1" % \ifeof\@inputcheck \ifx\input@path\@undefined - \def\reserved@a{#3}% + \let\reserved@a\@secondoftwo \else - \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}% + \def\reserved@a{\@iffileonpath{#1}}% \fi \else \closein\@inputcheck \edef\@filef@und{"#1" }% - \def\reserved@a{#2}% + \let\reserved@a\@firstoftwo \fi - \reserved@a} +% \end{macrocode} +% This is just there so that any |#| inside |#2| or |#3| needs +% doubling (as that was the case in the past). +% \begin{macrocode} + \expandafter\def\expandafter\reserved@a + \expandafter{\reserved@a{#2}{#3}}% +\reserved@a} +% +%\EndIncludeInRelease +%\IncludeInRelease{2019/10/01}% +% {\IfFileExists@}{manage unbalanced conditionals} +% +%\long\def \IfFileExists@#1#2#3{% +% \openin\@inputcheck"#1" % +% \ifeof\@inputcheck +% \ifx\input@path\@undefined +% \def\reserved@a{#3}% +% \else +% \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}% +% \fi +% \else +% \closein\@inputcheck +% \edef\@filef@und{"#1" }% +% \def\reserved@a{#2}% +% \fi +% \reserved@a} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\IfFileExists@}{manage unbalanced conditionals} +% +%\let\IfFileExists@\@undefined +% +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % +% +% +% +% +% +% % \begin{macro}{\@iffileonpath} % If the file is not found by |\openin|, and |\input@path| is defined, % look in all the directories specified in |\input@path|. @@ -1103,6 +1185,10 @@ % \changes{v1.2d}{2019/10/26}{quote on openin}% % \changes{v1.2f}{2019/11/11}{make \cs{@filef@und} match quoting used on \cs{openin}}% % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2019/10/01}% +% {\@iffileonpath}{Quote file names} \long\def\@iffileonpath#1{% \let\reserved@a\@secondoftwo \expandafter\@tfor\expandafter\reserved@b\expandafter @@ -1122,28 +1208,7 @@ % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\quote@name}{Quote file names}% -% -%\let\quote@name\@undefined -%\let\quote@@name\@undefined -%\let\unquote@name\@undefined -% -%\let\IfFileExists@\@undefined -% -%\long\def \IfFileExists#1#2#3{% -% \openin\@inputcheck#1 % -% \ifeof\@inputcheck -% \ifx\input@path\@undefined -% \def\reserved@a{#3}% -% \else -% \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}% -% \fi -% \else -% \closein\@inputcheck -% \edef\@filef@und{#1 }% -% \def\reserved@a{#2}% -% \fi -% \reserved@a} +% {\quote@name}{Quote file names} % %\long\def\@iffileonpath#1{% % \let\reserved@a\@secondoftwo diff --git a/Master/texmf-dist/source/latex/base/ltfinal.dtx b/Master/texmf-dist/source/latex/base/ltfinal.dtx index aa4219723af..19f82934aa6 100644 --- a/Master/texmf-dist/source/latex/base/ltfinal.dtx +++ b/Master/texmf-dist/source/latex/base/ltfinal.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2020-09-26 v2.2j LaTeX Kernel (Final Settings)] + [2021/04/18 v2.2o LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -57,7 +57,7 @@ % % % \section{Final settings} -% This section contains the final settings for \LaTeX. It initialises +% This section contains the final settings for \LaTeX. It initializes % some debugging and typesetting parameters, sets the default % |\catcode|s and uc/lc codes, and inputs the hyphenation file. % @@ -90,6 +90,9 @@ % \changes{v2.0s}{2016/10/15}{Tidy up status of char 127} % \changes{v2.2i}{2020/08/21}{Integration of new hook management interface} % +% +% +% % \subsection{Debugging} % % By default, \LaTeX{} shows statistics: @@ -150,7 +153,7 @@ %\begin{macro}{\newXeTeXintercharclass} % \changes{v2.0a}{2014/12/30}{macro added} % \changes{v2.0b}{2015/01/23}{use reserved count 257} -% \changes{v2.0f}{2015/04/28}{define \cs{xe@alloc@intercharclass} for compatibility with older xelatex initilisation} +% \changes{v2.0f}{2015/04/28}{define \cs{xe@alloc@intercharclass} for compatibility with older xelatex initialization} %\begin{macro}{\xe@alloc@intercharclass} %\begin{macro}{\e@alloc@intercharclass@top} % \changes{v2.0j}{2016/01/04}{Start allocation at one not three} @@ -239,7 +242,73 @@ % \end{macro} % \end{macro} % -% +% \begin{macro}{trace_stack_levels} +% Now define the Lua function to emulate \cs{tracingstacklevels} and +% install it in the \texttt{input_level_string} callback. +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +% \end{macrocode} +% In \texttt{latexrelease} mode we always remove the function from +% the callback, then add the correct version later. +% \begin{macrocode} +%\ifx\directlua\@undefined +%\else +% \directlua{% +% if luatexbase.callbacktypes['input_level_string'] and % +% luatexbase.in_callback('input_level_string','tracingstacklevels') then +% luatexbase.remove_from_callback('input_level_string','tracingstacklevels') +% end}% +%\fi +%\IncludeInRelease{2021/06/01}{trace_stack_levels}% +% {Lua trace_stack_levels function}% +\ifx\directlua\@undefined +\else +%<*2ekernel> + \expanded{% + \everyjob{\the\everyjob + \noexpand%\directlua +% + \directlua{% + local function trace_stack_levels (input_ptr) + local tracingstacklevels = tex.count.tracingstacklevels + if tex.tracingmacros > 0 or input_ptr < tracingstacklevels then + if tracingstacklevels > 0 then + if input_ptr < tracingstacklevels then + return "\string\n\string~" .. string.rep(".",input_ptr) + else + return "\string~\string~" + end + else + return "\string\n" + end + else + return "" + end + end +% if luatexbase.callbacktypes['input_level_string'] then + luatexbase.add_to_callback('input_level_string', + trace_stack_levels,'tracingstacklevels') +% end + }% +%<*2ekernel> + }}% +% +\fi +%\EndIncludeInRelease +% +% \end{macrocode} +% Then for the full rollback, just do nothing, since the function +% was already taken out of the rollback above. +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}{trace_stack_levels}% +% {Lua trace_stack_levels function}% +%% Nothing here +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} % % The default values of the picture and |\fbox| parameters: % \begin{macrocode} @@ -522,12 +591,13 @@ % %<*2ekernel|latexrelease> %\IncludeInRelease{2017/04/15}% -% {\document@default@language}{Save language for hyphenation}% +% {\document@default@language}{Save language for hyphenation}% \let\document@default@language\m@ne % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\document@default@language}{Save language for hyphenation}% +% {\document@default@language}{Save language for hyphenation}% +% %\let\document@default@language\@undefined %\EndIncludeInRelease %<*2ekernel> @@ -562,6 +632,52 @@ \fi % \end{macrocode} % +% For pdf\TeX\ preload and enable automatic glyph to Unicode mapping +% for more reliable copy and paste support. +% \changes{v2.2l}{2021/01/21}{Load glyphtounicode.tex for pdf\TeX} +% \changes{v2.2m}{2021/02/25}{Improve speed of ToUnicode everyjob loading code} +% +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\pdfgentounicode}{Preload glyphtounicode}% +\ifx \pdfgentounicode \@undefined \else +%<*2ekernel> + \ifnum 0=0% + \ifdefined\pdftexversion +% \pdftexversion<140 does not have \pdfgentounicode, so we only check higher values + \ifnum \pdftexversion=140 \ifnum\pdftexrevision<22 1\fi\fi + \fi + \relax +% + \input glyphtounicode +%<*2ekernel> + \else + \begingroup + \everyeof{\noexpand}\endlinechar-1 + \edef\x{\endgroup + \everyjob{\the\everyjob\@@input glyphtounicode }% + }\x + \fi +% + \pdfgentounicode=1 +\fi +% +%\EndIncludeInRelease +% \end{macrocode} +% When rolling back we can't unload the glyphtounicode mappings, but we +% can reset |\pdfgentounicode| to ensure that they aren't used. +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\pdfgentounicode}{Preload glyphtounicode}% +%\ifx \pdfgentounicode \@undefined \else +% \pdfgentounicode=0 +%\fi +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% % \subsection{Input encoding} % % \changes{v2.1a}{2018/03/25}{default to UTF-8} @@ -632,7 +748,7 @@ % % \begin{macro}{\UseRawInputEncoding} % \changes{v2.1a}{2018/03/25}{Macro added} -% Reset 8 bit characters to catcode 12 so the input endcoing matches the ``Raw'' +% Reset 8 bit characters to catcode 12 so the input encoding matches the ``Raw'' % font encoding. % Useful for special behaviours, or for compatibility with older \LaTeX\ formats. % \changes{v2.1b}{2018/04/06}{Undo changes to \cs{DeclareFontEncoding@} and @@ -939,7 +1055,7 @@ \expandafter\reserved@a\@uclclist\reserved@b{\reserved@b\@gobble}% % \end{macrocode} % Tell UTF-8 processing to process chars even though we are in an \cs{protected@edef}. -% \changes{v2.1h}{2019/09/14}{Expand UTF8 chrs when case changing (github/177)} +% \changes{v2.1h}{2019/09/14}{Expand UTF8 chars when case changing (github/177)} % \begin{macrocode} \let\UTF@two@octets@noexpand\@empty \let\UTF@three@octets@noexpand\@empty diff --git a/Master/texmf-dist/source/latex/base/ltfloat.dtx b/Master/texmf-dist/source/latex/base/ltfloat.dtx index dee9a10197e..ed25db3ed10 100644 --- a/Master/texmf-dist/source/latex/base/ltfloat.dtx +++ b/Master/texmf-dist/source/latex/base/ltfloat.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -31,7 +31,7 @@ % %<*driver> % \fi -\ProvidesFile{ltfloat.dtx}[2020/04/09 v1.2d LaTeX Kernel (Floats)] +\ProvidesFile{ltfloat.dtx}[2021/03/03 v1.2f LaTeX Kernel (Floats)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfloat.dtx} @@ -356,7 +356,7 @@ % \changes{v1.1f}{1994/11/21} % {Missing percents reinserted after 4, 8: these are not numbers.} % \changes{v1.1g}{1994/12/10}{Old version reinstated temporarily} -% \changes{v1.1g}{1994/12/10}{Sanitisation added temporarily} +% \changes{v1.1g}{1994/12/10}{Sanitization added temporarily} % The first part of this sets the count register that stores all % the information about the type and fps of the float. % @@ -574,7 +574,7 @@ % % \begin{macro}{\@setnobreak} % \changes{v1.1f}{1994/11/21}{Macro added} -% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before +% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before % \cs{@nobreak...}} % \begin{macrocode} \def \@setnobreak{% @@ -588,7 +588,7 @@ % % \begin{macro}{\@setminipage} % \changes{v1.1f}{1994/11/21}{Macro added} -% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before +% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before % \cs{@minipage...}} % \begin{macrocode} \def \@setminipage{% @@ -734,7 +734,7 @@ % {Use new \cs{color@hbox} concept.} % \changes{v1.1f}{1994/11/21}{Corrected position of \cs{outer@nobreak}} % \changes{v1.1f}{1994/11/21}{Added reset of minipage flag} -% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before +% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before % \cs{@minipage...}} % \begin{macrocode} \@minipagefalse @@ -1002,9 +1002,14 @@ % \changes{v1.1f}{1994/11/21}{Added \cs{@setminipage} etc} % \changes{v1.1f}{1994/11/21}{Added resetting of size and font} % \changes{v1.1m}{1995/05/25}{(CAR) Resettings moved to hook} -% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before +% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before % \cs{@minipage...}} +% \changes{v1.2e}{2021/02/03}{Explicitly end with \cs{par} (gh/489)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\@savemarbox}{Explicit par for marginpar}% \long\def \@savemarbox #1#2{% \global\setbox #1% \color@vbox @@ -1012,12 +1017,35 @@ \hsize\marginparwidth \@parboxrestore \@marginparreset - #2% + #2\par \@minipagefalse \outer@nobreak }% \color@endbox } +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\@savemarbox}{Explicit par for marginpar}% +% +%\long\def \@savemarbox #1#2{% +% \global\setbox #1% +% \color@vbox +% \vtop{% +% \hsize\marginparwidth +% \@parboxrestore +% \@marginparreset +% #2% +% \@minipagefalse +% \outer@nobreak +% }% +% \color@endbox +%} +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1026,7 +1054,7 @@ % % The rational for allowing these normally global flags to be set % locally here, via |\@parboxrestore| was stated originally by -% Donald Arsenau and extended by Chris Rowley. +% Donald Arseneau and extended by Chris Rowley. % It is because these flags are only set globally to % true by section commands, and these should never appear within % marginals or floats or, indeed, in any group; and they are only ever @@ -1480,7 +1508,13 @@ % {Removed \cs{normalcolor} (again)} % \changes{v1.1t}{1997/11/19} % {Missing percent, again} +% \changes{v1.2e}{2021/02/10}{Explicitly run \cs{par} at the end of footnote text +% in preparation for paragraph hooks} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\@footnotetext}{footnotetext tagging}% \long\def\@footnotetext#1{\insert\footins{% \reset@font\footnotesize \interlinepenalty\interfootnotelinepenalty @@ -1493,7 +1527,32 @@ \color@begingroup \@makefntext{% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% + \par \color@endgroup}}% +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\@footnotetext}{footnotetext tagging}% +% +%\long\def\@footnotetext#1{\insert\footins{% +% \reset@font\footnotesize +% \interlinepenalty\interfootnotelinepenalty +% \splittopskip\footnotesep +% \splitmaxdepth \dp\strutbox \floatingpenalty \@MM +% \hsize\columnwidth \@parboxrestore +% \protected@edef\@currentlabel{% +% \csname p@footnote\endcsname\@thefnmark +% }% +% \color@begingroup +% \@makefntext{% +% \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% +% \color@endgroup}}% +% +%\EndIncludeInRelease +%<*2ekernel> % \end{macrocode} % \end{macro} % @@ -1558,10 +1617,51 @@ % \begin{macrocode} \def\@mpfn{footnote} \def\thempfn{\thefootnote} -% % \end{macrocode} +% % \end{macro} % \end{macro} % +% +% +% +% \begin{macro}{\footref} +% This command generates a footnote mark. The value is produced by +% referencing a \cs{label} placed into a \cs{footnote} elsewhere +% (can be one in the main galley or in a minipage). +% \changes{v1.2f}{2021/02/16}{\cs{footref} added} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\footref}{Add footref}% +\def\footref#1{% + \begingroup + \unrestored@protected@xdef\@thefnmark{\ref{#1}}% + \endgroup + \@footnotemark +} +% +%\EndIncludeInRelease +% \end{macrocode} +% We don't remove it when rolling back so that packages offered it +% in the past do not need to alter their behavior in a rollback +% situation. +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\footref}{Add footref}% +% +% % \let\footref\@undefined +% +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +% +% \end{macrocode} +% % \Finale % diff --git a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx index 0a44d5acf1e..5f70053a688 100644 --- a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfntcmd.dtx} - [2019/12/17 v3.4c LaTeX Kernel (Font commands)] + [2020/12/05 v3.4c LaTeX Kernel (Font commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfntcmd.dtx} @@ -303,7 +303,7 @@ % character in an unsloped font; we believe (in early 2003) that % this is perhaps inefficient but not dangerous. % -% It also now checks for empty contents of the text command and optimises +% It also now checks for empty contents of the text command and optimizes % this case. Some care is also taken to check that doing dangerous % things in vertical mode is avoided. % @@ -539,7 +539,7 @@ % % \begin{macro}{\ifmaybe@ic} % \changes{v3.4a}{2009/12/14}{Macro added} -% Switch used soley within |\maybe@ic| not interfering with other +% Switch used solely within |\maybe@ic| not interfering with other % switches. % \begin{macrocode} \newif\ifmaybe@ic @@ -585,7 +585,7 @@ % \begin{macrocode} \do \t@st@ic % \end{macrocode} -% Frank thinks that the next bit it is inefficient if done after +% Frank thinks that the next bit is inefficient if done after % the second change. Chris thinks that most all of this is % inefficient for the commonest cases: but that is the price of a % cleverer algorithm. It is certainly needed to deal with the use diff --git a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx index a66a26cd39c..86c84b111fb 100644 --- a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 2019-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssaxes.dtx} - [2020/08/21 v1.0g LaTeX Kernel (NFSS Axes handing)] + [2021/03/18 v1.0i LaTeX Kernel (NFSS Axes handing)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -68,11 +68,11 @@ % % \StopEventually{} % -% Everything in the this file got introduced 2020/02/02, so we do a -% single rollback (for now). +% \changes{v1.0h}{2020/12/04}{Reorganized the rollback data} +% +% Everything in the this file got introduced 2020/02/02, so we use large rollback +% chunks, only interrupted if necessary. % \begin{macrocode} -%<*2ekernel> -% %<*2ekernel|latexrelease> %\IncludeInRelease{2020/02/02}% % {\DeclareFontSeriesChangeRule}{Series change rules}% @@ -168,13 +168,13 @@ % request (i.e., second argument). % % In particular this is also true for cases involving \texttt{m}, -% e.g., \texttt{bm} (bold medium width) which automatially gets +% e.g., \texttt{bm} (bold medium width) which automatically gets % reduced result in \texttt{b} or \texttt{mc} (medium weight % condensed) which becomes \texttt{c} as a result. % % \item % -% Only a few entries have ``alterative'' values and perhaps most of +% Only a few entries have ``alternative'' values and perhaps most of % them should get dropped. Or maybe not \ldots{} needs some thought % perhaps. % @@ -183,7 +183,7 @@ % to stay with \texttt{b} when a change to \texttt{c} is requested % and \texttt{bc} doesn't exist, than to go to first change the % shape to \texttt{n} and then find that \texttt{bc/n} doesn't -% exist either and thus ending up wth \texttt{m/n}. +% exist either and thus ending up with \texttt{m/n}. % % \item % @@ -678,21 +678,59 @@ % \end{macrocode} % % - - +% Supporting rollback \ldots +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\DeclareFontSeriesChangeRule}{Series change rules}% +% +%\let\DeclareFontSeriesChangeRule\@undefined +% +%\EndIncludeInRelease +% \end{macrocode} +% +% +% +% +% % \subsection{Changing to a new series} % % - -% \begin{macro}{\if@forced@series} -% If the series gets forced we need to know that fact later on. +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\fontseries}{delay fontseries update}% +% \end{macrocode} +% +% +% \begin{macro}{\fontseries} +% The \cs{fontseries} command takes one argument which is the requested new +% font series. In the orginal implementation it simply saved the +% expanded value in \cs{f@series}. Now we do a bit more processing +% and look up the final value in the font series data base. This is +% done by \cs{merge@font@series}. But the lookup should be done +% within the target family and call to \cs{fontseries} might be +% followed by a \cs{fontfamily} call. So we delay the processing to +% \cs{selectfont} and only record the necessary action in +% \cs{delayed@f@adjustment}. % \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added} +% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)} % \begin{macrocode} -\newif\if@forced@series +\DeclareRobustCommand\fontseries[1]{\@forced@seriesfalse + \expandafter\def\expandafter\delayed@f@adjustment\expandafter + {\delayed@f@adjustment\delayed@merge@font@series{#1}}} % \end{macrocode} % \end{macro} % % +% \begin{macro}{\delayed@f@adjustment} +% The macro holding the delayed action(s) for use in \cs{selectfont}. +% \begin{macrocode} +\let\delayed@f@adjustment\@empty +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\fontseriesforce} % To change unconditionally to a new series you can use % \cs{fontseriesforce}. Of course, if the series doesn't exist for @@ -700,24 +738,69 @@ % dependency on the current series. % \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added} % \begin{macrocode} -\DeclareRobustCommand\fontseriesforce[1]{\@forced@seriestrue\edef\f@series{#1}} +\DeclareRobustCommand\fontseriesforce[1]{\@forced@seriestrue + \expandafter\def\expandafter\delayed@f@adjustment\expandafter + {\delayed@f@adjustment\edef\f@series{#1}}} % \end{macrocode} % \end{macro} % % -% \begin{macro}{\fontseries} -% The \cs{fontseries} command takes one argument which is the requested new -% font series. In the orginal implementation it simply saved the -% expanded value in \cs{f@series}. Now we do a bit more processing -% and look up the final value in the font series data base. This is -% done by \cs{merge@font@series}. +% +% \begin{macro}{\if@forced@series} +% If the series gets forced we need to know that fact later on. % \changes{v1.0c}{2020/02/10}{Switch \cs{if@forced@series} added} % \begin{macrocode} -\DeclareRobustCommand\fontseries[1]{\@forced@seriesfalse\merge@font@series{#1}} +\newif\if@forced@series % \end{macrocode} % \end{macro} - - +% +% +% \begin{macrocode} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/02/02}% +% {\fontseries}{delay fontseries update}% +% +%\DeclareRobustCommand\fontseries[1]{\@forced@seriesfalse +% \merge@font@series{#1}} +%\DeclareRobustCommand\fontseriesforce[1]{\@forced@seriestrue +% \edef\f@series{#1}} +%\let\delayed@f@adjustment\@undefined +% +% \end{macrocode} +% For a roll forward we may have to define \cs{if@forced@series} +% but this needs doing in a way that \TeX{} doesn't see it when +% skipping over conditionals. +% \changes{v1.0i}{2021/03/18} +% {Fix rollforward definition.} +% \begin{macrocode} +%\expandafter\newif\csname if@forced@series\endcsname +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\fontseries}{delay fontseries update}% +% +%\DeclareRobustCommand\fontseries[1]{\edef\f@series{#1}} +%\let\fontseriesforce\@undefined +% +%\EndIncludeInRelease +% \end{macrocode} +% +% +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/02/02}% +% {\merge@font@series}{Merge series values}% +% \end{macrocode} +% +% % \begin{macro}{\merge@font@series} % We look up the data base value by expanding the right command % twice. If no such value exist then the result will be \cs{relax} @@ -734,9 +817,9 @@ } % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\merge@font@series@} % This now defines the new \cs{f@series}: % \begin{macrocode} @@ -758,11 +841,9 @@ % \end{macrocode} % Otherwise we check if the desired result for the series % (\texttt{\#1}) exists for the font family and the current shape. -% As the \texttt{.fd} is perhaps not loaded yet, we first -% have to do that, otherwise the test would fail even if the face -% is actually available. +% All this happens inside \cs{selectfont} which has already taken care to load +% the \texttt{.fd}, file if necessary. % \begin{macrocode} - \maybe@load@fontshape \edef\reserved@a{\f@encoding /\f@family /#1/\f@shape}% \ifcsname \reserved@a \endcsname % \end{macrocode} @@ -798,9 +879,10 @@ % \end{macrocode} % It is possible that the previous font and the new one are % actually identical (and the font was not found because it still -% needs loading) in which case a warning would look rather odd. So -% we make a quick check for that (which is the reason why we defined -% \cs{@reserveda} above. +% needs loading) in which case a warning would look rather odd. So +% we make a quick check for that (which is the reason why we +% defined \cs{@reserveda} above instead of doing inline testing +% inside \cs{ifcsname}). % \begin{macrocode} \def\@font@shape@subst@warning{% \edef\reserved@b{\curr@fontshape}% @@ -814,13 +896,71 @@ % % % +% \begin{macro}{\merge@font@series@without@substitution, +% \merge@font@series@without@substitution@, +% \delayed@merge@font@series} +% +% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)} +% +% \cs{merge@font@series@without@substitution} works like +% \cs{merge@font@series}, i.e., it looks up the combination in the +% rule base and if there exists an entry it uses it and if not it +% uses the new series value. However, it doesn't check if there is +% actually a font face with the new series value as +% \cs{merge@font@series} does. This simplified command is used in +% \cs{selectfont} at a point where other font attributes are not +% yet updated so that checking the font face might result incorrect +% in substitutions. +% +% \begin{macrocode} +\def\merge@font@series@without@substitution#1{% + \expandafter\expandafter\expandafter + \merge@font@series@without@substitution@ + \csname series@\f@series @#1\endcsname + {#1}% + \@nil +} +% \end{macrocode} +% +% \begin{macrocode} +\def\merge@font@series@without@substitution@#1#2#3\@nil{% + \def\reserved@a{#3}% + \ifx\reserved@a\@empty + \set@target@series{#2}% + \else + \set@target@series{#1}% + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\delayed@merge@font@series} +% +% When we delay the merge action in \cs{fontseries} we first +% attempt to use merging without substitution. If that results in a +% non-existing font face the merge is redone in \cs{selectfont} +% using a version with substitution. See \cs{selectfont} for details. +% +% \changes{v1.0h}{2020/12/22}{Distangle series and shape update +% (gh/444)} +% \begin{macrocode} +\let\delayed@merge@font@series\merge@font@series@without@substitution +% \end{macrocode} +% \end{macro} % % \begin{macro}{\maybe@load@fontshape} % A small helper that we use a couple of times: try loading a % fontshape (in a group because \cs{try@load@fontshape} normalizes -% catcodes). +% catcodes and we also want to change \cs{typeout} so that it +% doesn't report missing \texttt{.fd} files on the terminal). % \begin{macrocode} -\def\maybe@load@fontshape{\begingroup\try@load@fontshape\endgroup} +\def\maybe@load@fontshape{% + \begingroup + \let \typeout \@font@info + \try@load@fontshape + \endgroup} % \end{macrocode} % \end{macro} % @@ -845,7 +985,7 @@ % \end{macrocode} % We need to \cs{edef} the argument first in case it starts with a % conditional. Then we check (and perhaps drop) an ``m'' from the -% value andassign the result to \cs{f@series}. +% value and assign the result to \cs{f@series}. % \changes{v1.0d}{2020/02/27}{Drop ``m'' only in a specific set of values (gh/293)} % \begin{macrocode} \edef\f@series{#1}% @@ -916,6 +1056,30 @@ } % \end{macrocode} % \end{macro} +% +% +% +% Supporting rollback \ldots +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\merge@font@series}{Merge series values}% +% +%\let\merge@font@series\@undefined +%\let\merge@font@series@\@undefined +%\let\@font@shape@subst@warning\@undefined +%\let\merge@font@series@without@substitution\@undefined +%\let\merge@font@series@without@substitution@\@undefined +%\let\delayed@merge@font@series\@undefined +%\let\maybe@load@fontshape\@undefined +%\let\set@target@series\@undefined +%\let\series@maybe@drop@one@m\@undefined +%\let\series@drop@one@m\@undefined +% +%\EndIncludeInRelease +% \end{macrocode} + @@ -925,6 +1089,12 @@ % that is desirable), essentially building in an ``sc'' % axis). % +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/02/02}% +% {\DeclareFontShapeChangeRule}{Font shape change rules}% +% \end{macrocode} +% % % % \begin{macro}{\DeclareFontShapeChangeRule} @@ -948,8 +1118,9 @@ % resets everything and \texttt{up} changes italic or slanted to % upright and \texttt{ulc} undoes small caps. % -% So we now offer \cs{normalshape} (using \cs{shapedefault} which is normally the same as -% calling both \cs{ulcshape} and \cs{upshape}, only more efficient. +% So we now offer \cs{normalshape} (using \cs{shapedefault} which +% is normally the same as calling both \cs{ulcshape} and +% \cs{upshape}, only more efficient. % % % \begin{macro}{\ulcshape} @@ -1080,7 +1251,7 @@ % \texttt{n}. This is the way \texttt{fontspec} implemented its % version on this interface, so this rule means we are also % compatible with the way \texttt{fontspec} behaved. Still it -% remains an odditywhic I would rather liked to have avoided. +% remains an oddity which I would rather liked to have avoided. % \begin{macrocode} %\DeclareFontShapeChangeRule {sc}{up} {sc} {} \DeclareFontShapeChangeRule {sc}{up} {n} {} @@ -1100,7 +1271,7 @@ % \texttt{ulc} in \cs{f@series} which most certainly doesn't % exist. So when a font is later selected that would result in a % substitution (so no harm done really). Alternatively, we could in -% this case use \texttt{n} as aternative, which may be a bit +% this case use \texttt{n} as alternative, which may be a bit % faster, but such a setup would be so weird in the first place % that this isn't worth the effort. % @@ -1134,26 +1305,97 @@ \DeclareFontShapeChangeRule {sw}{up} {n} {} % \end{macrocode} % +% Supporting rollback \ldots +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\DeclareFontShapeChangeRule}{Font shape change rules}% +% +%\let\DeclareFontShapeChangeRule\@undefined +%\let\ulcshape\@undefined +%\let\ulcdefault\@undefined +%\let\swshape\@undefined +%\let\swdefault\@undefined +%\let\sscshape\@undefined +%\let\sscdefault\@undefined +% +%\EndIncludeInRelease +% \end{macrocode} +% % % \subsection{Changing to a new shape} % +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\fontshape}{Font shape change}% +% \end{macrocode} +% +% +% % \begin{macro}{\fontshape} % Again the \cs{fontshape} now has to do a lookup to get to its new % value in \cs{f@shape}. The method is exactly the same as in % \cs{fontseries}. +% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)} % \begin{macrocode} -\DeclareRobustCommand\fontshape[1]{\merge@font@shape{#1}} +\DeclareRobustCommand\fontshape[1] + {\expandafter\def\expandafter\delayed@f@adjustment\expandafter + {\delayed@f@adjustment\delayed@merge@font@shape{#1}}} % \end{macrocode} % \end{macro} % % % \begin{macro}{\fontshapeforce} % The unconditional version: +% +% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)} % \begin{macrocode} -\DeclareRobustCommand\fontshapeforce[1]{\edef\f@shape{#1}} +\DeclareRobustCommand\fontshapeforce[1] + {\expandafter\def\expandafter\delayed@f@adjustment\expandafter + {\delayed@f@adjustment\edef\f@shape{#1}}} % \end{macrocode} % \end{macro} % +% +% Supporting rollback \ldots +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{2020/02/02}% +% {\fontshape}{Font shape change}% +% +%\DeclareRobustCommand\fontshape[1]{\merge@font@shape{#1}} +%\DeclareRobustCommand\fontshapeforce[1]{\edef\f@shape{#1}} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\fontshape}{Font shape change}% +% +%\DeclareRobustCommand\fontshape [1]{\edef\f@shape{#1}} +%\let\fontshapeforce\@undefined +% +%\EndIncludeInRelease +% \end{macrocode} +% + + + + + +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2020/02/02}% +% {\merge@font@shape}{Font shape change rules}% +% \end{macrocode} +% +% +% % \begin{macro}{\merge@font@shape} % Look up the database entry (if existing) and act accordingly. % \begin{macrocode} @@ -1178,9 +1420,12 @@ \ifx\reserved@a\@empty \edef\f@shape{#2}% \else - \maybe@load@fontshape +% \end{macrocode} +% \cs{reserved@a} is used in \cs{@font@shape@subst@warning} so we +% have to define it in addition to do the \cs{ifcsname} test +% \begin{macrocode} \edef\reserved@a{\f@encoding /\f@family /\f@series/#1}% - \ifcsname \reserved@a\endcsname + \ifcsname \reserved@a\endcsname \edef\f@shape{#1}% \else \ifcsname \f@encoding /\f@family /\f@series/#2\endcsname @@ -1197,6 +1442,38 @@ % \end{macro} % % +% \begin{macro}{\merge@font@shape@without@substitution, +% \merge@font@shape@without@substitution@, +% \delayed@merge@font@shape} +% See definition of \cs{selectfont} for how these macros are used. +% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)} +% \begin{macrocode} +\def\merge@font@shape@without@substitution#1{% + \expandafter\expandafter\expandafter + \merge@font@shape@without@substitution@ + \csname shape@\f@shape @#1\endcsname + {#1}% + \@nil +} +% \end{macrocode} +% +% \begin{macrocode} +\def\merge@font@shape@without@substitution@#1#2#3\@nil{% + \def\reserved@a{#3}% + \ifx\reserved@a\@empty + \edef\f@shape{#2}% + \else + \edef\f@shape{#1}% + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\let\delayed@merge@font@shape\merge@font@shape@without@substitution +% \end{macrocode} +% \end{macro} +% +% % % \begin{macro}{\normalshape} % @@ -1255,52 +1532,41 @@ % \end{macrocode} % \end{macro} % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Supporting rollback \ldots % \begin{macrocode} % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\DeclareFontSeriesChangeRule}{Series change rules}% +% {\merge@font@shape}{Font shape change rules}% % -%\DeclareRobustCommand\fontseries[1]{\edef\f@series{#1}} %\DeclareRobustCommand\fontshape [1]{\edef\f@shape{#1}} -%\let\fontseriesforce\@undefined %\let\fontshapeforce\@undefined % -%\let\DeclareFontSeriesChangeRule\@undefined -%\let\merge@font@series\@undefined -%\let\merge@font@series@\@undefined -%\let\@font@shape@subst@warning\@undefined -%\let\maybe@load@fontshape\@undefined -%\let\set@target@series\@undefined -%\let\series@maybe@drop@one@m\@undefined -%\let\series@drop@one@m\@undefined -%\let\DeclareFontShapeChangeRule\@undefined %\let\merge@font@shape\@undefined %\let\merge@font@shape@\@undefined +% +%\let\merge@font@shape@without@substitution\@undefined +%\let\merge@font@shape@without@substitution@\@undefined +%\let\delayed@merge@font@shape\@undefined +% %\let\normalshape\@undefined -%\let\ulcshape\@undefined -%\let\ulcdefault\@undefined -%\let\swshape\@undefined -%\let\swdefault\@undefined -%\let\sscshape\@undefined -%\let\sscdefault\@undefined -%\let\normalshape\@undefined +% % \end{macrocode} % This is always called in \cs{document} so don't make it undefined. % \begin{macrocode} % %\let\reinstall@nfss@defs\relax %\EndIncludeInRelease -%<*2ekernel> % \end{macrocode} % +% +% % This initializes the 2020/02/02 extensions to NFSS after any changes % in the preamble. % \changes{v1.0g}{2020/08/21}{Integration of new hook management interface} % \begin{macrocode} -% %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% % {\reinstall@nfss@defs}{NFSS series init}% diff --git a/Master/texmf-dist/source/latex/base/ltfssbas.dtx b/Master/texmf-dist/source/latex/base/ltfssbas.dtx index 30f500b6e4e..df265d0b0fc 100644 --- a/Master/texmf-dist/source/latex/base/ltfssbas.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssbas.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2020/12/10 v3.2h LaTeX Kernel (NFSS Basic Macros)] + [2021/04/26 v3.2i LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -896,15 +896,35 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/02/02}% -% {\usefont}{Drop m in usefont}% +%\IncludeInRelease{2021/06/01}% +% {\usefont}{Force font face}% \DeclareRobustCommand\usefont[4]{\fontencoding{#1}% \edef\f@family{#2}% \set@target@series{#3}% - \edef\f@shape{#4}\selectfont + \edef\f@shape{#4}% +% \end{macrocode} +% Any earlier \cs{fontseries}, etc.\ should be canceled and we +% should switch unconditionally to the requested font face so we +% drop any code that may have been stored in +% \cs{delayed@f@adjustment}. +% \changes{v3.2i}{2021/04/26}{Unconditionally switch to the requested +% font face (gh/444)} +% \begin{macrocode} + \let\delayed@f@adjustment\@empty + \selectfont \ignorespaces} % %\EndIncludeInRelease +%\IncludeInRelease{2020/02/02}% +% {\usefont}{Drop m in usefont}% +% +%\DeclareRobustCommand\usefont[4]{\fontencoding{#1}% +% \edef\f@family{#2}% +% \set@target@series{#3}% +% \edef\f@shape{#4}\selectfont +% \ignorespaces} +% +%\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% % {\usefont}{Drop m in usefont}% % @@ -1403,7 +1423,7 @@ % The idea for this macro is stolen from the \texttt{substitutefont} % package by Günter Milde, with some modifications and a new name. % -% Its purpose is to provide characters in a special encoding tht +% Its purpose is to provide characters in a special encoding that % are not available in the current font family to be taken from a % different family that is visually compatible (or not if you % choose badly). For example, you can match the GFS Didot Greek @@ -1422,7 +1442,7 @@ % %<*2ekernel|latexrelease> %\IncludeInRelease{2020/02/02}% -% {\DeclareFontFamilySubstitution}{Provide family substituation}% +% {\DeclareFontFamilySubstitution}{Provide family substitution}% \begingroup \nfss@catcodes \gdef\DeclareFontFamilySubstitution#1#2#3{% @@ -1432,7 +1452,7 @@ % is better to handle that differently. % % Of course the families may still need loading at -% this point and so we arange for this. Otherwise we might run into +% this point and so we arrange for this. Otherwise we might run into % trouble because the necessary \cs{DeclareFontFamily} has not been % seen. % \begin{macrocode} @@ -1476,7 +1496,7 @@ % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\DeclareFontFamilySubstitution}{Provide family substituation}% +% {\DeclareFontFamilySubstitution}{Provide family substitution}% % %\let\DeclareFontFamilySubstitution\@undefined %\EndIncludeInRelease @@ -1503,11 +1523,11 @@ \noexpand\@nil}% % \end{macrocode} % Initialize all those internal variables which may or may not have -% values in the first seconds of NFSS' bootstraping process. Later +% values in the first seconds of NFSS' bootstrapping process. Later % on such values will be updated when an encoding is selected, etc. % % We definitely don't want to set |\f@encoding|; we can set all the -% others since if they are left ``blank'' any selection would grap +% others since if they are left ``blank'' any selection would grab % ``error default values'' as well. However, this probably should % go also---and now it did. % \changes{v2.1n}{1994/05/14}{Don't set \cs{f@encoding}} @@ -1559,7 +1579,7 @@ % \begin{macrocode} % %\IncludeInRelease{2015/01/01}{\wrong@fontshape}% -% {Font substituation in preamble}% +% {Font substitution in preamble}% %<*2ekernel|latexrelease> \def\wrong@fontshape{% \csname D@\f@encoding\endcsname % install defaults if in math @@ -1600,9 +1620,9 @@ % corresponding \texttt{.fd} file may not been loaded % yet. Therefore we try this now. Otherwise equating the requested % font shape with the finally selected fontshape below will fail -% and can result in ``NFSS tables corruped''. After begin document +% and can result in ``NFSS tables corrupted''. After begin document % that will not happen as all \texttt{.fd} files involved in -% substituation are loaded at |\begin{document}|. +% substitution are loaded at |\begin{document}|. % \begin{macrocode} \begingroup \try@load@fontshape @@ -1681,7 +1701,7 @@ % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}{\wrong@fontshape}% -% {Font substituation in preamble}% +% {Font substitution in preamble}% %\def\wrong@fontshape{% % \csname D@\f@encoding\endcsname % \edef\reserved@a{\csname\curr@fontshape\endcsname}% @@ -1856,7 +1876,7 @@ % it modifies the corresponding macro |\mv@|\meta{version} % so that it calls |\getanddefine@fonts| directly in future as well. % We use the macro |\extract@alph@from@version| to do this. -% It takes the math alphabet identifer |#1| and the math version +% It takes the math alphabet identifier |#1| and the math version % macro as arguments. % \changes{v1.9a}{1992/07/26}{} % \begin{macrocode} @@ -1944,7 +1964,7 @@ \use@mathgroup##1{#2}}}% % \end{macrocode} % \changes{v2.1t}{1994/10/15}{Warn if math alpha is used outside math} -% In addtion it defines the alphabet the way it should be used from +% In addition it defines the alphabet the way it should be used from % now on. % \begin{macrocode} \gdef#3{\relax\ifmmode \else \non@alpherr#3\fi diff --git a/Master/texmf-dist/source/latex/base/ltfsscmp.dtx b/Master/texmf-dist/source/latex/base/ltfsscmp.dtx index 8583fb1a9b4..03be855127d 100644 --- a/Master/texmf-dist/source/latex/base/ltfsscmp.dtx +++ b/Master/texmf-dist/source/latex/base/ltfsscmp.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -36,7 +36,7 @@ % % \ProvidesFile{ltfsscmp.dtx} - [2015/06/23 v3.0f LaTeX Kernel (NFSS1 Compatibility)] + [2020/12/05 v3.0f LaTeX Kernel (NFSS1 Compatibility)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -181,7 +181,7 @@ \in@{pt}{#3}% not a proof but a good chance \ifin@ % \end{macrocode} -% We grap also everything after pt and discard it if people have +% We grab also everything after pt and discard it if people have % forgotten to place a percent sign there. % \changes{v2.1d}{1994/02/10}{scan away stuff after pt} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltfssdcl.dtx b/Master/texmf-dist/source/latex/base/ltfssdcl.dtx index 291cd1368f2..9710d543829 100644 --- a/Master/texmf-dist/source/latex/base/ltfssdcl.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssdcl.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -36,7 +36,7 @@ % % \ProvidesFile{ltfssdcl.dtx} - [2020/03/19 v3.0v LaTeX Kernel (NFSS Declarative Interface)] + [2021/02/15 v3.0w LaTeX Kernel (NFSS Declarative Interface)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -490,7 +490,11 @@ in version \math@version}% \@eha \fi - \else \expandafter\non@alpherr\fi +% \end{macrocode} +% extra \cs{expandafter} to remove the \cs{expandafter} added below +% \changes{v3.0w}{2021/02/115}{fix for (gh/501)} +% \begin{macrocode} + \else \expandafter\expandafter\expandafter\non@alpherr\fi % \end{macrocode} % If the legacy interface is used, e.g., \verb=$\sf -1$= the math % alphabet \verb=#1= does not take an argument so we better do not @@ -747,7 +751,7 @@ \@font@info{Redeclaring symbol font `#1'}% % \end{macrocode} % \changes{v3.0f}{1997/11/13} -% {(DPC) Really update \cs{group@list} dont +% {(DPC) Really update \cs{group@list} don't % leave new version in \cs{toks@}. latex/2661} % Update the group list. % \begin{macrocode} @@ -1526,7 +1530,7 @@ \def\set@mathdelimiter#1#2#3#4#5#6{% % \end{macrocode} % We use \cs{protected} not \cs{MakeRobust} so that -% \verb=\bigl\lfoor= etc.\ works inside \cs{protected@edef}. +% \verb=\bigl\lfoor= etc.\ works inside the argument of \cs{protected@edef}. % \changes{v3.0s}{2019/08/27}{Make math delimiters robust} % \changes{v3.0t}{2020/01/20}{fix for gh/251} % \begin{macrocode} @@ -1733,7 +1737,7 @@ \relax % \end{macrocode} % If it is undefined, fine otherwise check if it is a math alphabet -% defined via |\DeclareSymbolFontAlphabet|: +% defined via \\ |\DeclareSymbolFontAlphabet|: % \begin{macrocode} \else \edef\reserved@a{% diff --git a/Master/texmf-dist/source/latex/base/ltfssini.dtx b/Master/texmf-dist/source/latex/base/ltfssini.dtx index fbea725c1df..b06fc161b08 100644 --- a/Master/texmf-dist/source/latex/base/ltfssini.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssini.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -36,7 +36,7 @@ % % \ProvidesFile{ltfssini.dtx} - [2020/10/08 v3.2e LaTeX Kernel (NFSS Initialisation)] + [2021/04/26 v3.2h LaTeX Kernel (NFSS Initialisation)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -56,7 +56,7 @@ % % \GetFileInfo{ltfssini.dtx} % \title{A new font selection scheme for \TeX{} macro packages\\ -% (Initialisation)\thanks +% (Initialization)\thanks % {This file has version number % \fileversion\ dated \filedate}} % @@ -83,7 +83,7 @@ % \changes{v3.1d}{2019/08/27}{Make various commands robust} % % -% \section{NFSS Initialisation} +% \section{NFSS Initialization} % % \iffalse %<+checkmem>\CHECKMEM @@ -301,7 +301,7 @@ \else % \end{macrocode} % -% \changes{v3.1g}{2020/02/05}{Clarrified error text} +% \changes{v3.1g}{2020/02/05}{Clarified error text} % \begin{macrocode} \@latex@error{Wrong syntax for \string\DeclareFontSeriesDefault}% {Mandatory first argument must be 'md' or 'bf'.} @@ -431,7 +431,7 @@ %<+debug> \series@change@debug{No series preparation (forced \f@series)\on@line}% \fontfamily#2% \else -%<+debug> \series@change@debug{Prepearing for switching to #1 (#2)\on@line}% +%<+debug> \series@change@debug{Preparing for switching to #1 (#2)\on@line}% \expand@font@defaults % \end{macrocode} % We prepare for changing the current series. We have to find it @@ -448,7 +448,7 @@ % \item \cs{bfseries} is called for a family using \texttt{bx} % (e.g., CMR) % \item Switch to a font family that is none of the meta -% families, e.g., via \verb=\fontfamily{ptm}\selectfont= +% families, e.g., via \verb=\fontfamily{ptm}\allowbreak\verb=\selectfont= % \item Then none of the real meta families, match but the final % \verb=\@elt{??}= will. % \item Therefore if the current series is \cs{mddefault} or @@ -493,7 +493,7 @@ % \end{macrocode} % The \cs{target@series@value} may contain something like % \texttt{cm} (coming from a default) and so we can't directly -% asign it to \cs{f@series} be have to drop any surplus \texttt{m} +% assign it to \cs{f@series} be have to drop any surplus \texttt{m} % first. % \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from % \cs{target@series@value} (gh/291)} @@ -513,7 +513,7 @@ % In this macro used in the look you basically find the nested % \cs{ifx}s from the outline above. The only difference is that is % it is parameterized instead of being written out and only for one -% block of tests because the code is called reatedly when looping +% block of tests because the code is called repeatedly when looping % over the meta family list. From the list we get each meta family % name in turn. % \begin{macrocode} @@ -665,7 +665,7 @@ % the now current series value (in \cs{f@series}). % % But what should happen if \cs{seriesdefault} got explicitly -% changed? In that case the explicit change should surive and we +% changed? In that case the explicit change should survive and we % should not alter \cs{seriesdefault}. This is solved by comparing % the current value of \cs{seriesdefault} with a kernel version % saved in the format and if they differ we do not call @@ -915,9 +915,9 @@ %\end{verbatim} % We have to do the testing while the current family is still % unchanged but we have to do the adjustment of the series after it -% got changed (because the new family might has different sets -% ofshapes available and we certainly don't want to see -% substituation going on. So we use \cs{target@series@value} to +% got changed (because the new family might have different sets +% of shapes available and we certainly don't want to see +% substitution going on. So we use \cs{target@series@value} to % hold the target series (if any). %\begin{verbatim} % \let\target@series@value\@empty @@ -1088,6 +1088,8 @@ % \end{macro} % % +% \changes{v3.2g}{2021/03/18} +% {Add legacy hook definitions for rollback.} % \begin{macrocode} % %\EndIncludeInRelease @@ -1140,6 +1142,9 @@ % \prepare@family@series@update{tt}\ttdefault % \@ttfamilyhook % \selectfont} +%\let\@rmfamilyhook\@empty +%\let\@sffamilyhook\@empty +%\let\@ttfamilyhook\@empty % % \end{macrocode} % @@ -1183,7 +1188,7 @@ % to different NFSS axis values it becomes important to have the % ability to determine the current context as we can no longer look % at \cs{f@series} to answer a question such as ``am I currently -% typsetting in a bold typeface?'' +% typesetting in a bold typeface?'' % % This is provided by the test \cs{IfFontSeriesContextTF}. It takes % three arguments: @@ -1221,7 +1226,7 @@ \DeclareRobustCommand\IfFontSeriesContextTF[1]{% \expand@font@defaults % \end{macrocode} -% In the beginning we haven't found the context we are loking for. +% In the beginning we haven't found the context we are looking for. % \begin{macrocode} \@font@series@contextfalse % \end{macrocode} @@ -1238,7 +1243,7 @@ \expandafter\edef\csname ??def@ult\endcsname{\f@family}% % \end{macrocode} % Then we run through the meta family list (currently containing -% just the three values) followed by the artifical meta family +% just the three values) followed by the artificial meta family % \texttt{??} and test each of them in turn using % \cs{test@font@series@context} as the testing command. % \begin{macrocode} @@ -1264,7 +1269,7 @@ % \begin{macro}{\test@font@series@context} % This tests the context (stored in \cs{requested@test@context}) -% and updates the bookean if the right context is found. +% and updates the boolean if the right context is found. % \begin{macrocode} \def\test@font@series@context#1{% % \end{macrocode} @@ -1307,8 +1312,9 @@ } % \end{macrocode} % \end{macro} - - +% +% +% % \begin{macro}{\if@font@series@context} % The boolean to signal if we found the requested font series context. % \begin{macrocode} @@ -1334,19 +1340,21 @@ %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} - - - +% +% +% +% +% % % \section{Supporting nested emphasis} % % By default \LaTeXe{} supports two levels of nested emphasis: if % the current font has an upright shape then it switches to % \cs{itshape} otherwise to \cs{eminnershape} (which defaults to -% \cs{upshape}). This means nested emphasis will ocssilate between +% \cs{upshape}). This means nested emphasis will oscillate between % italic and upright shapes. % -% Sometimes it would be nice to allow for a more lengthly sequence, +% Sometimes it would be nice to allow for a more lengthy sequence, % but instead of providing a fixed one \LaTeX{} now offers a % general mechanism that allows to define arbitrary sequences. % @@ -1377,7 +1385,7 @@ % \begin{macro}{\DeclareEmphSequence} % % \cs{DeclareEmphSequence} expects a clist of declaration. Spaces in the -% argument are dropped to avoid surious spaces in the output. The +% argument are dropped to avoid spurious spaces in the output. The % declarations are additive. At the very end the shape is reset % using |\emreset| and |\emforce| so that this case is never % skipped.\footnote{Maybe we should not add \cs{emforce} but allow @@ -1401,9 +1409,9 @@ \let\emfontdeclare@clist\@empty % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\emrest} % Reset the font to upright and upper/lower case. With the default rules % using \cs{shapedefault} does that for us but to be on the safe side we @@ -1412,12 +1420,13 @@ \DeclareRobustCommand\emreset{\upshape\ulcshape} % \end{macrocode} % \end{macro} - - - +% +% +% % \begin{macro}{\em} -% The new definition for \cs{em} (and implicitly \cs{emph} is like -% it was before if \cs{emfontdeclare@clist} is empty. +% +% The new definition for \cs{em} (and implicitly \cs{emph}) is the +% same as before as long as \cs{emfontdeclare@clist} is empty. % \begin{macrocode} \DeclareRobustCommand\em{% \@nomath\em @@ -1479,7 +1488,7 @@ % \begin{macrocode} \expandafter\ifx\csname \curr@fontshape/\f@size\em@force % \end{macrocode} -% For the comparison with \cs{ifx} we have to exand +% For the comparison with \cs{ifx} we have to expand % \cs{em@currfont} once as the relevant info is inside. % \begin{macrocode} \expandafter\endcsname @@ -1761,7 +1770,7 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/02/02}% +%\IncludeInRelease{2021/06/01}% % {\normalfont}{Add hook to \normalfont}% \DeclareRobustCommand\normalfont{% % \end{macrocode} @@ -1774,6 +1783,15 @@ \edef\f@series{\seriesdefault}% \edef\f@shape{\shapedefault}% % \end{macrocode} +% Any earlier \cs{fontseries}, etc.\ should be canceled and we +% should switch unconditionally to the requested font face so we +% drop any code that may have been stored in +% \cs{delayed@f@adjustment}. +% \changes{v3.2h}{2021/04/26}{Unconditionally switch to the requested +% font face (gh/444)} +% \begin{macrocode} + \let\delayed@f@adjustment\@empty +% \end{macrocode} % % \changes{v3.2b}{2020/08/21}{Integration of new hook management interface} % \begin{macrocode} @@ -1785,18 +1803,54 @@ \@defaultfamilyhook % hookname from 2020/02 will vanish \selectfont} % \end{macrocode} -% +% % \begin{macrocode} \let\reset@font\normalfont % \end{macrocode} % \end{macro} % \end{macro} -% +% % % % \begin{macrocode} +% \changes{v3.2g}{2021/03/18} +% {Add missing 2020/02/02 latexrelease entry.} % %\EndIncludeInRelease +% +%\IncludeInRelease{2020/10/01}% +% {\normalfont}{Add hook to \normalfont}% +% +%\DeclareRobustCommand\normalfont{% +% \fontencoding\encodingdefault +% \edef\f@family{\familydefault}% +% \edef\f@series{\seriesdefault}% +% \edef\f@shape{\shapedefault}% +% \UseHook{normalfont}% +% \@defaultfamilyhook % hookname from 2020/02 will vanish +% \selectfont} +% +%\let\reset@font\normalfont +% +%\EndIncludeInRelease +% +%\IncludeInRelease{2020/02/02}% +% {\normalfont}{Add hook to \normalfont}% +% +%\DeclareRobustCommand\normalfont{% +% \fontencoding\encodingdefault +% \edef\f@family{\familydefault}% +% \edef\f@series{\seriesdefault}% +% \edef\f@shape{\shapedefault}% +% \@defaultfamilyhook +% \selectfont} +% +%\let\reset@font\normalfont +% +%\let\@defaultfamilyhook\@empty +% +%\EndIncludeInRelease +% %\IncludeInRelease{0000/00/00}% % {\normalfont}{Add hook to \normalfont}% % @@ -1863,8 +1917,20 @@ % \changes{v3.1c}{2019/07/09}{Explicitly set some defaults} % \begin{macrocode} \fontfamily{cmr} -\fontseries{m} -\fontshape{n} +% \end{macrocode} +% +% \changes{v3.2f}{2020/12/04}{Adjust start values for series and shape (gh/444)} +% Previously the default values for series and shape were set by +% calling \cs{fontseries} and \cs{fontshape}, but their action is +% now delayed until \cs{selectfont} which isn't called inside the +% format (to avoid unnecessarily loading a font that may never get used). +% We therefore have to set \cs{f@series} and \cs{f@shape} directly instead. +% \begin{macrocode} +\def\f@series{m} % \fontseries{m} +\def\f@shape{n} % \fontshape{n} +% \end{macrocode} +% +% \begin{macrocode} \fontsize{10}{10} % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx index 055f408ceb3..c6aec105ba5 100644 --- a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx +++ b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,14 +30,14 @@ % \iffalse %%% From File: ltfsstrc.dtx %% Copyright (C) 1989-97 by Frank Mittelbach and Rainer Sch\"opf. -%% Copyright (C) 1994-97 by LaTeX3 project. All rights reserved. +%% Copyright (C) 1994-97 by LaTeX Project. All rights reserved. % -%\NeedsTeXFormat{LaTeX2e}[1995/05/16] +%\NeedsTeXFormat{LaTeX2e}[2021/06/01] %\ProvidesPackage{tracefnt} -% [2019/10/11 v3.0l Standard LaTeX package (font tracing)] +% [2020/12/22 v3.0n Standard LaTeX package (font tracing)] % \fi % \ProvidesFile{ltfsstrc.dtx} -% [2020/02/03 v3.0l LaTeX Kernel (NFSS tracing)] +% [2021/04/26 v3.0o LaTeX Kernel (NFSS tracing)] % % \iffalse %<+checkmem>\CHECKMEM @@ -190,7 +190,7 @@ % special package file named \texttt{trace.sty}.\footnote{This package % is not in distribution at the moment (and probably doesn't any % longer work). Think of this part of the code as being historical -% artefacts.} +% artifacts.} % \begin{macrocode} %<+debug> \input trace.sty % \end{macrocode} @@ -420,19 +420,25 @@ % \end{macrocode} % \end{macro} % + +% \begin{macrocode} +%<*2ekernel|latexrelease|package> +%\IncludeInRelease{2021/06/01}% +% {\selectfont}{Add hook to \selectfont}% +% \end{macrocode} +% % -% \changes{v1.0j}{1990/02/18} -% {Redefine unprotected version \cs{p@selectfont} -% instead of \cs{selectfont}.} % % % \begin{macro}{\selectfont} +% \changes{v1.0j}{1990/02/18} +% {Redefine unprotected version \cs{p@selectfont} +% instead of \cs{selectfont}.} % \changes{v1.1a}{1989/12/16}{Changed order of calls.} % \changes{v2.3f}{1994/05/12}{Use \cs{DeclareRobustCommand}} % The macro |\selectfont| is called whenever a font change must % take place. % \begin{macrocode} -%<*2ekernel|package> \DeclareRobustCommand\selectfont {% % \end{macrocode} @@ -456,6 +462,77 @@ \ifx\f@linespread\baselinestretch \else \set@fontsize\baselinestretch\f@size\f@baselineskip \fi % \end{macrocode} +% +% The series and shape updates are only prepared by +% \cs{fontseries} and \cs{fontshape} but not executed until after +% we are ready to change the font face. This way they happen after +% a possibly new family is set which is important because they +% look at the available font faces in that family and alter the +% selection based on availibility. Several calls to \cs{fontseries} +% or \cs{fontshape} are delayed in the order in which they appear, +% so that by switching them one can work around missing +% intermediate font faces and avoid substitutions. +% +% We first attempt to do the merge without any substitution. As we +% might end up with a non-existing font face we may have to restart +% and therefore save the current values of \cs{f@series} and +% \cs{f@shape} before the merge. +% +% But first we make a quick test to see if there are any delayed +% actions, because if not it is pointless to make all the +% assignments and try loading a missing fontshape. +% +% \changes{v3.0n}{2020/12/22}{Execute delayed series and shape updates (gh/444)} +% \begin{macrocode} + \ifx\delayed@f@adjustment\@empty + \else + \let\f@shape@saved\f@shape + \let\f@series@saved\f@series +% \end{macrocode} +% The we run the delayed adjustments (which is using the +% \cs{..@without@substitution} commands +% \begin{macrocode} + \delayed@f@adjustment +% \end{macrocode} +% We then check if the resulting cominbation is valid but for this +% we have to make sure the the appropiate \texttt{.fd} is loaded if +% that hasn't happened so far. +% \begin{macrocode} + \maybe@load@fontshape + \ifcsname \f@encoding/\f@family/\f@series/\f@shape \endcsname +% \end{macrocode} +% If this macro is defined then we are good and no further action +% is necessary. +% +% Otherwise the combination is not valid, so we redo the merge but +% this time with substitutions. +% \begin{macrocode} + \else + \let\f@shape\f@shape@saved + \let\f@series\f@series@saved + \let\delayed@merge@font@shape\merge@font@shape + \let\delayed@merge@font@series\merge@font@series + \delayed@f@adjustment + \let\delayed@merge@font@shape\merge@font@shape@without@substitution + \let\delayed@merge@font@series\merge@font@series@without@substitution + \fi +% \end{macrocode} +% Now the series and shape values are updated and we clear +% \cs{delayed@f@adjustment}. This is important because on the next +% execution of \cs{selectfont} we should not mistakenly redo the +% delayed actions if there wasn't any series or shape change. +% \begin{macrocode} + \let\delayed@f@adjustment\@empty + \fi +% \end{macrocode} +% If the series was forced we should now cancel that in case the +% next series change is done with some low-level setting to +% \cs{f@series}. +% \changes{v3.0o}{2021/04/26}{Unset the forced series boolean when reaching +% \cs{selectfont} (gh/444)} +% \begin{macrocode} + \@forced@seriesfalse +% \end{macrocode} % Then we generate the internal name of the font % by concatenating {\em family}, {\em series}, % {\em shape}, and current {\em size}, @@ -478,18 +555,13 @@ % \begin{macrocode} \font@name % \end{macrocode} -% If |\tracingfonts| is -% greater than 2 we also show the font switch. -% We do this before |\glb@settings| is called since this -% macro might redefine |\font@name|. -% \changes{v1.0k}{1990/03/14}{Added code for TeX3.} -% \changes{v1.0i}{1990/02/16}{Changed \cs{f@size} to \cs{lcl@currsize} -% (see fam file).} +% +% After switching fonts we run a hook, so that packages can make +% last minute alterations based on the new font (originally provided +% in \pkg{everysel} but using a different interface). +% \changes{v3.0m}{2020/12/03}{Install a hook in \cs{selectfont} (gh/444)} % \begin{macrocode} -%<*trace> - \ifnum \tracingfonts>\tw@ - \@font@info{Switching to \font@name}\fi -% + \UseHook{selectfont}% % \end{macrocode} % Finally we call |\size@update|. This macro is normally empty but % will contain actions (like setting the |\baselineskip|) that have @@ -514,11 +586,69 @@ % \end{macro} % % +% \begin{macro}{selectfont} +% Declare the hook used in selecfont in the kernel, but not +% inside the \pkg{tracefnt} package. +% \begin{macrocode} +%<-trace>\NewHook{selectfont} +% \end{macrocode} +% \end{macro} +% +% +% If |\tracingfonts| is +% greater than 2 we also show the font switch inside \cs{selectfont}. +% We do this by adding this code to the hook in the \pkg{tracefnt} package: +% macro might redefine |\font@name|. +% \begin{macrocode} +%<*trace> +\AddToHook{selectfont} + {\ifnum \tracingfonts>\tw@ + \@font@info{Switching to \font@name}\fi} +% +% \end{macrocode} +% +% +% \begin{macrocode} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% With \cs{selectfont} having different definitions in different +% kernels we also have to provide them in the \texttt{tracefnt} +% package to support rollback. In packages that works a bit +% differently and therefore we have to provide an empty block there. +% \begin{macrocode} +%\IncludeInRelease{2021/06/01}% +% {\selectfont}{Add hook to \selectfont}% +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\selectfont}{Add hook to \selectfont}% +% +%\DeclareRobustCommand\selectfont +% {% +% \ifx\f@linespread\baselinestretch \else +% \set@fontsize\baselinestretch\f@size\f@baselineskip \fi +% \xdef\font@name{% +% \csname\curr@fontshape/\f@size\endcsname}% +% \pickup@font +% \font@name +% \size@update +% \enc@update +% } +% +%\EndIncludeInRelease +% \end{macrocode} +% +% % % \begin{macro}{\set@fontsize} % The macro |\set@fontsize| does the actual work. First it assigns % new values to |\f@size|, |\f@baselineskip| and |\f@linespread|. % \begin{macrocode} +%<*2ekernel|package> \def\set@fontsize#1#2#3{% \@defaultunits\@tempdimb#2pt\relax\@nnil \edef\f@size{\strip@pt\@tempdimb}% @@ -1245,7 +1375,7 @@ % Now, we are through with the case of a simple size, except for % calling the size function. This will be handled later, as it is % the same mechanism for all types of size specification. We will -% now proceed to macors for extraction of size range specification. +% now proceed to macros for extraction of size range specification. % % % diff --git a/Master/texmf-dist/source/latex/base/lthooks.dtx b/Master/texmf-dist/source/latex/base/lthooks.dtx index 0a04c38efbd..20e172a57f2 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 -%% -%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach, -%% Phelype Oleinik & LaTeX Team +% +% Copyright (C) 2020-2021 +% Frank Mittelbach, Phelype Oleinik & LaTeX Team % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: lthooks.dtx % % \begin{macrocode} -\def\lthooksversion{v1.0h} -\def\lthooksdate{2021/01/07} +\def\lthooksversion{v1.0n} +\def\lthooksdate{2021/05/26} % \end{macrocode} % %<*driver> @@ -54,6 +54,9 @@ } \ExplSyntaxOff +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + \EnableCrossrefs \CodelineIndex \begin{document} @@ -64,10 +67,13 @@ % \fi % % -% \long\def\fmi#1{\begin{quote}\itshape FMi: #1\end{quote}} -% \long\def\pho#1{\begin{quote}\itshape PhO: #1\end{quote}} +% \providecommand\hook[1]{\texttt{#1}} +% +% \providecommand\fmi[1]{\marginpar{\footnotesize FMi: #1}} +% \providecommand\fmiinline[1]{\begin{quote}\itshape\footnotesize FMi: #1\end{quote}} +% \providecommand\pho[1]{\marginpar{\footnotesize PhO: #1}} +% \providecommand\phoinline[1]{\begin{quote}\itshape\footnotesize PhO: #1\end{quote}} % -% \newcommand\hook[1]{\texttt{#1}} % % % \title{The \texttt{lthooks} package\thanks{This package has version @@ -119,14 +125,15 @@ % % \subsection{\LaTeXe\ interfaces} % -% \subsubsection{Declaring hooks and using them in code} +% \subsubsection{Declaring hooks} % -% With two exceptions, hooks have to be declared before they can be -% used. The exceptions are hooks in environments (i.e., executed at -% \cs{begin} and \cs{end}) and hooks run when loading files, -% e.g. before and after a package is loaded, etc. Their hook names -% depend on the environment or the file name and so declaring them -% beforehand is difficult. +% With a few exceptions, hooks have to be declared before they can +% be used. The exceptions are the generic hooks for commands, +% environments (i.e., executed at \cs{begin} and \cs{end}) and +% hooks run when loading files, e.g. before and after a package is +% loaded, etc. Their hook names depend on the command, +% environment or the +% file name and so declaring them beforehand is not practical. % % % \begin{function}{\NewHook} @@ -173,6 +180,62 @@ % \end{function} % % +% \subsubsection{Special declarations for hooks} +% +% The declarations here should normally not be used. They are available +% to provide support for special use cases mainly involving +% generic command hooks. +% +% \begin{function}{\DisableHook} +% \begin{syntax} +% \cs{DisableHook} \Arg{hook} +% \end{syntax} +% After this declaration 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. +% +% This is intended to be used with generic command hooks (see +% \texttt{ltcmdhooks-doc}) as depending on the definition of the +% command such generic hooks may be unusable. If that is known, a +% package developer can disable such hooks up front. +% +% 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}{\ProvideHook} +% \begin{syntax} +% \cs{ProvideHook} \Arg{hook} +% \end{syntax} +% Like \cs{NewHook} but does nothing if the hook was previously +% declared with \cs{NewHook}. This declaration should only be used +% in special situations, e.g., when command of another package +% need to be altered and it is is not clear if for that command a +% generic hook was already explicitly declared before. +% +% Normally \cs{NewHook} should be used instead. +% \end{function} +% +% \begin{function}{\ProvideReversedHook} +% \begin{syntax} +% \cs{ProvideReversedHook} \Arg{hook} +% \end{syntax} +% Like \cs{NewReversedHook} but does nothing if the hook was +% previously declared as a reversed hook. +% \end{function} +% +% \begin{function}{\ProvideMirroredHookPair} +% \begin{syntax} +% \cs{ProvideMirroredHookPair} \Arg{hook-1} \Arg{hook-2} +% \end{syntax} +% A shorthand for +% \cs{ProvideHook}\Arg{hook-1}\cs{ProvideReversedHook}\Arg{hook-2}. +% \end{function} +% +% +% +% \subsubsection{Using hooks in code} % % % \begin{function}{\UseHook} @@ -198,7 +261,7 @@ % 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{\meta{addto-cmd}} command (e.g., +% 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 @@ -209,10 +272,12 @@ % consumed and any further attempt to add to it will result in % executing the code to be added immediately. % -% \fmi{Maybe add an error version as well?} +% \fmiinline{Maybe add an error version as well?} % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. -% A leading |.| is treated literally. +% A leading |.| is treated literally. See +% section~\ref{sec:default-label} for details. + % \end{function} % % @@ -261,9 +326,10 @@ % that label, the removal order takes action and the code is not % added. % -% If the optional argument is \texttt{*}, then all code chunks are +% If the optional \meta{label} argument is \texttt{*}, then all code chunks are % removed. This is rather dangerous as it drops code from other -% packages one may not know about! +% packages one may not know about and should therefore not by used +% by packages but only in document preambles! % % The \meta{hook} and \meta{label} can be specified using the % dot-syntax to denote the current package name. @@ -296,7 +362,7 @@ %\end{verbatim} % because that only \enquote{adds} a further empty chunk of code to % the hook. Adding \cs{normalsize} would work but that means the hook -% then contained \cs{small}\cs{normalsize} which means to font size +% then contained \cs{small}\cs{normalsize} which means two font size % changes for no good reason. % % The above is only needed if one wants to typeset several quotes in a @@ -356,10 +422,9 @@ % \meta{label} throughout the sub-packages in order to avoid % that the labels change if you internally reorganize your code. % -% Except for \cs{UseHook}, \cs{UseOneTimeHook}, \cs{IfHookEmptyTF}, and -% \cs{IfHookExistsTF} (and their \pkg{expl3} interfaces \cs{hook_use:n}, -% \cs{hook_use_once:n}, \cs{hook_if_empty:nTF}, and -% \cs{hook_if_exist:nTF}), all \meta{hook} +% Except for \cs{UseHook}, \cs{UseOneTimeHook} and \cs{IfHookEmptyTF} +% (and their \pkg{expl3} interfaces \cs{hook_use:n}, +% \cs{hook_use_once:n} and \cs{hook_if_empty:nTF}, all \meta{hook} % and \meta{label} arguments are processed in the same way: first, % spaces are trimmed around the argument, then it is fully expanded % until only character tokens remain. If the full expansion of the @@ -367,8 +432,8 @@ % token, a low-level \TeX{} error is raised (namely, the \meta{hook} is % expanded using \TeX's \cs{csname}\ldots\cs{endcsname}, as such, % Unicode characters are allowed in \meta{hook} and \meta{label} -% arguments). The arguments of \cs{UseHook}, \cs{UseOneTimeHook}, -% \cs{IfHookEmptyTF}, and \cs{IfHookExistsTF} are +% arguments). The arguments of \cs{UseHook}, \cs{UseOneTimeHook}, and +% \cs{IfHookEmptyTF} are % processed much in the same way except that spaces are not trimmed % around the argument, for better performance. % @@ -422,8 +487,7 @@ % this syntax is not available in \cs{UseHook} (and \cs{hook_use:n}) % because the hook is most of the time used outside of the package file % in which it was defined. This syntax is also not available in the hook -% conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}) and -% \cs{IfHookExistsTF} (and \cs{hook_if_exist:nTF}) because these +% conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}), because these % conditionals are used in some performance-critical parts of the hook % management code, and because they are usually used to refer to other % package's hooks, so the dot-syntax doesn't make much sense. @@ -432,7 +496,7 @@ % it in logical parts, but still use the main package name as % \meta{label}, then the \meta{default label} can be set using % \cs{SetDefaultHookLabel} or -% \cs{PushDefaultHookLabel}..\cs{PopDefaultHookLabel}. +% \cs{PushDefaultHookLabel}\verb={..}=\,\ldots\cs{PopDefaultHookLabel}. % % \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel} % \begin{syntax} @@ -595,7 +659,7 @@ % There can only be a single relation between two labels for a % given hook, % i.e., a later \cs{DeclareHookrule} overwrites any previous -% delcaration. +% declaration. % % The \meta{hook} and \meta{label} can be specified using the % dot-syntax to denote the current package name. @@ -648,9 +712,10 @@ % \item exist and be non-empty; and % \item not exist (in which case emptiness doesn't apply); % \end{itemize} -% Hooks are a bit more complicated: they have four possible states. -% A hook may exist or not, and either way it may or may not be empty. -% This means that even a hook that doesn't exist may be non-empty. +% Hooks are a bit more complicated: +% a hook may exist or not, and either way it may or may not be empty. +% This means that even a hook that doesn't exist may be non-empty and +% it can also be disabled. % % This seemingly strange state may happen when, for example, package~$A$ % defines hook \hook{A/foo}, and package $B$ adds some code to that @@ -661,11 +726,17 @@ % querying the existence of a hook doesn't imply its emptiness, neither % does the other way around. % +% Given that code or rules can be added to a hook even if it doesn't +% physically exist yet, means that a querying its existence has no +% real use case (in contrast to other variables that can only be +% update if they have already been declared). For that reason only the +% test for emptiness has a public interface. +% % A hook is said to be empty when no code was added to it, either to % its permanent code pool, or to its ``next'' token list. The hook % doesn't need to be declared to have code added to its code pool. % A hook is said to exist when it was declared with \cs{NewHook} or -% some variant thereof. Generic \hook{file} and \hook{env} hooks are +% some variant thereof. Generic hooks such as \hook{file} and \hook{env} hooks are % automatically declared when code is added to them. % % \begin{function}[EXP]{\IfHookEmptyTF} @@ -673,7 +744,8 @@ % \cs{IfHookEmptyTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{hook} is empty (\emph{i.e.}, no code was added to -% it using either \cs{AddToHook} or \cs{AddToHookNext}), and +% it using either \cs{AddToHook} or \cs{AddToHookNext}) or such code +% was removed again (via \cs{RemoveFromHook}), and % branches to either \meta{true code} or \meta{false code} depending % on the result. % @@ -681,30 +753,7 @@ % A leading |.| is treated literally. % \end{function} % -% \begin{function}[EXP]{\IfHookExistsTF} -% \begin{syntax} -% \cs{IfHookExistsTF} \Arg{hook} \Arg{true code} \Arg{false code} -% \end{syntax} -% Tests if the \meta{hook} exists (if it was created with either -% \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and -% branches to either \meta{true code} or \meta{false code} depending -% on the result. -% -% The existence of a hook usually doesn't mean much from the viewpoint -% of code that tries to add/remove code from that hook, since package -% loading order may vary, thus the creation of hooks is asynchronous -% to adding and removing code from it, so this test should be used -% sparingly. -% -% Generic hooks are declared at the time code is added to them, so the -% result of \cs{hook_if_exist:n} will change once code is added to -% said hook (unless the hook was previously declared). -% -% The \meta{hook} \emph{cannot} be specified using the dot-syntax. -% A leading |.| is treated literally. -% \end{function} % -% \fmi{Would be helpful if we provide some use cases} % % \subsubsection{Displaying hook code} % @@ -807,7 +856,7 @@ % \meta{label-2}, in that order, as detailed in \cs{DeclareHookRule}. % If the relation is \texttt{default} it means that that rule applies % to \meta{label-1} and \meta{label-2} in \emph{all} hooks, (unless -% overrided by a non-default relation). +% overridden by a non-default relation). % % Finally, line~14 lists the labels in the hook after sorting; % that is, in the order they will be executed when the hook is used. @@ -819,7 +868,7 @@ % \begin{syntax} % \cs{DebugHooksOn} % \end{syntax} -% Turn the debugging of hook code on or off. This displays changes +% Turn the debugging of hook code on or off. This displays most changes % made to the hook data structures. The output is rather coarse and % not really intended for normal use. % \end{function} @@ -856,6 +905,53 @@ % % % +% \begin{function}{\hook_disable:n} +% \begin{syntax} +% \cs{hook_disable:n} \Arg{hook} +% \end{syntax} +% Marks \Arg{hook} as disabled. Any further attempt to add code to +% it or declare it, will result in an error and any call to +% \cs{hook_use:n} will simply do nothing. +% +% This declaration is intended for use with generic hooks that are +% known not to work (see \texttt{ltcmdhooks-doc}) if they receive +% code. +% +% 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_provide:n} +% \begin{syntax} +% \cs{hook_provide:n} \Arg{hook} +% \end{syntax} +% Like \cs{hook_new:n} but does nothing if the hook was previously +% declared with \cs{hook_new:n}. This declaration should only be used +% in special situations, e.g., when a command of another package +% needs to be altered and it is is not clear if for that command a +% generic \hook{cmd} hook was already explicitly declared before. +% +% Normally \cs{hook_new:n} should be used instead. +% \end{function} +% +% \begin{function}{\hook_provide_reversed:n} +% \begin{syntax} +% \cs{hook_provide_reversed:n} \Arg{hook} +% \end{syntax} +% Like \cs{hook_new_reversed:n} but does nothing if the hook was +% previously declared as a reversed hook. +% \end{function} +% +% \begin{function}{\hook_provide_pair:nn} +% \begin{syntax} +% \cs{hook_provide_pair:nn} \Arg{hook-1} \Arg{hook-2} +% \end{syntax} +% A shorthand for +% \cs{hook_provide:n}\Arg{hook-1}\cs{hook_provide_reversed:n}\Arg{hook-2}. +% \end{function} +% +% +% % \begin{function}{\hook_use:n} % \begin{syntax} % \cs{hook_use:n} \Arg{hook} @@ -968,28 +1064,6 @@ % A leading |.| is treated literally. % \end{function} % -% \begin{function}[pTF]{\hook_if_exist:n} -% \begin{syntax} -% \cs{hook_if_exist:nTF} \Arg{hook} \Arg{true code} \Arg{false code} -% \end{syntax} -% Tests if the \meta{hook} exists (if it was created with either -% \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and -% branches to either \meta{true code} or \meta{false code} depending -% on the result. -% -% The existence of a hook usually doesn't mean much from the viewpoint -% of code that tries to add/remove code from that hook, since package -% loading order may vary, thus the creation of hooks is asynchronous -% to adding and removing code from it, so this test should be used -% sparingly. -% -% Generic hooks are declared at the time code is added to them, so the -% result of \cs{hook_if_exist:n} will change once code is added to -% said hook (unless the hook was previously declared). -% -% The \meta{hook} \emph{cannot} be specified using the dot-syntax. -% A leading |.| is treated literally. -% \end{function} % % \begin{function}{\hook_show:n,\hook_log:n} % \begin{syntax} @@ -1259,8 +1333,8 @@ % For that reason such code is not using the hook management, but % instead private kernel commands directly before or after a public % hook with the following naming -% convention: \cs{@kernel@before@\meta{hookname}} or -% \cs{@kernel@after@\meta{hookname}}. For example, in +% convention: \cs{@kernel@before@\meta{hook}} or +% \cs{@kernel@after@\meta{hook}}. For example, in % \cs{enddocument} you find %\begin{verbatim} % \UseHook{enddocument}% @@ -1336,20 +1410,14 @@ % Like \cs{AtBeginDocument} but for the \hook{enddocument} hook. % \end{function} % -% -% -% \begin{function}{\AtBeginDvi} -% \begin{syntax} -% \cs{AtBeginDvi} \oarg{label} \Arg{code} -% \end{syntax} -% This hook is discussed in conjunction with the shipout hooks. -% \end{function} +% There is also \cs{AtBeginDvi} which is discussed in conjunction +% with the shipout hooks. % % \bigskip % % The few hooks that existed previously in \LaTeXe{} used internally % commands such as \cs{@begindocumenthook} and packages sometimes -% augemented them directly rather than working through +% augmented them directly rather than working through % \cs{AtBeginDocument}. For that reason there is currently support % for this, that is, if the system detects that such an internal % legacy hook command contains code it adds it to the new hook @@ -1415,7 +1483,7 @@ % % The hooks are only executed if \cs{begin}\Arg{env} and % \cs{end}\Arg{env} is used. If the environment code is executed -% via low-level calls to \cs{\meta{env}} and \cs{end\meta{env}} +% via low-level calls to \cs[no-index]{\meta{env}} and \cs[no-index]{end\meta{env}} % (e.g., to avoid the environment grouping) they are not % available. If you want them available in code using this method, % you would need to add them yourself, i.e., write something like @@ -1458,6 +1526,38 @@ % \end{function} % % +% \subsubsection{Generic hooks for commands} +% +% Similar to environments there are now (at least in theory) two +% generic hooks available for any \LaTeX{} command. These are +% \begin{description} +% \item[\hook{cmd/\meta{name}/before}] +% +% This hook is executed at the very start of the command +% execution. +% +% \item[\hook{cmd/\meta{name}/after}] +% This hook is executed at the very end of the command body. It is +% implemented as a reversed hook. +% \end{description} +% In practice there are restrictions and especially the +% \hook{after} hook works only with a subset of commands. Details +% about these restrictions are documented in +% \texttt{ltcmdhooks-doc.pdf} or with code in +% \texttt{ltcmdhooks-code.pdf}. +% +% +% +% +% \subsubsection{Generic hooks provided by file loading operations} +% +% There are several hooks added to \LaTeX{}'s process of loading +% file via its high-level interfaces such as \cs{input}, +% \cs{include}, \cs{usepackage}, \cs{RequirePackage}, etc. These +% are documented in \texttt{ltfilehook-doc.pdf} or with code in +% \texttt{ltfilehook-code.pdf}. +% +% % % \subsubsection{Hooks provided by \cs{begin}\texttt{\{document\}}} % \label{sec:begindocument-hooks} @@ -1557,7 +1657,9 @@ % generates material for further pages. It is the right place to % do some final housekeeping and possibly write out some % information to the \texttt{.aux} file (which is still open at -% this point to receive data). It is also the correct place to +% this point to receive data, but since there will be no more pages you +% need to write to it using \cs{immediate}\cs{write}). It is also the +% correct place to % set up any testing code to be run when the \texttt{.aux} file % is re-read in the next step. % @@ -1615,7 +1717,7 @@ % % % It is in also possible to use the generic \hook{env/document/end} -% hook which is execuded by \cs{end}, i.e., just in front of the +% hook which is executed by \cs{end}, i.e., just in front of the % first hook above. Note however that the other generic \cs{end} % environment hook, i.e., \hook{env/document/after} will never get % executed, because by that time \LaTeX{} has finished the document @@ -1624,7 +1726,7 @@ % % % -% \subsubsection{Hooks provided \cs{shipout} operations} +% \subsubsection{Hooks provided by \cs{shipout} operations} % \label{sec:shipout} % % There are several hooks and mechanisms added to \LaTeX{}'s @@ -1633,14 +1735,6 @@ % \texttt{ltshipout-code.pdf}. % % -% \subsubsection{Hooks provided by file loading operations} -% -% There are several hooks added to \LaTeX{}'s -% process of loading file via its high-level interfaces such as -% \cs{input}, \cs{include}, \cs{usepackage}, etc. These are documented in -% \texttt{ltfilehook-doc.pdf} or with code in -% \texttt{ltfilehook-code.pdf}. -% % % \subsubsection{Hooks provided in NFSS commands} % @@ -1709,27 +1803,20 @@ % \section{The Implementation} % % -% \subsection{Loading further extensions} -% % \begin{macrocode} %<@@=hook> % \end{macrocode} % +% \changes{v1.0i}{2021/03/18}{Use \cs{NewModuleRelease}.} +% \changes{v1.0n}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} % -% At the moment the whole module rolls back in one go, but if we -% make any modifications in later releases this will then need -% splitting. % \begin{macrocode} %<*2ekernel|latexrelease> -%\IncludeInRelease{2020/10/01}% -% {\NewHook}{The hook management}% -% \end{macrocode} -% -% \begin{macrocode} \ExplSyntaxOn +%\NewModuleRelease{2020/10/01}{lthooks} +% {The~hook~management~system} % \end{macrocode} % -% % \subsection{Debugging} % % \begin{macro}{\g_@@_debug_bool} @@ -1772,9 +1859,11 @@ % % \begin{macro}[EXP]{\@@_str_compare:nn} % Private copy of \cs{__str_if_eq:nn} +% \InternalDetectionOff % \begin{macrocode} \cs_new_eq:NN \@@_str_compare:nn \__str_if_eq:nn % \end{macrocode} +% \InternalDetectionOn % \end{macro} % % \subsection{Declarations} @@ -1857,8 +1946,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x} -% Some variants of \pkg{expl3} functions. \fmi{should be moved to expl3} +% \begin{macro}[int]{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x} +% 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 } @@ -1950,25 +2040,30 @@ % \end{macro} % % +% % \subsection{Providing new hooks} % -% \begin{macro}{\g_@@_..._code_prop,\@@~...,\@@_next~...} +% \subsubsection{The data structures of a hook} % -% Hooks have a \meta{name} and for each hook we have to provide a number of -% data structures. These are +% \DescribeMacro{\g_@@_\meta{hook}_code_prop} +% \DescribeMacro{\@@\textvisiblespace\meta{hook}} +% \DescribeMacro{\@@_next\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 % \begin{description} -% \item[\cs{g_@@_\meta{name}_code_prop}] A property list holding the code +% \item[\cs{g_@@_\meta{hook}_code_prop}] A property list holding the code % for the hook in separate chunks. The keys are by default the % package names that add code to the hook, but it is possible % for packages to define other keys. % -% \item[{\cs[no-index]{g_@@_\meta{name}_rule_\meta{label1}\string|\meta{label2}_tl}}] +% \item[{\cs[no-index]{g_@@_\meta{hook}_rule_\meta{label1}\string|\meta{label2}_tl}}] % A token list holding the relation between \meta{label1} and -% \meta{label2} in the \meta{name}. The \meta{labels} are lexically +% \meta{label2} in the \meta{hook}. The \meta{labels} are lexically % (reverse) sorted to ensure that two labels always point to the same -% token list. For global rules, the \meta{name} is |??|. +% token list. For global rules, the \meta{hook} name is |??|. % -% \item[\cs{@@~\meta{name}}] The code that is actually executed +% \item[\cs{@@\textvisiblespace\meta{hook}}] The code that is actually executed % when the hook is called in the document is stored in this token % list. It is constructed from the code chunks applying the % information. @@ -1977,54 +2072,194 @@ % and to make it simpler to normalize hook names in % \cs{@@_make_name:n}. % -% \item[\cs{g_@@_\meta{name}_reversed_tl}] Some hooks are +% \item[\cs{g_@@_\meta{hook}_reversed_tl}] Some hooks are % \enquote{reversed}. This token list stores a |-| for such hook % so that it can be identified. The |-| character is used because % $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed % ones. + +% \item[{\cs[no-index]{g_@@_\meta{hook}_declared_tl}}] This token +% list serves as marker for the hook being officially declared. Its +% existence is tested to raise an error in case another declaration +% is attempted. % -% \item[\cs{@@_toplevel~\meta{name}}] This token list stores the code +% \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. % Instead, all code is appended to it and executed after (or before, % if the hook is reversed) the normal % hook code, but before the |next| code chunk. % -% \item[\cs{@@_next~\meta{name}}] Finally there is extra code -% (normally empty) that is used on the next invocation of the hook -% (and then deleted). This can be used to define some special -% behavior for a single occasion from within the document. This token -% list follows the same naming scheme than the main \cs{@@~\meta{name}} -% token list. It is called \cs{@@_next~\meta{name}} rather than -% \cs{@@~next_\meta{name}} because otherwise a hook whose name is -% |next_|\meta{name} would clash with the next code-token list of the -% hook called \meta{name}. +% \item[\cs{@@_next\textvisiblespace\meta{hook}}] Finally there is +% extra code (normally empty) that is used on the next invocation +% of the hook (and then deleted). This can be used to define some +% special behavior for a single occasion from within the document. +% This token list follows the same naming scheme than the main +% \cs{@@\textvisiblespace\meta{hook}} token list. It is called +% \cs{@@_next\textvisiblespace\meta{hook}} rather than +% \cs[no-index]{@@\textvisiblespace next_\meta{hook}} because +% otherwise a hook whose name is |next_|\meta{hook} would clash +% with the next code-token list of the hook called \meta{hook}. % % \end{description} -% \end{macro} % % +% \subsubsection{On the existence of hooks} +% \label{sec:existence} +% +% A hook may be in different states of existence. Here we give an +% overview of internal commands to set up hooks and explain how the +% different states are distinguished. The actual implementation +% then follows in the next sections. % +% One problem we have to solve is, that we need to be able to add +% code to hooks (e.g., with \cs{AddToHook}) even if that code has +% not been declared yet. For example, one package needs to write +% into a hook of another package, but that package ay not get +% loaded or only loaded later. Another problem most hooks require +% declaration but this is not the case for the generic hooks. % -% \begin{macro}{\hook_new:n} -% The \cs{hook_new:n} declaration declare a new hook and expects +% We therefore distinguish the following states for a hook and they +% are managed with four different tests: structure existence +% (\cs{@@_if_structure_exist:nTF}), creation +% (\cs{@@_if_usable:nTF}), declaration (\cs{@@_if_declared:nTF}) +% and disabled or not (\cs{@@_if_disabled:nTF}) +% \begin{description} +% \setlist[itemize]{leftmargin=5cm,format=\cs} +% \item[not existing] +% +% Nothing is known about the hook so far. This state can be +% detected with \cs{@@_if_structure_exist:nTF} +% (which uses the false branch). +% +% In this state the hook can be declared, disabled, rules can be +% defined or code could be added to it, but it is not possible +% to use the hook (with \cs{UseHook}). + +% \item[basic data structure set up] +% +% A hook is this state when its basic data structure has been +% set up (using \cs{@@_init_structure:n}). The data structure setup happens +% automatically when commands such as \cs{AddToHook} are used +% and the hook is at that point in state \enquote{not existing}. +% +% In this state the four tests give the following results: +% \begin{itemize} +% \item [@@_if_structure_exist:nTF] returns |true|. +% \item [@@_if_usable:nTF] returns |false|. +% \item [@@_if_declared:nTF] returns |false|. +% \item [@@_if_disabled:nTF] returns |false|. +% \end{itemize} +% +% The allowed acctions are the same as in the \enquote{not +% existing} state. +% +% \item[declared] +% +% A hook is in this state it is not disabled and was explicity declared (e.g., +% with \cs{NewHook}). In this case the four tests give the +% following results: +% \begin{itemize} +% \item [@@_if_structure_exist:nTF] returns |true|. +% \item [@@_if_usable:nTF] returns |true|. +% \item [@@_if_declared:nTF] returns |true|. +% \item [@@_if_disabled:nTF] returns |false|. +% \end{itemize} +% +% \item[usable] +% +% A hook is in this state if it is not disabled, was not +% explicitly declared but nevertheless is allowed to be used +% (with \cs{UseHook} or \cs{hook_use:n}). This state is only +% possible for generic hooks as they do not need to be +% declared. Therefore such hooks move directly from state +% \enquote{not existing} to \enquote{usable} the moment a +% declaration such as \cs{AddToHook} wants to add to the hook +% data structure. In this state the tests give the following +% results: +% \begin{itemize} +% \item [@@_if_structure_exist:nTF] returns |true|. +% \item [@@_if_usable:nTF] returns |true|. +% \item [@@_if_declared:nTF] returns |false|. +% \item [@@_if_disabled:nTF] returns |false|. +% \end{itemize} +% +% +% \item[disabled] +% +% A hook in any state is moved to this state when +% \cs{DisableHook} is used. This changes the tests to give the +% following results: +% \begin{itemize} +% \item [@@_if_structure_exist:nTF] \emph{unchanged}. +% \item [@@_if_usable:nTF] returns |false|. +% \item [@@_if_declared:nTF] returns |true|. +% \item [@@_if_disabled:nTF] returns |true|. +% \end{itemize} +% The structure test is unchanged (if the hook was unknown before it is +% false, otherwise true). The usable test returns false so that +% any \cs{UseHook} will bypass the hook from now on. The +% declared test returns true so that any further \cs{NewHook} +% generates an error and the disabled test returns true so that +% \cs{AddToHook} can return an error. +% \fmiinline{maybe it should do this only after begin document?} +% +% \end{description} +% +% +% +% +% \subsubsection{Setting hooks up} +% +% +% \begin{macro}{\hook_new:n,\@@_new:n} +% The \cs{hook_new:n} declaration declares a new hook and expects % the hook \meta{name} as its argument, e.g., % \hook{begindocument}. % \begin{macrocode} \cs_new_protected:Npn \hook_new:n #1 { \@@_normalize_hook_args:Nn \@@_new:n {#1} } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_new:n #1 { % \end{macrocode} -% We check for one of the internal data structures and if it -% already exists we complain. +% 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. % \begin{macrocode} - \hook_if_exist:nTF {#1} + \@@_if_declared:nTF {#1} { \msg_error:nnn { hooks } { exists } {#1} } + { + \tl_new:c { g_@@_#1_declared_tl } + \@@_make_usable:n {#1} + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_make_usable:n} +% +% 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. +% \begin{macrocode} +\cs_new_protected:Npn \@@_make_usable:n #1 + { % \end{macrocode} -% Otherwise we add the hook name to the list of all hooks and -% allocate the necessary data structures for the new hook. +% Now we check if the hook's data structure can be safely created +% without \pkg{expl3} raising errors, then +% we add the hook name to the list of all hooks and +% allocate the necessary data structures for the new hook, +% otherwise just do nothing. % \begin{macrocode} + \tl_if_exist:cF { @@~#1 } { \seq_gput_right:Nn \g_@@_all_seq {#1} % \end{macrocode} @@ -2035,12 +2270,12 @@ % \end{macrocode} % Now ensure that the base data structure for the hook exists: % \begin{macrocode} - \@@_declare:n {#1} + \@@_init_structure: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. % \begin{macrocode} - \clist_new:c {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 @@ -2062,23 +2297,30 @@ % % \begin{macrocode} \@@_include_legacy_code_chunk:n {#1} - } + } } % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_declare:n} -% This function declares the basic data structures for a hook without -% actually declaring the hook itself. This is needed to allow adding -% to undeclared hooks. Here it is unnecessary to check whether all -% variables exist, since all three are declared at the same time -% (either all of them exist, or none). +% \begin{macro}{\@@_init_structure:n} +% This function declares the basic data structures for a hook +% without explicit declaring the hook itself. This is needed to +% allow adding to undeclared hooks. Here it is unnecessary to +% check whether all variables exist, since all three are declared +% at the same time (either all of them exist, or none). +% +% It creates the hook code pool +% (\cs[no-index]{g_@@_\meta{hook}_code_prop}) and the |top-level| +% and |next| token lists. A hook is initialized with +% \cs{@@_init_structure:n} the first time anything is added to it. +% Inizializing a hook just with \cs{@@_init_structure:n} will not +% make it usable with \cs{hook_use:n}. % \begin{macrocode} -\cs_new_protected:Npn \@@_declare:n #1 +\cs_new_protected:Npn \@@_init_structure:n #1 { - \@@_if_exist:nF {#1} + \@@_if_structure_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } \tl_new:c { @@_toplevel~#1 } @@ -2110,6 +2352,9 @@ % \end{macrocode} % \end{macro} % +% +% +% % \begin{macro}{\hook_new_pair:nn} % A shorthand for declaring a normal and a (matching) reversed hook in one go. % \begin{macrocode} @@ -2160,6 +2405,140 @@ % % % +% \subsubsection{Disabling and providing hooks} +% +% \begin{macro}{\hook_disable:n} +% \begin{macro}{\@@_disable:n} +% \begin{macro}[pTF]{\@@_if_disabled:n} +% +% Disables a hook by creating its +% \cs[no-index]{g_@@_\meta{hook}_declared_tl} so that the hook +% errors when used with \cs{hook_new:n}, then it undefines +% \cs{@@\textvisiblespace\meta{hook}} so that it may not be executed. +% +% This does not clear any code that may be already stored in the +% hook's structure, but doesn't allow adding more code. +% \cs{@@_if_disabled:nTF} uses that specific combination to check +% if the hook is disabled. +% +% \begin{macrocode} +%\IncludeInRelease{2021/06/01}% +% {\hook_disable:n}{Disable~hooks} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \hook_disable:n #1 + { \@@_normalize_hook_args:Nn \@@_disable:n {#1} } +\cs_new_protected:Npn \@@_disable:n #1 + { + \tl_gclear_new:c { g_@@_#1_declared_tl } + \cs_undefine:c { @@~#1 } + } +\prg_new_conditional:Npnn \@@_if_disabled:n #1 { p, T, F, TF } + { + \bool_lazy_and:nnTF + { \tl_if_exist_p:c { g_@@_#1_declared_tl } } + { ! \tl_if_exist_p:c { @@~#1 } } + { \prg_return_true: } + { \prg_return_false: } + } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01} +% {\hook_disable:n}{Disable~hooks} +% +%\cs_new_protected:Npn \hook_disable:n #1 {} +% +%\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hook_provide:n} +% \begin{macro}{\hook_provide_reversed:n} +% \begin{macro}{\@@_provide:n} +% The \cs{hook_provide: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. +% The \cs{hook_provide_reversed:n} does the same for reversed hooks. +% \hook{begindocument}. +% \begin{macrocode} +%\IncludeInRelease{2021/06/01}% +% {\hook_provide:n}{Providing~hooks} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \hook_provide:n #1 + { \@@_normalize_hook_args:Nn \@@_provide:nn {#1} { } } +\cs_new_protected:Npn \hook_provide_reversed:n #1 + { \@@_normalize_hook_args:Nn \@@_provide:nn {#1} { - } } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_provide:nn #1 #2 + { +% \end{macrocode} +% If the hook to be provided was disabled we warn (for now --- this +% may change). +% \begin{macrocode} + \@@_if_disabled:nTF {#1} + { \msg_warning:nnn { hooks } { provide-disabled } {#1} } +% \end{macrocode} +% Otherwise we check if it was already declared. +% \begin{macrocode} + { + \@@_if_declared:nTF {#1} + { +% \end{macrocode} +% Issue an error if we try to provide a a hook that is reversed and +% the already existing one is not (or vice versa). +% \begin{macrocode} + \str_if_eq:eeF { \tl_use:c { g_@@_#1_reversed_tl } } {#2} + { \msg_error:nnn { hooks } { provide-error } {#1} } + } +% \end{macrocode} +% If it wasn't declared, we declared as a normal or reversed hook +% as appropriate. +% \begin{macrocode} + { + \tl_new:c { g_@@_#1_declared_tl } + \@@_make_usable:n {#1} + \tl_gset:cn { g_@@_#1_reversed_tl } {#2} + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hook_provide_pair:nn} +% A shorthand for providing a normal and a (matching) reversed hook in one go. +% \begin{macrocode} +\cs_new_protected:Npn \hook_provide_pair:nn #1#2 + { \hook_provide:n {#1} \hook_provide_reversed:n {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\IncludeInRelease{2020/10/01} +% {\hook_provide:n}{Providing~hooks} +% +%\cs_new_protected:Npn \hook_provide_reversed:n #1 {} +%\cs_new_protected:Npn \hook_provide:n #1 {} +%\cs_new_protected:Npn \hook_provide_pair:nn #1#2 {} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% % \subsection{Parsing a label} % % \begin{macro}[EXP]{\@@_parse_label_default:n} @@ -2231,7 +2610,7 @@ { \tl_if_empty:NTF \@currname { - \msg_expandable_error:nnn { hooks } { should-not-happen } + \msg_expandable_error:nnn { kernel } { should-not-happen } { Empty~default~label. } \@@_make_name:n { label-missing } } @@ -2243,15 +2622,15 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_make_name:n,\@@_make_name:w} -% Provides a standard sanitisation of a hook's name. +% Provides a standard sanitization of a hook's name. % It uses \cs{cs:w} to build a control sequence out of the hook name, % then uses \cs{cs_to_str:N} to get the string representation of that, % without the escape character. \cs{cs:w}-based expansion is used % instead of |e|-based because Unicode characters don't behave well -% inside \cs{expanded}. The macro adds the \cs{@@~} prefix to the +% inside \cs{expanded}. The macro adds the \cs[no-index]{@@\textvisiblespace} prefix to the % hook name to reuse the hook's code token list to build the csname % and avoid leaving \enquote{public} control sequences defined -% (as~\cs{relax}) in TeX's memory. +% (as~\cs[no-index]{relax}) in TeX's memory. % \begin{macrocode} \cs_new:Npn \@@_make_name:n #1 { @@ -2311,6 +2690,9 @@ % \end{macro} % % +% +% \subsection{Adding or removing hook code} +% % \begin{macro}{\hook_gput_code:nnn} % \begin{macro}{\@@_gput_code:nnn,\@@_gput_code:nxv,\@@_hook_gput_code_do:nnn} % @@ -2320,6 +2702,9 @@ % \begin{macrocode} \cs_new_protected:Npn \hook_gput_code:nnn #1 #2 { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3 { % \end{macrocode} @@ -2343,7 +2728,7 @@ % If no removal is queued, we are free to add. Start by checking if % the hook exists. % \begin{macrocode} - \hook_if_exist: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}= @@ -2364,10 +2749,17 @@ % declare it as a generic hook, if its name matches one of the valid % patterns. % \begin{macrocode} - { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } + { + \@@_if_disabled:nTF {#1} + { \msg_error:nnn { hooks } { hook-disabled } {#1} } + { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } + } } } } +% \end{macrocode} +% +% \begin{macrocode} \cs_generate_variant:Nn \@@_gput_code:nnn { nxv } % \end{macrocode} % @@ -2379,7 +2771,7 @@ % However, first some debugging info if debugging is enabled: % \begin{macrocode} \@@_debug:n{\iow_term:x{****~ Add~ to~ - \hook_if_exist:nF {#1} { undeclared~ } + \@@_if_usable:nF {#1} { undeclared~ } hook~ #1~ (#2) \on@line\space <-~ \tl_to_str:n{#3}} } % \end{macrocode} @@ -2387,9 +2779,9 @@ % If there's code already there, then append \verb=#3= to that, % otherwise just put \verb=#3=. If the current label is |top-level|, % the code is added to a dedicated token list -% \cs[no-index]{@@_toplevel~\meta{hook}} that goes at the end of the +% \cs{@@_toplevel\textvisiblespace\meta{hook}} that goes at the end of the % hook (or at the beginning, for a reversed hook), just before -% \cs[no-index]{@@_next~\meta{hook}}. +% \cs[no-index]{@@_next\textvisiblespace\meta{hook}}. % \begin{macrocode} \str_if_eq:nnTF {#2} { top-level } { @@ -2397,9 +2789,9 @@ { % \end{macrocode} % If the hook's basic structure does not exist, we need to declare it -% with \cs{@@_declare:n}. +% with \cs{@@_init_structure:n}. % \begin{macrocode} - \@@_declare:n {#1} + \@@_init_structure:n {#1} \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} } { \msg_error:nnn { hooks } { misused-top-level } {#1} } @@ -2424,14 +2816,15 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 { - \@@_declare:n {#1} + \@@_init_structure:n {#1} \@@_hook_gput_code_do:nnn {#1} {#2} {#3} } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_try_declaring_generic_hook:nnn} -% \begin{macro}{\@@_try_declaring_generic_next_hook:nn} +% \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 % functions to execute when some action is to be taken. @@ -2458,13 +2851,14 @@ \hook_gput_next_code:nn \@@_gput_next_do:nn } % \end{macrocode} +% \end{macro} % -% \begin{macro}{ -% \@@_try_declaring_generic_hook:nNNnn, -% \@@_try_declaring_generic_hook_split:nNNnn -% } -% \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn} -% \cs{@@_try_declaring_generic_hook:nNNnn} now splits the hook name +% +% \begin{macro}{\@@_try_declaring_generic_hook:nNNnn, +% \@@_try_declaring_generic_hook_split:nNNnn} +% +% \cs{@@_try_declaring_generic_hook:nNNnn} +% now splits the hook name % at the first \texttt{/} (if any) and first checks if it is a % file-specific hook (they require some normalization) using % \cs{@@_if_file_hook:wTF}. If not then check it is one of a @@ -2482,12 +2876,24 @@ } { \@@_try_declaring_generic_hook_split:nNNnn {#1} } } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3 { \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} { #2 } { #3 } {#1} } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn} +% +% \begin{macrocode} +%\IncludeInRelease{2021/06/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 } { @@ -2496,31 +2902,70 @@ { \prop_if_in:NnTF \c_@@_generics_prop {#1} { - \hook_if_exist:nF {#5} { \hook_new:n {#5} } + \@@_if_usable:nF {#5} + { % \end{macrocode} -% After having declared the hook we check the second component (for -% file hooks) or the third component for environment hooks) and -% if it is on the list of components for which we should have declared -% a reversed hook we alter the hook data structure accordingly. +% If the hook doesn't exist yet we check if it is a \texttt{cmd} +% hook and if so we attempt patching the command in addition to +% declaring the hook. +% +% 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. +% \begin{macrocode} + \str_if_eq:nnT {#1} { cmd } + { \@@_try_put_cmd_hook:n {#5} } +% \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. % \begin{macrocode} + \@@_make_usable:n {#5} + } \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2} { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } { \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3} { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } } -% \end{macrocode} -% Now that we know that the hook is declared we can add the code to it. -% \begin{macrocode} \prg_return_true: } { \prg_return_false: } } } +%\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%\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 } +% { +% \tl_if_empty:nTF {#2} +% { \prg_return_false: } +% { +% \prop_if_in:NnTF \c_@@_generics_prop {#1} +% { +% \@@_if_declared:nF {#5} { \hook_new:n {#5} } +% \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2} +% { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } +% { +% \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3} +% { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } +% } +% \prg_return_true: +% } +% { \prg_return_false: } +% } +% } +% +%\EndIncludeInRelease % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} % \end{macro} % % \begin{macro}[pTF]{\@@_if_file_hook:w} @@ -2529,7 +2974,7 @@ % |file/before/foo.tex|). If it is a file-specific hook, then it % executes the \meta{true} branch, otherwise \meta{false}. % -% A file-specific hook is \texttt{file/\meta{position}/\meta{name}}. +% A file-specific hook is \hook{file/\meta{position}/\meta{name}}. % If any of these parts don't exist, it is a general file hook or not % a file hook at all, so the conditional evaluates to \meta{false}. % Otherwise, it checks that the first part is |file| and that the @@ -2595,14 +3040,16 @@ % Property list holding the generic names. We don't provide any user % interface to this as this is meant to be static. % \begin{description} +% \item[\texttt{cmd}] +% The generic hooks used for commands. % \item[\texttt{env}] % The generic hooks used in \cs{begin} and \cs{end}. -% \item[\texttt{file}] +% \item[\texttt{file}, \texttt{package}, \texttt{class}, \texttt{include}] % The generic hooks used when loading a file % \end{description} % \begin{macrocode} \prop_const_from_keyval:Nn \c_@@_generics_prop - {env=,file=,package=,class=,include=} + {cmd=,env=,file=,package=,class=,include=} % \end{macrocode} % \end{macro} % @@ -2629,11 +3076,11 @@ \cs_new_protected:Npn \@@_gremove_code:nn #1 #2 { % \end{macrocode} -% First check that the hook code pool exists. \cs{hook_if_exist:nTF} +% First check that the hook code pool exists. \cs{@@_if_usable:nTF} % isn't used here because it should be possible to remove code from a % hook before its defined (see section~\ref{sec:querying}). % \begin{macrocode} - \@@_if_exist:nTF {#1} + \@@_if_structure_exist:nTF {#1} { % \end{macrocode} % Then remove the chunk and run \cs{@@_update_hook_code:n} so @@ -2641,9 +3088,9 @@ % \verb=\begin{document}=. % % If all code is to be removed, clear the code pool -% \cs[no-index]{g_@@_\meta{hook}_code_prop}, the top-level code -% \cs[no-index]{@@_toplevel~\meta{hook}}, and the next-execution code -% \cs[no-index]{@@_next~\meta{hook}}. +% \cs{g_@@_\meta{hook}_code_prop}, the top-level code +% \cs{@@_toplevel\textvisiblespace\meta{hook}}, and the next-execution code +% \cs{@@_next\textvisiblespace\meta{hook}}. % \begin{macrocode} \str_if_eq:nnTF {#2} {*} { @@ -2656,7 +3103,7 @@ % If the label is |top-level| then clear the token list, as all code % there is under the same label. Marked removal is not implemented % for |top-level| because it is hard to reliably know that no code -% was added to \cs[no-index]{@@_toplevel~\meta{hook}} (granted that +% was added to \cs{@@_toplevel\textvisiblespace\meta{hook}} (granted that % an empty code could be interpreted as that, but then it differs in % behaviour from other labels, in which an empty chunk is still valid % for removal). Besides, it doesn't make much (if any) sense for @@ -2680,7 +3127,7 @@ % \end{macrocode} % Finally update the code, if the hook exists. % \begin{macrocode} - \hook_if_exist:nT {#1} + \@@_if_usable:nT {#1} { \@@_update_hook_code:n {#1} } } % \end{macrocode} @@ -2775,10 +3222,10 @@ % disadvantage of that being not really distinguishable from a real % hook name. I now have settled for \texttt{??} which needs some % gymnastics to get it into the csname, but since this is used a -% lot things should be fast, so this is not done with \texttt{c} +% lot, the code should be fast, so this is not done with \texttt{c} % expansion in the code later on. % -% \cs{@@~??} isn't used, but it has to be defined to trick +% \cs{@@\textvisiblespace??} isn't used, but it has to be defined to trick % the code into thinking that \verb=??= is actually a hook. % \begin{macrocode} \prop_new:c {g_@@_??_code_prop} @@ -2799,14 +3246,12 @@ % % \begin{macro}{\hook_gset_rule:nnnn} % \begin{macro}{\@@_gset_rule:nnnn} -% -% \fmi{needs docu correction given new implementation} -% % With % \cs{hook_gset_rule:nnnn}\Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} % a relation is defined between the two code labels for the given % \meta{hook}. The special hook \texttt{??} stands for \emph{any} -% hook describing a default rule. +% hook, which sets a default rule (to be used if no other relation +% between the two hooks exist). % \begin{macrocode} \cs_new_protected:Npn \hook_gset_rule:nnnn #1#2#3#4 { @@ -2814,14 +3259,14 @@ {#1} {#2} {#3} {#4} } % \end{macrocode} -% +% % \begin{macrocode} \cs_new_protected:Npn \@@_gset_rule:nnnn #1#2#3#4 { % \end{macrocode} % First we ensure the basic data structure of the hook exists: % \begin{macrocode} - \@@_declare:n {#1} + \@@_init_structure:n {#1} % \end{macrocode} % Then we clear any previous relationship between both labels. % \begin{macrocode} @@ -2898,9 +3343,11 @@ % together in hook |#1|. % \begin{macrocode} \cs_new_protected:cpn { @@_rule_incompatible-error_gset:nnn } #1#2#3 - { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + { xE } } \cs_new_protected:cpn { @@_rule_incompatible-warning_gset:nnn } #1#2#3 - { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } } + { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + { xW } } % \end{macrocode} % \end{macro} % @@ -2937,7 +3384,7 @@ { \if_int_compare:w \@@_str_compare:nn {#1} {#2} > 0 \exp_stop_f: \prg_return_true: - \else + \else: \prg_return_false: \fi: } @@ -3037,13 +3484,13 @@ % If there aren't any code % chunks for the current hook, there is no point in even starting % the sorting routine so we make a quick test for that and in that -% case just update \cs{@@~\meta{hook}} to hold the |top-level| and +% case just update \cs{@@\textvisiblespace\meta{hook}} to hold the |top-level| and % |next| code chunks. If there are code chunks we call % \cs{@@_initialize_single:NNn} and pass to it ready made csnames % as they are needed several times inside. This way we save a bit % on processing time if we do that up front. % \begin{macrocode} - \hook_if_exist:nT {#1} + \@@_if_usable:nT {#1} { \prop_if_empty:cTF {g_@@_#1_code_prop} { @@ -3096,7 +3543,7 @@ % \begin{macro}[EXP]{\@@_tl_csname:n,\@@_seq_csname:n} % It is faster to pass a single token and expand it when necessary % than to pass a bunch of character tokens around. -% \fmi{note to myself: verify} +% \fmiinline{note to myself: verify} % \begin{macrocode} \cs_new:Npn \@@_tl_csname:n #1 { l_@@_label_#1_tl } \cs_new:Npn \@@_seq_csname:n #1 { l_@@_label_#1_seq } @@ -3160,7 +3607,7 @@ % a way that one can omit a lot of tests and I have mimicked that as % far as possible. The result is a restriction I do not test for at % the moment: a label can't be equal to the number 0! \fmi{Needs -% checking for, just in case} +% checking for, just in case ... maybe} % % ^^A #1 <- \@@~#1 % ^^A #2 <- \g_@@_#1_labels_clist @@ -3301,7 +3748,7 @@ % \end{macrocode} % % This is not really the information one needs in the error case -% but will do for now \ldots \fmi{fix} +% but will do for now \ldots \fmi{improve output on a rainy day} % \begin{macrocode} \@@_debug_label_data:N \l_@@_work_prop \iow_term:x{====================} @@ -3572,15 +4019,20 @@ { \@@_log_cmd:x { >~#1 } } \cs_new_protected:Npn \@@_log_line_indent:x #1 { \@@_log_cmd:x { >~\@spaces #1 } } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_log:nN #1 #2 { \@@_preamble_hook:n {#1} \@@_log_cmd:x { ^^J ->~The~hook~'#1': } % \end{macrocode} -% +% % \begin{macrocode} - \hook_if_exist:nF {#1} - { \@@_log_line:x { is~not~declared! } } + \@@_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 } } { @@ -3598,7 +4050,7 @@ \@@_log_line:x { Document-level~(top-level)~code - \hook_if_exist:nT {#1} + \@@_if_usable:nT {#1} { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } : } \@@_log_line_indent:x @@ -3649,7 +4101,7 @@ % to that hook) and not empty % \begin{macrocode} \bool_lazy_and:nnTF - { \hook_if_exist_p:n {#1} } + { \@@_if_usable_p:n {#1} } { ! \hook_if_empty_p:n {#1} } { \@@_log_line:x @@ -3671,10 +4123,12 @@ } } { + \@@_log_line:x { Execution~order: } #2 { - Hook~ \hook_if_exist:nTF {#1} - {code~pool~empty} {not~declared} + \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1} + { code~pool~is~empty } + { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} } } } } @@ -3766,25 +4220,37 @@ % \end{macrocode} % \end{macro} % +% +% +% % \subsection{Specifying code for next invocation} % % \begin{macro}{\hook_gput_next_code:nn} -% \begin{macro}{% -% \@@_gput_next_code:nn, -% \@@_gput_next_do:nn, -% \@@_gput_next_do:Nnn, -% \@@_clear_next:n -% } % \begin{macrocode} \cs_new_protected:Npn \hook_gput_next_code:nn #1 { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_gput_next_code:nn, +% \@@_gput_next_do:nn, +% \@@_gput_next_do:Nnn, +% \@@_clear_next:n} +% \begin{macrocode} \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 { - \@@_declare:n {#1} - \hook_if_exist:nTF {#1} - { \@@_gput_next_do:nn {#1} {#2} } - { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } + \@@_if_disabled:nTF {#1} + { \msg_error:nnn { hooks } { hook-disabled } {#1} } + { + \@@_init_structure:n {#1} + \@@_if_usable:nTF {#1} + { \@@_gput_next_do:nn {#1} {#2} } + { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } + } } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_gput_next_do:nn #1 { \exp_args:Nc \@@_gput_next_do:Nnn @@ -3813,7 +4279,11 @@ { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } % \end{macrocode} % \end{macro} -% \end{macro} +% +% +% +% +% % % \subsection{Using the hook} % @@ -3840,7 +4310,7 @@ % them causes an update, so \cs{hook_use:n} can be made expandable. % This one is better not protected so that it can expand into nothing % if containing no code. Also important in case of generic hooks that -% we do not generate a \cs{relax} as a side effect of checking for a +% we do not generate a \cs[no-index]{relax} as a side effect of checking for a % csname. In contrast to the \TeX{} low-level % \verb=\csname ...\endcsname= construct \cs{tl_if_exist:c} is % careful to avoid this. @@ -3877,7 +4347,7 @@ % \end{macro} % % \begin{macro}[EXP]{\@@_use:wn} -% \begin{macro}{\@@_try_file_hook:n,\@@_if_exist_use:n} +% \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 % file hook: those need a special treatment. If it is not, the hook % does not exist. If it is, then \cs{@@_try_file_hook:n} is called, @@ -3887,7 +4357,7 @@ % % If it is a file-specific hook, it passes through the same % normalization as during declaration, and then it is used if defined. -% \cs{@@_if_exist_use:n} checks if the hook exist, and calls +% \cs{@@_if_usable_use:n} checks if the hook exist, and calls % \cs{@@_preamble_hook:n} if so, then uses the hook. % \begin{macrocode} \cs_new:Npn \@@_use:wn #1 / #2 \s_@@_mark #3 @@ -3896,16 +4366,22 @@ { \@@_try_file_hook:n {#3} } { } % Hook doesn't exist } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_try_file_hook:n #1 { \@@_if_file_hook:wTF #1 / / \s_@@_mark { - \exp_args:Ne \@@_if_exist_use:n + \exp_args:Ne \@@_if_usable_use:n { \exp_args:Ne \@@_file_hook_normalize:n {#1} } } - { \@@_if_exist_use:n {#1} } % file/ generic hook (e.g. file/before) + { \@@_if_usable_use:n {#1} } % file/ generic hook (e.g. file/before) } -\cs_new_protected:Npn \@@_if_exist_use:n #1 +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_if_usable_use:n #1 { \tl_if_exist:cT { @@~#1 } { @@ -3928,7 +4404,6 @@ % hook name, since \cs{hook_use:n} and \cs{hook_use_once:n} are % documented to not trim spaces. % -% \pho{Should this raise an error if the hook doesn't exist?} % \begin{macrocode} \cs_new_protected:Npn \hook_use_once:n #1 { @@ -3952,9 +4427,10 @@ % exist, in which case emptiness doesn't apply (though % \cs{tl_if_empty:N} returns false in this case). % -% Hooks are a bit more complicated: they have four possible states. +% Hooks are a bit more complicated: they have several other states as +% discussed in \ref{sec:existence}. % A hook may exist or not, and either way it may or may not be empty -% (even a hook that doesn't exist may be non-empty). +% (even a hook that doesn't exist may be non-empty) or may be disabled. % % A hook is said to be empty when no code was added to it, either to % its permanent code pool, or to its ``next'' token list. The hook @@ -3964,19 +4440,19 @@ % In this case it is important that the code added by package $B$ is % remembered until package $A$ is loaded). % -% A hook is said to exist when it was declared with \cs{hook_new:n} or -% some variant thereof. -% +% 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[no-index]{g_@@_\meta{hook}_code_prop}, its -% \cs[no-index]{@@_toplevel~\meta{hook}} and its -% \cs[no-index]{@@_next~\meta{hook}} are empty. +% \cs{g_@@_\meta{hook}_code_prop}, its +% \cs{@@_toplevel\textvisiblespace\meta{hook}} and its +% \cs{@@_next\textvisiblespace\meta{hook}} are empty. % \begin{macrocode} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } { - \@@_if_exist:nTF {#1} + \@@_if_structure_exist:nTF {#1} { \bool_lazy_and:nnTF { \prop_if_empty_p:c { g_@@_#1_code_prop } } @@ -3993,8 +4469,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF]{\hook_if_exist:n} -% A canonical way to test if a hook exists. A hook exists if the +% +% \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 @@ -4002,7 +4479,7 @@ % 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 \hook_if_exist:n #1 { p , T , F , TF } +\prg_new_conditional:Npnn \@@_if_usable:n #1 { p , T , F , TF } { \tl_if_exist:cTF { @@~#1 } { \prg_return_true: } @@ -4011,13 +4488,15 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[pTF]{\@@_if_exist:n} -% An internal check if the hook has already been declared with -% \cs{@@_declare:n}. This means that the hook was already used somehow +% \begin{macro}[pTF]{\@@_if_structure_exist:n} +% +% An internal check if the hook has already its basic internal +% structure set up with +% \cs{@@_init_structure:n}. This means that the hook was already used somehow % (a code chunk or rule was added to it), but it still wasn't declared % with \cs{hook_new:n}. % \begin{macrocode} -\prg_new_conditional:Npnn \@@_if_exist:n #1 { p , T , F , TF } +\prg_new_conditional:Npnn \@@_if_structure_exist:n #1 { p , T , F , TF } { \prop_if_exist:cTF { g_@@_#1_code_prop } { \prg_return_true: } @@ -4025,6 +4504,22 @@ } % \end{macrocode} % \end{macro} +% +% +% +% \begin{macro}[pTF]{\@@_if_declared:n} +% +% Internal test to check if the hook was officially declared with +% \cs{hook_new:n} or a variant. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_declared:n #1 { p, T, F, TF } + { + \tl_if_exist:cTF { g_@@_#1_declared_tl } + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} % % \begin{macro}[pTF]{\@@_if_reversed:n} % An internal conditional that checks if a hook is reversed. @@ -4043,11 +4538,21 @@ % % \subsection{Messages} % +% Hook errors are LaTeX kernel errors: +% \begin{macrocode} +\prop_gput:Nnn \g_msg_module_type_prop { hooks } { LaTeX } +% \end{macrocode} +% And so are kernel errors (this should move elsewhere eventually). +% \begin{macrocode} +\prop_gput:Nnn \g_msg_module_type_prop { kernel } { LaTeX } +%\prop_gput:Nnn \g_msg_module_name_prop { kernel } { } % <-- currently not working +% \end{macrocode} +% % \begin{macrocode} \msg_new:nnnn { hooks } { labels-incompatible } { - Labels~`#1'~and~`#2'~are~incompatible - \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~ + Labels~'#1'~and~'#2'~are~incompatible + \str_if_eq:nnF {#3} {??} { ~in~hook~'#3' } .~ \int_compare:nNnTF {#4} = { 1 } { The~ code~ for~ both~ labels~ will~ be~ dropped. } { You~ may~ see~ errors~ later. } @@ -4058,17 +4563,28 @@ % % \begin{macrocode} \msg_new:nnnn { hooks } { exists } - { Hook~`#1'~ has~ already~ been~ declared. } + { Hook~'#1'~ has~ already~ been~ declared. } { There~ already~ exists~ a~ hook~ declaration~ with~ this~ name.\\ Please~ use~ a~ different~ name~ for~ your~ hook.} % \end{macrocode} % +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { hook-disabled } + { Cannot~add~code~to~disabled~hook~'#1'. } + { + The~hook~'#1'~you~tried~to~add~code~to~was~previously~disabled~ + with~\iow_char:N\\hook_disable:n~or~\iow_char:N\\DisableHook,~so~ + it~cannot~have~code~added~to~it. + } +% \end{macrocode} +% % \begin{macrocode} \msg_new:nnn { hooks } { empty-label } { Empty~code~label~\msg_line_context:.~ - Using~`\@@_currname_or_default:'~instead. + Using~'\@@_currname_or_default:'~instead. } % \end{macrocode} % @@ -4082,26 +4598,26 @@ % % \begin{macrocode} \msg_new:nnnn { hooks } { unknown-rule } - { Unknown~ relationship~ `#3'~ - between~ labels~ `#2'~ and~ `#4'~ - \str_if_eq:nnF {#1} {??} { ~in~hook~`#1' }. ~ + { Unknown~ relationship~ '#3'~ + between~ labels~ '#2'~ and~ '#4'~ + \str_if_eq:nnF {#1} {??} { ~in~hook~'#1' }. ~ Perhaps~ a~ missspelling? } { The~ relation~ used~ not~ known~ to~ the~ system.~ Allowed~ values~ are~ - `before'~ or~ `<',~ - `after'~ or~ `>',~ - `incompatible-warning',~ - `incompatible-error',~ - `voids'~ or~ - `unrelated'. + 'before'~ or~ '<',~ + 'after'~ or~ '>',~ + 'incompatible-warning',~ + 'incompatible-error',~ + 'voids'~ or~ + 'unrelated'. } % \end{macrocode} % % \begin{macrocode} \msg_new:nnnn { hooks } { misused-top-level } { - Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\ + Illegal~use~of~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\ 'top-level'~is~reserved~for~the~user's~document. } { @@ -4115,22 +4631,13 @@ % \begin{macrocode} \msg_new:nnn { hooks } { set-top-level } { - You~cannot~change~the~default~label~#1~`top-level'.~Illegal \\ + You~cannot~change~the~default~label~#1~'top-level'.~Illegal \\ \use:nn { ~ } { ~ } \iow_char:N \\#2{#3} \\ \msg_line_context:. } % \end{macrocode} % % \begin{macrocode} -\msg_new:nnn { hooks } { ddhl-deprecated } - { - \iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\ - Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\ - The~deprecated~name~will~be~removed~in~the~next~release. - } -% \end{macrocode} -% -% \begin{macrocode} \msg_new:nnn { hooks } { extra-pop-label } { Extra~\iow_char:N \\PopDefaultHookLabel. \\ @@ -4139,18 +4646,47 @@ \msg_new:nnn { hooks } { missing-pop-label } { Missing~\iow_char:N \\PopDefaultHookLabel. \\ - The~label~`#1'~was~pushed~but~never~popped.~Something~is~wrong. + The~label~'#1'~was~pushed~but~never~popped.~Something~is~wrong. } % \end{macrocode} % % \begin{macrocode} -\msg_new:nnn { hooks } { should-not-happen } +\msg_new:nnn { kernel } { should-not-happen } { - ERROR!~This~should~not~happen.~#1 \\ + This~should~not~happen.~#1 \\ Please~report~at~https://github.com/latex3/latex2e. } % \end{macrocode} % +% +% +% \begin{macrocode} +\msg_new:nnn { hooks } { provide-disabled } + { + Cannot~ provide~ hook~ '#1'~ because~ it~ is~ disabled! + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { provide-error } + { + Hook~'#1'~ already~ declared~ as~ a~ + \@@_if_reversed:nTF {#1} { reversed } { normal }~ hook! + } + { + You~ attempted~ to~ provide~ the~ hook~'#1'~ as~ a~ + \@@_if_reversed:nTF {#1} { normal } { reversed }~ hook,~ but~ it~ + was~ already~ previously~ declared~ as~ a~ + \@@_if_reversed:nTF {#1} { reversed } { normal }~ hook.~ + A~ redeclaration~ is~ not~ possible. + } +% \end{macrocode} +% +% +% +% +% +% % \subsection{\LaTeXe{} package interface commands} % % @@ -4164,6 +4700,44 @@ % \end{macrocode} % \end{macro} % +% +% +% \begin{macrocode} +%\IncludeInRelease{2021/06/01}% +% {\hook_provide:n}{Providing~hooks} +% \end{macrocode} +% +% \begin{macro}{\ProvideHook,\ProvideReversedHook,\ProvideMirroredHookPair} +% Providing new hooks \ldots +% \changes{v1.0m}{2021/04/29}{Add \cs{ProvideHook} etc.} +% \begin{macrocode} +\NewDocumentCommand \ProvideHook { m }{ \hook_provide:n {#1} } +\NewDocumentCommand \ProvideReversedHook { m }{ \hook_provide_reversed:n {#1} } +\NewDocumentCommand \ProvideMirroredHookPair { mm }{ \hook_provide_pair:nn {#1}{#2} } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DisableHook} +% Disabling a (generic) hook. +% \begin{macrocode} +\NewDocumentCommand \DisableHook { m }{ \hook_disable:n {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01} +% {\hook_provide:n}{Providing~hooks} +% +%\def \ProvideHook#1{} +%\def \ProvideReversedHook#1{} +%\def \ProvideMirroredHookPair#1#2{} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% % \begin{macro}{\AddToHook} % % \begin{macrocode} @@ -4192,7 +4766,10 @@ % \begin{macro}{\SetDefaultHookLabel} % \begin{macro}{\PushDefaultHookLabel} % \begin{macro}{\PopDefaultHookLabel} -% \begin{macro}{\DeclareDefaultHookLabel} +% +% \fmiinline{Docu task: At some point this code for this should be moved to the +% label section earlier and here we should keep only the interface commands.} +% % \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_push_aux:n} % \begin{macro}{\@@_curr_name_pop:} % \begin{macro}{\@@_end_document_label_check:} @@ -4216,8 +4793,11 @@ % the stack to support roll forward. But in some rare cases, % \pkg{latexrelease} may be loaded inside another package (notably % \pkg{platexrelease}), so we'll first push the |top-level| entry: +% \changes{v1.0i}{2021/03/18} +% {Only add \texttt{top-level} if not already there.} % \begin{macrocode} -%\seq_gput_right:Nn \g_@@_name_stack_seq { top-level } +%\seq_if_empty:NT \g_@@_name_stack_seq +% { \seq_gput_right:Nn \g_@@_name_stack_seq { top-level } } % \end{macrocode} % then we dissect the \cs{@currnamestack}, adding \cs{@currname} to % the stack: @@ -4233,9 +4813,12 @@ % \q_recursion_tail \q_recursion_tail % \q_recursion_tail \q_recursion_stop % \end{macrocode} -% and finalle set the default label to be the \cs{@currname}: +% and finally set the default label to be the \cs{@currname}: +% \changes{v1.0i}{2021/03/18} +% {Remove the (empty) \enquote{top-level} from \cs{@currnamestack}.} % \begin{macrocode} %\tl_gset:Nx \g_@@_hook_curr_name_tl { \@currname } +%\seq_gpop_right:NN \g_@@_name_stack_seq \l_@@_tmpa_tl % \end{macrocode} % % Two commands keep track of the stack: when a file is input, @@ -4274,7 +4857,7 @@ % \end{macrocode} % % At the end of the document we want to check if there was no -% \cs{@@_curr_name_push:} without a matching \cs{@@_curr_name_pop:} +% \cs{@@_curr_name_push:n} without a matching \cs{@@_curr_name_pop:} % (not a critical error, but it might indicate that something else is % not quite right): % \begin{macrocode} @@ -4316,11 +4899,6 @@ } { \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} } } -\NewDocumentCommand \DeclareDefaultHookLabel { m } - { - \msg_error:nn { hooks } { ddhl-deprecated } - \SetDefaultHookLabel {#1} - } % \end{macrocode} % % The label is only automatically updated with \cs{@onefilewithoptions} @@ -4360,7 +4938,6 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % % @@ -4413,7 +4990,7 @@ % \begin{macro}{\ClearHookRule} % A special setup rule that removes an existing relation. % Basically {@@_rule_gclear:nnn} plus fixing the property list for debugging. -% \fmi{Need an L3 interface, or maybe it should get dropped?} +% \fmiinline{Needs perhaps an L3 interface, or maybe it should get dropped?} % \begin{macrocode} \NewDocumentCommand \ClearHookRule { m m m } { \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} } @@ -4421,19 +4998,33 @@ % \end{macro} % % -% \begin{macro}[EXP]{\IfHookExistsTF,\IfHookEmptyTF} +% \begin{macro}[EXP]{\IfHookEmptyTF} % Here we avoid the overhead of \pkg{xparse}, since \cs{IfHookEmptyTF} % is used in \cs{end} (that is, every \LaTeX{} environment). As a % further optimisation, use \cs{let} rather than \cs{def} to avoid one % expansion step. % \begin{macrocode} -\cs_new_eq:NN \IfHookExistsTF \hook_if_exist:nTF \cs_new_eq:NN \IfHookEmptyTF \hook_if_empty:nTF % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\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}, +% \texttt{pxeveryshi.sty}, so the public name may be an alias of the +% internal conditional for a while. Regardless, those packages' use for +% \cs{IfHookExistsTF} is not really correct and can be changed.} +% \begin{macrocode} +\cs_new_eq:NN \IfHookExistsTF \@@_if_usable:nTF +% \end{macrocode} +% \end{macro} +% +% +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % % \subsection{Internal commands needed elsewhere} % @@ -4449,6 +5040,7 @@ % \begin{macro}{\@expl@@@initialize@all@@, % \@expl@@@hook@curr@name@pop@@} % +% \InternalDetectionOff % \begin{macrocode} \cs_new_eq:NN \@expl@@@initialize@all@@ \__hook_initialize_all: @@ -4458,29 +5050,25 @@ \cs_new_eq:NN \@expl@@@hook@curr@name@pop@@ \__hook_curr_name_pop: % \end{macrocode} +% \InternalDetectionOn % \end{macro} % -% -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} -% -% % Rolling back here doesn't undefine the interface commands as they % may be used in packages without rollback functionality. So we % just make them do nothing which may or may not work depending on % the code usage. % \changes{v1.0d}{2020/10/04}{Definition \cs{AddToHookNext} was supposed -% to be for \cs{AddToHook} vize versa (gh/401)} +% to be for \cs{AddToHook} vice versa (gh/401)} % \begin{macrocode} -% -%\EndIncludeInRelease +% %\IncludeInRelease{0000/00/00}% -% {\NewHook}{The hook management}% +% {lthooks}{The~hook~management}% +% +%\def \NewHook#1{} +%\def \NewReversedHook#1{} +%\def \NewMirroredHookPair#1#2{} % -%\def\NewHook#1{} -%\def\NewReversedHook#1{} -%\def\NewMirroredHookPair#1#2{} +%\def \DisableHook #1{} % %\long\def\AddToHookNext#1#2{} % @@ -4508,7 +5096,9 @@ %\long\def \IfHookExistsTF #1#2#3{#3} %\long\def \IfHookEmptyTF #1#2#3{#2} % -%\EndIncludeInRelease +%\EndModuleRelease +\ExplSyntaxOff +% % \end{macrocode} % % diff --git a/Master/texmf-dist/source/latex/base/lthyphen.dtx b/Master/texmf-dist/source/latex/base/lthyphen.dtx index 71ab081c669..9244db06423 100644 --- a/Master/texmf-dist/source/latex/base/lthyphen.dtx +++ b/Master/texmf-dist/source/latex/base/lthyphen.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -40,7 +40,7 @@ %\iffalse This is a META comment % % File `lthyphen.dtx'. -% Copyright (C) 1994-94 LaTeX3 project, Frank Mittelbach and +% Copyright (C) 1994-94 LaTeX Project, Frank Mittelbach and % Rainer Sch\"opf, all rights reserved. % %\fi diff --git a/Master/texmf-dist/source/latex/base/ltidxglo.dtx b/Master/texmf-dist/source/latex/base/ltidxglo.dtx index dcb88e83e98..75a80cd4390 100644 --- a/Master/texmf-dist/source/latex/base/ltidxglo.dtx +++ b/Master/texmf-dist/source/latex/base/ltidxglo.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltlength.dtx b/Master/texmf-dist/source/latex/base/ltlength.dtx index f5b63ed35ea..1be147547ec 100644 --- a/Master/texmf-dist/source/latex/base/ltlength.dtx +++ b/Master/texmf-dist/source/latex/base/ltlength.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltlength.dtx} - [2019/08/27 v1.1d LaTeX Kernel (Lengths)] + [2020/12/05 v1.1d LaTeX Kernel (Lengths)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltlength.dtx} @@ -154,7 +154,7 @@ % This macro takes the contents of the skip register that is % supplied as its argument and removes the fractional part to make % it a whole number of points. This can be used in class files to -% avoid values like |345.4666666pt| when calulating a dimension. +% avoid values like |345.4666666pt| when calculating a dimension. % \changes{LaTeX2e}{1993/11/22}{Macro added} % \begin{macrocode} \def\@settopoint#1{\divide#1\p@\multiply#1\p@} diff --git a/Master/texmf-dist/source/latex/base/ltlists.dtx b/Master/texmf-dist/source/latex/base/ltlists.dtx index 653e4e2edd2..fecb3125880 100644 --- a/Master/texmf-dist/source/latex/base/ltlists.dtx +++ b/Master/texmf-dist/source/latex/base/ltlists.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -31,7 +31,7 @@ %<*driver> % \fi \ProvidesFile{ltlists.dtx} - [2020/04/24 v1.0t LaTeX Kernel (List Environments)] + [2020/12/05 v1.0t LaTeX Kernel (List Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltlists.dtx} @@ -112,7 +112,7 @@ % the entire environment is a single item. It is defined by % letting |\quotation| == |\list{}{...}\item\relax|. (Note the % |\relax|, there in case the first character in the environment is a -% '['.) The spacing parameters provide a great deal of flexability in +% '['.) The spacing parameters provide a great deal of flexibility in % designing the format, including the ability to let the indentation of % the first paragraph be different from that of the subsequent ones. % @@ -589,7 +589,7 @@ % when not inlabel flag is false} % Because |\par| is sometimes made a no-op it is possible for a missing % |\item| to produce a loop that does not fill memory and so never gets -% trapped by \TeX. We thus need to trap this here by seting |\par| to +% trapped by \TeX. We thus need to trap this here by setting |\par| to % count the number of times a paragraph ii is called with no progress % being made started. % \begin{macrocode} @@ -729,7 +729,7 @@ % If a section heading changes |\clubpenalty| to keep lines % after it together then this modification is restored via the % |\everypar| mechanism at the start of the next paragraph. As we -% destroy the contents of this token here we explicity set +% destroy the contents of this token here we explicitly set % |\clubpenalty| back to its default. % \changes{v1.0t}{2015/05/10}{Explicitly reset \cs{clubpenalty} before % clearing \cs{everypar}; see also pr/0462 and pr/4065} @@ -807,7 +807,7 @@ % \end{macro} % % \begin{macro}{\@item} -% \changes{v1.0l}{1996/07/26}{Remove unecessary \cs{global} before +% \changes{v1.0l}{1996/07/26}{Remove unnecessary \cs{global} before % \cs{@minipage...}} % \begin{macrocode} \def\@item[#1]{% @@ -889,7 +889,7 @@ \everypar{}% \fi}% % \end{macrocode} -% \changes{v1.0l}{1996/07/26}{Remove unecessary \cs{global} before +% \changes{v1.0l}{1996/07/26}{Remove unnecessary \cs{global} before % \cs{@nobreak...}} % \changes{v1.0m}{1996/10/23}{\cs{@nobreak...} moved into the % \cs{everypar} and not executed unconditionally, see above} diff --git a/Master/texmf-dist/source/latex/base/ltlogos.dtx b/Master/texmf-dist/source/latex/base/ltlogos.dtx index 6784cb41c00..132eaf636f7 100644 --- a/Master/texmf-dist/source/latex/base/ltlogos.dtx +++ b/Master/texmf-dist/source/latex/base/ltlogos.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltluatex.dtx b/Master/texmf-dist/source/latex/base/ltluatex.dtx index 8573b3e6ca6..3b9a3377312 100644 --- a/Master/texmf-dist/source/latex/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex/base/ltluatex.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 2015-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -28,7 +28,7 @@ \ProvidesFile{ltluatex.dtx} % %<*tex> -[2020/09/25 v1.1s +[2021/04/18 v1.1t % % LuaTeX support for plain TeX (core) %<*tex> @@ -38,6 +38,10 @@ % %<*driver> \documentclass{ltxdoc} + +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + \GetFileInfo{ltluatex.dtx} \begin{document} \title{\filename\\(Lua\TeX{}-specific support)} @@ -129,7 +133,7 @@ % \DescribeMacro{\newluachunkname} % |newluachunkname{|\meta{chunkname}|}|\\ % Allocates a number for Lua chunk register, indexed from~$1$. -% Also enters the name of the regiser (without backslash) into the +% Also enters the name of the register (without backslash) into the % \verb|lua.name| table to be used in stack traces. % % \noindent @@ -204,6 +208,7 @@ % The number is returned and also \meta{name} argument is added to the % |lua.name| array at that index. % +% \begin{sloppypar} % \noindent % \DescribeMacro{new_luafunction} % |luatexbase.new_luafunction(|\meta{functionname}|)|\\ @@ -211,6 +216,7 @@ % with |\luafunction|, |\lateluafunction|, and |\luadef|, % indexed from~$1$. The optional \meta{functionname} argument % is just used for logging. +% \end{sloppypar} % % These functions all require access to a named \TeX{} count register % to manage their allocations. The standard names are those defined @@ -582,7 +588,7 @@ % \changes{v1.0a}{2015/09/24}{Macro added} % Category code tables are allocated with a limit half of that used by Lua\TeX{} % for everything else. At the end of allocation there needs to be an -% initialisation step. Table~$0$ is already taken (it's the global one for +% initialization step. Table~$0$ is already taken (it's the global one for % current use) so the allocation starts at~$1$. % \begin{macrocode} \ifx\e@alloc@ccodetable@count\@undefined @@ -779,8 +785,8 @@ % \subsection{Lua loader} % \changes{v1.1r}{2020/08/10}{Load ltluatex Lua module during format building} % -% Lua code loaded in the format often has to to be loaded again at the -% beginning of every job, so we define a helper whch allows us to avoid +% Lua code loaded in the format often has to be loaded again at the +% beginning of every job, so we define a helper which allows us to avoid % duplicated code: % % \begin{macrocode} @@ -1113,9 +1119,10 @@ luatexbase.registernumber = registernumber % % \begin{macro}{new_attribute} % \changes{v1.0a}{2015/09/24}{Function added} -% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking} +% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking} % As attributes are used for Lua manipulations its useful to be able % to assign from this end. +% \InternalDetectionOff % \begin{macrocode} local attributes=setmetatable( {}, @@ -1143,12 +1150,13 @@ local function new_attribute(name) end luatexbase.new_attribute = new_attribute % \end{macrocode} +% \InternalDetectionOn % \end{macro} % % \subsection{Custom whatsit allocation} % % \begin{macro}{new_whatsit} -% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking} +% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking} % Much the same as for attribute allocation in Lua. % \begin{macrocode} local whatsit_count_name = whatsit_count_name or "e@alloc@whatsit@count" @@ -1169,7 +1177,7 @@ luatexbase.new_whatsit = new_whatsit % \subsection{Bytecode register allocation} % % \begin{macro}{new_bytecode} -% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking} +% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking} % Much the same as for attribute allocation in Lua. % The optional \meta{name} argument is used in the log if given. % \begin{macrocode} @@ -1192,7 +1200,7 @@ luatexbase.new_bytecode = new_bytecode % \subsection{Lua chunk name allocation} % % \begin{macro}{new_chunkname} -% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking} +% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking} % As for bytecode registers but also store the name in the % |lua.name| table. % \begin{macrocode} @@ -1404,6 +1412,7 @@ local callbacktypes = callbacktypes or { % \changes{v1.1j}{2019/06/18}{make\_extensible added} % \changes{v1.1j}{2019/06/18}{font\_descriptor\_objnum\_provider added} % \changes{v1.1l}{2020/02/02}{glyph\_info added} +% \changes{v1.1t}{2021/04/18}{input\_level\_string added} % \begin{macrocode} define_font = exclusive, glyph_info = exclusive, @@ -1411,6 +1420,7 @@ local callbacktypes = callbacktypes or { glyph_stream_provider = exclusive, make_extensible = exclusive, font_descriptor_objnum_provider = exclusive, + input_level_string = exclusive, % \end{macrocode} % \changes{v1.0m}{2016/02/11}{pdf\_stream\_filter\_callback removed} % \begin{macrocode} @@ -1469,7 +1479,7 @@ end % functions in inverse order. % \item[exclusive] is for functions with more complex signatures; functions in % this type of callback are \emph{not} combined: An error is raised if -% a second callback is registered.. +% a second callback is registered. % \end{description} % % Handler for |data| callbacks. @@ -1735,7 +1745,7 @@ luatexbase.add_to_callback = add_to_callback % % \begin{macro}{remove_from_callback} % \changes{v1.0a}{2015/09/24}{Function added} -% \changes{v1.0k}{2015/12/02}{adjust initialisation of cb local (PHG)} +% \changes{v1.0k}{2015/12/02}{adjust initialization of cb local (PHG)} % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)} % \changes{v1.1m}{2020/03/07}{Do not call callback.register for user-defined callbacks} % Remove a function from a callback. First check arguments. diff --git a/Master/texmf-dist/source/latex/base/ltmath.dtx b/Master/texmf-dist/source/latex/base/ltmath.dtx index 770367c8a30..aadb96fb023 100644 --- a/Master/texmf-dist/source/latex/base/ltmath.dtx +++ b/Master/texmf-dist/source/latex/base/ltmath.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2020/11/09 v1.2h LaTeX Kernel (Math Setup)] + [2021/04/20 v1.2i LaTeX Kernel (Math Setup)] % \iffalse % % @@ -529,7 +529,7 @@ % % Originally \LaTeX{} only provided a small set of spacing commands % for use in text and math, some of the commands like \cs{;} were -% only supported in manth mode. \texttt{amsmath} normalized and +% only supported in math mode. \texttt{amsmath} normalized and % provided all of them in text and math. This code has now been % moved to the kernel so that it is generally available. % @@ -961,11 +961,12 @@ % \end{macro} % % \begin{macro}{\@eqncr} +% \changes{v1.2i}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macro}{\@xeqncr} % \begin{macro}{\@yeqncr} % \changes{v1.0y}{1995/10/16}{(DPC) Use \cs{@testopt} /1911} % \begin{macrocode} -\def\@eqncr{% +\protected\def\@eqncr{% {\ifnum0=`}\fi \@ifstar{% \global\@eqpen\@M\@yeqncr @@ -1033,8 +1034,9 @@ \let\@seqncr=\@eqncr % \end{macrocode} % +% \changes{v1.2i}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macrocode} -\@namedef{eqnarray*}{\def\@eqncr{\nonumber\@seqncr}\eqnarray} +\@namedef{eqnarray*}{\protected\def\@eqncr{\nonumber\@seqncr}\eqnarray} % \end{macrocode} % % \begin{macrocode} @@ -1101,7 +1103,7 @@ % To put the equation number on the left side of an equation we % have to use a little trick. The number is shifted |\displaywidth| % to the left inside a box of (approximately) zero width. This -% fails when the quation is too wide, the equation number than may +% fails when the equation is too wide, the equation number than may % overprint the equation itself. % \changes{v1.2y classes}{1995/01/12}{Added \cs{normalcolor}} % \changes{v1.3c classes}{1995/05/25} diff --git a/Master/texmf-dist/source/latex/base/ltmiscen.dtx b/Master/texmf-dist/source/latex/base/ltmiscen.dtx index cf7f3c836be..8bae3f9bfa3 100644 --- a/Master/texmf-dist/source/latex/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex/base/ltmiscen.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2020/12/18 v1.1x LaTeX Kernel (Misc. Environments)] + [2021/02/08 v1.1y LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -214,6 +214,7 @@ % \changes{v1.1i}{2000/05/19} % {Reset \cs{AtEndDocument} for latex/3060} % \begin{macrocode} + \@kernel@before@enddocument \UseOneTimeHook{enddocument}% \@kernel@after@enddocument % \end{macrocode} @@ -390,6 +391,35 @@ %<*2ekernel> % \end{macrocode} % +% \begin{macro}{\@kernel@before@enddocument} +% The \cs{@kernel@before@enddocument} hook is slightly different +% because we initialize it with \cs{par} so that \cs{enddocument} always +% returns to vertical mode as its first action. +% \changes{v1.1x}{2020/10/26}{\cs{enddocument} should always start out in +% vmode (gh/385)} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}% +% {\@kernel@before@enddocument}{kernel before hook}% +\def\@kernel@before@enddocument{\par} +% +%\EndIncludeInRelease +% \end{macrocode} +% +% The rollback code renders it harmless. +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}% +% {\@kernel@before@enddocument}{kernel before hook}% +% +%\let\@kernel@before@enddocument\@empty +% +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% % % % \begin{macro}{\@testdef} @@ -838,6 +868,15 @@ % \expandafter\endgroup\if@endpe\@doendpe\fi % \if@ignore\@ignorefalse\ignorespaces\fi} % +% \end{macrocode} +% Also undo the internal commands as some packages unfortunately test +% for their existence instead of using \cs{IfFormatAtLeastTF}. +% \changes{v1.1y}{2021/02/08}{Undo the internals for robust \cs{begin} +% and \cs{end} in rollback (gh/494)} +% \begin{macrocode} +%\expandafter\let\csname begin \endcsname\@undefined +%\expandafter\let\csname end \endcsname\@undefined +% %\EndIncludeInRelease %<*2ekernel> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltoutenc.dtx b/Master/texmf-dist/source/latex/base/ltoutenc.dtx index c6bfc149b7c..eb2ecd1e537 100644 --- a/Master/texmf-dist/source/latex/base/ltoutenc.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutenc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -37,14 +37,14 @@ %\ProvidesFile{ts1enc.def}[2001/06/05 v3.0e (jk/car/fm) %\ProvidesFile{tuenc.def} %\ProvidesPackage{fontenc} -% [2020/08/10 v2.0s +% [2021/04/29 v2.0v % Standard LaTeX file] % Standard LaTeX package] % %<*driver> % \fi \ProvidesFile{ltoutenc.dtx} - [2020/08/10 v2.0s LaTeX Kernel (font encodings)] + [2021/04/29 v2.0v LaTeX Kernel (font encodings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutenc.dtx} @@ -421,7 +421,7 @@ % for |\textdollar| in \texttt{OT1} is a hack since \$ and \pounds{} % actually share the same slot in this encoding. Thus if such a glyph % becomes available in a different encoding (e.g., \texttt{TS1}) one -% would like to get rid of the flacky one and make the default +% would like to get rid of the flaky one and make the default % definition point to the new encoding. In such a case defining %\begin{verbatim} % \DeclareTextSymbol{\textdollar}{TS1}{36} @@ -841,7 +841,7 @@ % avoid that (they are some hidden inside \cs{maybe@load@fontshape}). % As we don't have to load the fontshape in this case % (as that happened in the box above if necessary, we simply -% disable that part of the code temporaily. +% disable that part of the code temporarily. % We also ignore \cs{ignorespaces} which has the same issue and may % show up as part of \cs{normalfont} if that is used. % \changes{v2.0m}{2019/12/18}{Avoid code that breaks \cs{accent}} @@ -1717,6 +1717,17 @@ \DeclareTextSymbol{\textemdash}{OT1}{124} \DeclareTextSymbol{\textendash}{OT1}{123} % \end{macrocode} +% +% The \verb=\nobreak\hskip\z@= is there to prevent a break after +% the hyphen but allow later breaks in the remainder of the word. +% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash} +% and \cs{texthorizontalbar} (gh/404)} +% \begin{macrocode} +\DeclareTextCommand{\textnonbreakinghyphen}{OT1}{\mbox{-}\nobreak\hskip\z@} +\DeclareTextCommand{\textfiguredash} {OT1}{\textendash} +\DeclareTextCommand{\texthorizontalbar} {OT1}{\textemdash} +% \end{macrocode} +% % Using the ligatures helps with OT1 fonts that have % |\textexclamdown| and |\textquestiondown| in unusual positions. % \changes{v1.95}{2002/06/17}{Definition of \cs{textexclamdown} changed (pr/3368)} @@ -2045,6 +2056,19 @@ \DeclareTextSymbol{\textdollar}{T1}{`\$} \DeclareTextSymbol{\textemdash}{T1}{22} \DeclareTextSymbol{\textendash}{T1}{21} +% \end{macrocode} +% +% The \verb=\nobreak\hskip\z@= is there to prevent a break after +% the hyphen but allow later breaks in the remainder of the word. +% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash} +% and \cs{texthorizontalbar} (gh/404)} +% \begin{macrocode} +\DeclareTextCommand{\textnonbreakinghyphen}{T1}{\mbox{-}\nobreak\hskip\z@} +\DeclareTextCommand{\textfiguredash} {T1}{\textendash} +\DeclareTextCommand{\texthorizontalbar} {T1}{\textemdash} +% \end{macrocode} +% +% \begin{macrocode} \DeclareTextSymbol{\textexclamdown}{T1}{189} \DeclareTextSymbol{\textgreater}{T1}{`\>} %\DeclareTextSymbol{\texthyphenchar}{T1}{127} @@ -2538,7 +2562,7 @@ % % The tie accent was borrowed from the |cmmi| font. The tc fonts % now provide four tie accents, the first two are done in the -% classical way with assymetric glyphs hanging out of their boxes; +% classical way with asymmetric glyphs hanging out of their boxes; % the new ties are centered in their boxes like all other accents. % They need a name: please tell us if you know what to call them. % @@ -2550,7 +2574,7 @@ \DeclareTextAccent{\capitalnewtie}{TS1}{29} % \end{macrocode} % -% Compund word marks. +% Compound word marks. % % The text companion fonts contain two compound word marks of % different heights, one has |cap_height|, the other |asc_height|. @@ -2583,8 +2607,31 @@ \DeclareTextSymbol{\textquotesingle}{TS1}{39} % \end{macrocode} % "28 = 40 -% \begin{macrocode} -\DeclareTextSymbol{\textasteriskcentered}{TS1}{42} +% +% The symbol \cs{textasteriskcentered} ``\textasteriskcentered'' is +% supposed to be always available in \texttt{TS1} and that is +% important as it is used in footnote symbols. However, in a few +% fonts it is missing even though they are otherwise fairly +% complete. We therefore use a rather elaborate method and check if +% the slot has a glyph and if not produce a poor man's version by +% using a normal ``*'' slightly enlarged and somewhat lowered. +% The main application for this symbol is in footnote symbols and +% there it should produce a comparable size and show a similar placement. +% \changes{v2.0t}{2021/02/17}{Special definition for +% \cs{textasteriskcentered} when missing in TS1 (gh/502)} +% \begin{macrocode} +%\DeclareTextSymbol{\textasteriskcentered}{TS1}{42} % that's wanted +\DeclareTextCommand \textasteriskcentered{TS1}{% % and that's needed + \iffontchar\font 42 \char42 \else + \begingroup\fontencoding{T1}% + \fontsize + {\the\dimexpr1.3\dimexpr\f@size pt\relax}% + {\f@baselineskip}% + \selectfont + \raisebox{-0.7ex}[\dimexpr\height-0.7ex][0pt]{*}% + \endgroup + \fi +} % \end{macrocode} % Note that '054 is a comma and '056 is a full stop: these make % numbers using oldstyle digits easier to input. @@ -2837,7 +2884,7 @@ %<*TU> % \end{macrocode} % In the base interface the Unicode encoding is always known as TU -% But we parameterise the encoding name to allow for modelling +% But we parameterize the encoding name to allow for modelling % differences in Unicode support by different fonts. % \begin{macrocode} \providecommand\UnicodeEncodingName{TU} @@ -3106,8 +3153,34 @@ \DeclareTextSymbol{\textbaht} \UnicodeEncodingName{"0E3F} \DeclareTextSymbol{\SS} \UnicodeEncodingName{"1E9E} \DeclareTextSymbol{\textcompwordmark} \UnicodeEncodingName{"200C} +% \end{macrocode} +% +% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash} +% and \cs{texthorizontalbar} (gh/404)} +% \begin{macrocode} +%\DeclareTextSymbol{\textnonbreakinghyphen} \UnicodeEncodingName{"2011} +%\DeclareTextSymbol{\textfiguredash} \UnicodeEncodingName{"2012} \DeclareTextSymbol{\textendash} \UnicodeEncodingName{"2013} \DeclareTextSymbol{\textemdash} \UnicodeEncodingName{"2014} +%\DeclareTextSymbol{\texthorizontalbar} \UnicodeEncodingName{"2015} +% \end{macrocode} +% Unfortunately some fonts do not implement \texttt{"2011}, \texttt{"2012} and/or +% \texttt{"2015} (including the \LaTeX{} default fonts for Unicode +% engines) so we provide some approximations if the glyph is +% missing, like we do for \texttt{OT1} and \texttt{T1}. +% +% The \verb=\nobreak\hskip\z@= is there to prevent a break after +% the hyphen but allow later breaks in the remainder of the word. +% \begin{macrocode} +\DeclareTextCommand{\textnonbreakinghyphen} \UnicodeEncodingName + {\iffontchar\font "2011 \char "2011 \else \mbox{-}\nobreak\hskip\z@ \fi} +\DeclareTextCommand{\textfiguredash} \UnicodeEncodingName + {\iffontchar\font "2012 \char "2012 \else \char "2013 \fi} +\DeclareTextCommand{\texthorizontalbar} \UnicodeEncodingName + {\iffontchar\font "2015 \char "2015 \else \char "2014 \fi} +% \end{macrocode} +% +% \begin{macrocode} \DeclareTextSymbol{\textbardbl} \UnicodeEncodingName{"2016} \DeclareTextSymbol{\textquoteleft} \UnicodeEncodingName{"2018} \DeclareTextSymbol{\textquoteright} \UnicodeEncodingName{"2019} @@ -3159,15 +3232,17 @@ % \end{macrocode} % % Not all fonts have U+2217 but using U+002A requires some adjustment. +% \changes{v2.0t}{2021/02/17}{Adjust values for +% \cs{textasteriskcentered} To match TS1 definition (gh/502)} % \begin{macrocode} \DeclareTextCommand{\textasteriskcentered}\UnicodeEncodingName{% \iffontchar\font"2217 \char"2217 \else \begingroup \fontsize - {\the\dimexpr1.2\dimexpr\f@size pt\relax}% + {\the\dimexpr1.3\dimexpr\f@size pt\relax}% {\f@baselineskip}% \selectfont - \raisebox{-0.6ex}[\dimexpr\height-0.6ex][0pt]{*}% + \raisebox{-0.7ex}[\dimexpr\height-0.7ex][0pt]{*}% \endgroup \fi } @@ -3393,8 +3468,19 @@ \DeclareUnicodeComposite{\v} {o}{"01D2} \DeclareUnicodeComposite{\v} {U}{"01D3} \DeclareUnicodeComposite{\v} {u}{"01D4} +% \end{macrocode} +% +% \changes{v2.0v}{2021/04/29}{Add composites for +% \texttt{\protect\string\ae/\protect\string\AE/\ae/\AE} (gh/552)} +% \begin{macrocode} +\DeclareUnicodeComposite{\'} \AE{"01FC} +\DeclareUnicodeComposite{\'} {Æ}{"01FC} +\DeclareUnicodeComposite{\'} \ae{"01FD} +\DeclareUnicodeComposite{\'} {æ}{"01FD} \DeclareUnicodeComposite{\=} \AE{"01E2} +\DeclareUnicodeComposite{\=} {Æ}{"01E2} \DeclareUnicodeComposite{\=} \ae{"01E3} +\DeclareUnicodeComposite{\=} {æ}{"01E3} \DeclareUnicodeComposite{\v} {G}{"01E6} \DeclareUnicodeComposite{\v} {g}{"01E7} \DeclareUnicodeComposite{\v} {K}{"01E8} diff --git a/Master/texmf-dist/source/latex/base/ltoutenc.ins b/Master/texmf-dist/source/latex/base/ltoutenc.ins index 17d62e11e8a..1330b5c44eb 100644 --- a/Master/texmf-dist/source/latex/base/ltoutenc.ins +++ b/Master/texmf-dist/source/latex/base/ltoutenc.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltoutput.dtx b/Master/texmf-dist/source/latex/base/ltoutput.dtx index 35d049b9590..b1b3a240965 100644 --- a/Master/texmf-dist/source/latex/base/ltoutput.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutput.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltoutput.dtx} - [2020/08/21 v1.4f LaTeX Kernel (Output Routine)] + [2021/05/05 v1.4g LaTeX Kernel (Output Routine)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutput.dtx} @@ -57,7 +57,7 @@ % \iffalse % LATEX VERSION 2e % Copyright (C) 1992 by Leslie Lamport -% Copyright (C) 1994-2000 by Leslie Lamport, LaTeX3 project +% Copyright (C) 1994-2000 by Leslie Lamport, LaTeX Project % % LaTeX 2e kernel file for the output routine. % @@ -1134,7 +1134,7 @@ \global \advance \@colht \@tempdima \ifx \@dbltoplist \@empty \else - \@latexerr{Float(s) lost}\@ehb + \@latex@error{Float(s) lost}\@ehb \let \@dbltoplist \@empty \fi \@cons \@dbltoplist \@currbox @@ -1525,7 +1525,7 @@ \global \@colroom \@colht \ifx \@currlist\@empty \else - \@latexerr{Float(s) lost}\@ehb + \@latex@error{Float(s) lost}\@ehb \global \let \@currlist \@empty \fi \@makefcolumn\@deferlist @@ -1676,7 +1676,7 @@ % \begin{macro}{\@makecol} % \changes{v0.1c}{1993/11/23}{Command changed} % \changes{v1.0b}{1993/11/29}{\cs{@makespecialcolbox} added} -% We must rewrite this macro to alllow for variations in page-makeup +% We must rewrite this macro to allow for variations in page-makeup % required by changes in page-length. % % This uses a different macro if a special-length column is being @@ -1860,7 +1860,7 @@ % force the shortest possible column with the possibility of an % overfull box. % -% This should work for bothe flush- and ragged-bottom setting since +% This should work for both flush- and ragged-bottom setting since % it makes the contents no smaller than the size (|\@colht|) of the % box into which they are put. % @@ -2074,7 +2074,7 @@ % \end{macrocode} % % The |\catcode`\ = 10| was removed as it was considered useless -% (presumably because nothing gets tokenised during shipout). +% (presumably because nothing gets tokenized during shipout). % % This was put in as some error produced active spaces in a mark, I % think. @@ -2156,7 +2156,7 @@ % % The rest was always inside the box. % -% RmS 91/08/15: aded this line: +% RmS 91/08/15: added this line: % \begin{macrocode} \reset@font % \end{macrocode} @@ -3864,7 +3864,7 @@ % be printed in as small a space as possible, ie it uses any % shrinkability in the column. If the column was not explicitly broken % (\eg with |\pagebreak|) this may result in an overfull box message but -% execpt for this it will come out as expected (if you know what to +% except for this it will come out as expected (if you know what to % expect). % % The star form of this command is dedicated to Leslie Lamport, the @@ -3920,9 +3920,9 @@ % \@tempskipa#2\relax \ifdim \@tempskipa>.5\maxdimen - \@latexerr{Suggested\space extra\space height\space - (\the\@tempskipa)\space dangerously\space - large}\@eha + \@latex@error{Suggested\space extra\space height\space + (\the\@tempskipa)\space dangerously\space + large}\@eha \else \ifdim \vsize<.5\maxdimen %<*trace> @@ -3940,8 +3940,8 @@ \fi % \else - \@latexerr{Page\space height\space already\space - too\space large}\@eha + \@latex@error{Page\space height\space already\space + too\space large}\@eha \fi \fi } @@ -3973,7 +3973,7 @@ % It also enables the use of an extra specifier, {\tt !}, in the % location optional argument of a float. If this is present then, % just for this particular float, whenever it is processed by the float -% mechanism the followinhg are ignored: +% mechanism the following are ignored: % % \begin{itemize} % \item all restrictions on the number of floats which can appear; @@ -4556,7 +4556,7 @@ % Yet another is to move the column count register from the multicol % package into the kernel. This has been done. % \item Where should the reinserts be put to maximise the -% probability that footmotes come out on the correct page? +% probability that footnotes come out on the correct page? % Or should we go for as much compatibility as possible (but see % next item)? % \item Should we continue to support (as much as possible) @@ -4980,7 +4980,7 @@ % % At the top of the page |\@fptop| is inserted; % typically this supplies some stretchable whitespace. -% At the bottom of the page |\@fpbot| ais inserted. +% At the bottom of the page |\@fpbot| is inserted. % Between adjacent floats |\@fpsep| is inserted. % % These parameters are used for all floating objects on a diff --git a/Master/texmf-dist/source/latex/base/ltpage.dtx b/Master/texmf-dist/source/latex/base/ltpage.dtx index 8c7aac0a7b8..4504033f542 100644 --- a/Master/texmf-dist/source/latex/base/ltpage.dtx +++ b/Master/texmf-dist/source/latex/base/ltpage.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltpage.dtx} - [2020/07/27 v1.0m LaTeX Kernel (page style setup)] + [2020/12/05 v1.0m LaTeX Kernel (page style setup)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpage.dtx} @@ -260,7 +260,7 @@ % the problem is solved.} % \changes{v1.0j}{2000/05/26}{Use \cs{@empty} instead of brace group % (pr/3203).} -% \task{???}{mark initialisation solved?} +% \task{???}{mark initialization solved?} % \begin{macrocode} \def\@markright#1#2#3{\@temptokena {#1}% \unrestored@protected@xdef\@themark{{\the\@temptokena}{#3}}} diff --git a/Master/texmf-dist/source/latex/base/ltpageno.dtx b/Master/texmf-dist/source/latex/base/ltpageno.dtx index 6374f58b89a..03d36a53d98 100644 --- a/Master/texmf-dist/source/latex/base/ltpageno.dtx +++ b/Master/texmf-dist/source/latex/base/ltpageno.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltpageno.dtx} - [1994/05/19 v1.1a LaTeX Kernel (Page Numbering)] + [2020/12/05 v1.1a LaTeX Kernel (Page Numbering)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpageno.dtx} @@ -71,7 +71,7 @@ % assigned by |\newcount|. % % \DescribeMacro{\pagenumbering} -% The user sets the pagenumber style with the |\pagenumbering|\marg{foo} +% The user sets the page number style with the |\pagenumbering|\marg{foo} % command, which sets the page counter to 1 and defines |\thepage| to be % |\foo|. For example, |\pagenumbering{roman}| causes pages to be % numbered i, ii, etc. diff --git a/Master/texmf-dist/source/latex/base/ltpar.dtx b/Master/texmf-dist/source/latex/base/ltpar.dtx index ed1b439e9da..969954be0a7 100644 --- a/Master/texmf-dist/source/latex/base/ltpar.dtx +++ b/Master/texmf-dist/source/latex/base/ltpar.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltpar.dtx} - [1995/04/29 v1.1c LaTeX Kernel (paragraphs)] + [2021/04/13 v1.1c LaTeX Kernel (paragraphs)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpar.dtx} @@ -67,9 +67,11 @@ % |\par| and |\everypar| when ever their function needs to be % changed for a long time. % -% \StopEventually{} -% -% \subsection{Implementation} +% This file here describes the interfaces that have been in the kernel +% forever, used to implement the scenarios described below. They +% remain valid but are now augmented in the next file +% (\texttt{ltpara.dtx}) to add hooks to paragraphs. At some point we +% will consolidate the two files further. % % % There are two situations in which |\par| may be changed: @@ -93,6 +95,12 @@ % \end{itemize} % \end{itemize} % +% +% \StopEventually{} +% +% \subsection{Implementation} +% +% % \DescribeMacro{\@setpar} % To permit the proper interaction of these two situations, long-term % changes are made by the |\@setpar{|\meta{VAL}|}| command. diff --git a/Master/texmf-dist/source/latex/base/ltpara.dtx b/Master/texmf-dist/source/latex/base/ltpara.dtx new file mode 100644 index 00000000000..5ab52a5e9bc --- /dev/null +++ b/Master/texmf-dist/source/latex/base/ltpara.dtx @@ -0,0 +1,1223 @@ +% \iffalse meta-comment +% +%% File: ltpara.dtx (C) Copyright 2020-2021 +% Frank Mittelbach, LaTeX Team +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% license or (at your option) any later version. The latest version +% of this license is in the file +% +% https://www.latex-project.org/lppl.txt +% +% +%%% From File: ltpara.dtx +% +% \begin{macrocode} +\def\ltparaversion{v1.0g} +\def\ltparadate{2021/05/27} +% \end{macrocode} +%<*driver> +\documentclass{l3doc} + +%\usepackage{ltpara} + +% Fixing footnotes in functions and variables: this should be in l3doc! +\newcommand\fixfootnote[2]{\footnotemark + \AddToHookNext{env/#1/after}{\footnotetext{#2}}} +\AddToHook{env/function/begin}{\def\footnote{\fixfootnote{function}}} +\AddToHook{env/variable/begin}{\def\footnote{\fixfootnote{variable}}} + +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{ltpara.dtx} +\end{document} +% +% +% \fi +% +% \providecommand\hook[1]{\texttt{#1}} +% \providecommand\env[1]{\texttt{#1}} +% +% +% +% \title{The \texttt{ltpara.dtx} code\thanks{This file has version +% \ltparaversion\ dated \ltparadate, \copyright\ \LaTeX\ +% Project.}} +% \author{Frank Mittelbach} +% +% \maketitle +% +% +% \begin{abstract} +% This code defines four special kernel hooks to support paragraph +% tagging as well as four public hooks which can be occasionally +% useful. +% \end{abstract} +% +% \tableofcontents +% +% +% \section{Introduction} +% +% +% The building of paragraphs in the \TeX{} engine(s) has a number +% of peculiarities that makes it on one hand fairly flexible but on +% the other hand somewhat awkward to control or reliably to extend. +% Thus to better understand the code below we start with a brief introduction +% of the mechanism; for more details refer to the +% \TeX{}book~\cite[chap.~14]{texbook} (for the full truth you may +% even have to study the program code). +% +% \subsection{The default processing done by the engine} +% +% \TeX{} automatically starts building a paragraph when it is +% currently in vertical mode and encounters anything that can only +% live in horizontal mode. Most often this is a character, but +% there are also many commands that can be used only in horizontal mode. +% If any of them is encountered, \TeX{} will immediately back up +% (i.e., the character or command is read later again), adds a +% \cs{parskip} glue to the current vertical list unless the list is +% empty, switches to +% horizontal mode, starts its special \enquote{start of paragraph +% processing} and only then rereads the character or command that +% caused the mode change.\footnote{Already not quite true: the +% command \cs{noindent} starts the paragraph but influences the +% special processing by suppressing the paragraph indentation box +% normally inserted by it.} +% +% This \enquote{start of paragraph +% processing} first adds an empty box at the start of the +% horizontal list of width \cs{parindent} (which represents the +% paragraph indentation) unless the paragraph was started with +% \cs{noindent} in which case no such box is +% added\footnote{That's a bit different from placing a zero-sized +% box!}. It then reads and processes all tokens stored in the +% special engine token register \cs{everypar}. After that it reads +% and processes whatever has caused the paragraph to start. +% +% Thus out of the box, \TeX{} offers the possibility to put some +% special code into \cs{everypar} to gain control at (more or less) +% the start of the paragraph. For example, in LaTeX{} and a number +% of packages, special code like the following is sometimes used: +%\begin{verbatim} +% \everypar{{\setbox\z@\lastbox}\everypar{} ...} +%\end{verbatim} +% This removes the paragraph indentation box again (that was already +% placed by \TeX), then resets \cs{everypar} so that it doesn't do +% anything on the next paragraph start and then does whatever it +% wants to do, e.g., in an \cs{item} of a list it will typeset the label in +% front of the paragraph text. +% However, there is only one such \cs{everypar} token register and +% if different packages and/or the kernel all attempt to add their +% own code here, coordination is very difficult if not impossible. +% +% The process when the paragraph ends has different mechanisms and interfaces. +% A paragraph ends when the engine primitive \cs{par} is called +% while \TeX{} is in unrestricted horizontal mode, i.e., is +% building a paragraph. At other times this primitive does nothing +% or generates as an error depending on the mode \TeX{} is in, +% e.g., the \cs{par} in +% \verb=\hbox{a\par b}= is ignored, but \verb=$a\par b$= would complain. +% +% If this primitive ends the paragraph it does some special +% \enquote{end of horizontal list} processing, then calls \TeX{} paragraph +% builder that breaks the horizontal list into lines then these +% lines are added as boxes to the enclosing vertical list and +% \TeX{} returns to vertical mode. +% +% This \cs{par} command can be given explicitly, but there are also +% situations in which \TeX{} is generating it on the fly. Most +% often this happens when \TeX\ encounters a blank line which is +% automatically changed to a \cs{par} command which is then +% executed. The other possibility is that \TeX{} encounters a +% command which is incompatible with horizontal processing, e.g., +% \cs{vskip} (a request for adding vertical space). In such case it +% silently backs up, and inserts a \cs{par} in the hope that this +% gets it out of horizontal mode and makes the offending command +% acceptable. + +% The important point to note here is that \TeX{} really inserts +% the command \cs{par} which can be redefined. Thus, it may not have +% its original \enquote{primitive} meaning and therefore may not end the +% horizontal list and call the paragraph builder. This approach +% offers some flexibility but also allows you to easily produce a +% \TeX{} document that loops forever, for example, the simple line +%\begin{verbatim} +% A \let\par\relax \vskip +%\end{verbatim} +% will start a horizontal list at \texttt{A}, redefines \cs{par}, +% then sees \cs{vskip} and inserts \cs{par} to end the +% paragraph. But this now only runs \cs{relax} so nothing changes +% and \cs{vskip} is read again, issues a \cs{par} which \ldots. In +% short, it takes a plain \TeX{} document with five tokens to run +% forever (as not even memory is consumed and therefore eventually +% exhausted). +% +% There are no other ways than changing \cs{par} to gain control at +% the end of a paragraph, i.e., there is no token list like +% \cs{everypar} that is inserted, i.e., the only way to change the +% default behavior is to modify the action that \cs{par} executes +% with similar issues as outlined before: different processes need +% to ensure that they do not overwrite their modifications or +% worse, think that the \cs{par} in front of them is the engine +% primitive while in fact it has already been changed by other +% code. +% +% +% To make matters slightly worse there are a few places where +% \TeX{} handles the situation differently (most likely for speed +% reasons back when computers were much slower). If \TeX{} finds +% itself in unrestricted horizontal mode at the end of building a +% vertical box (or an \cs{insert}, \cs{vadjust} or at the end of +% executing the output routine code), it will finish the horizontal +% list not by issuing a \cs{par} command (which would be consistent +% with all other places, but by simply executing the primitive version +% of \cs{par} regardless of the definition that \cs{par} has at the +% time. +% +% Thus, if you have carefully crafted a redefined \cs{par} to execute +% some special actions at the end of a paragraph and you write +% something like +%\begin{verbatim} +% \vbox{Some paragraph ... text.} +%\end{verbatim} +% you will find that your code has never run for the last paragraph +% in that box. \LaTeX{} avoids this problem, by making sure that +% all its boxes (such as \cs{parbox} or the \env{minipage} +% environment, etc.) all internally add an explicit \cs{par} at the +% end so that such code is run and \TeX{} finds itself in vertical +% mode already without the need to start up the paragraph builder +% internally. But, of course, this only works for boxes under direct +% control of the \LaTeX{} kernel, if some package uses low-level +% \cs{vbox}es without adding this precaution the \TeX{} +% optimization kicks in and no special \cs{par} code is executed. +% +% And there is another optimization that is painful: if a paragraph +% is interrupted by a mathematical display, e.g., \verb=\[...\]= in +% \LaTeX{} or \verb=$$...$$= in plain \TeX{}, then \TeX{} will +% resume horizontal mode afterward, i.e., build a new horizontal +% list (without inserting an indentation box or \cs{everypar} at +% that point). However, if that list immediately ends with an +% explicit or implicit \cs{par} then \TeX{} will simply throw away +% this \enquote{null} paragraph and not do its usual \enquote{end +% of horizontal list} processing, so this special case need to be +% accounted for when introducing some extended processing. +% +% +% +% \section{The new mechanism implemented for \LaTeX{}} +% +% To improve the situation (and also to support automatic tagging +% of PDF documents) we now offer public as well as private hooks at +% the start and end of the paragraph processing. The public hooks +% can be used by packages (or by the user in the preamble or +% within the document) and using the hook mechanisms it is possible +% to reorder or arrange code from different packages in a way that +% it can safely coexist. +% +% To make that happen we have to make use of the basic +% functionality that is offered by \TeX{}, e.g., we install +% special code inside \cs{everypar} to provide hooks at the +% beginning and we redefine \cs{par} to do some special processing +% when appropriate to install hooks at the end of the paragraph. +% +% In order to make this work, we have to ensure that package use of +% \cs{everypar} is not overwriting our code. This is done through a +% trick: we basically hide the real \cs{everypar} from the packages +% and offer them a new token register (with the same name). So if +% they install their own code it doesn't overwrite ours. Our code +% then inserts the new \cs{everypar} at the right place inside the +% process so that it looks as if it was the primitive +% \cs{everypar}.\footnote{Ideally, \cs{everypar} wouldn't be used +% at all by packages and instead they would simply write their code +% into the hooks now offered by the kernel. However, while this is +% the longterm goal and clearly an improvement (because then the +% packages do no longer need to worry about getting their code +% overwritten or needing to account for already existing code in +% \cs{everypar}), this will not happen overnight. For that reason +% support for this legacy method is retained.} +% +% At the end of the paragraph it would be great if we could use a +% similar trick. However, due to the fact that \TeX{} inserts the +% token \cs{par} (that doesn't have a defined meaning) we can't hide +% \enquote{the real thing\textsuperscript{TM}} and offer the +% package an indistinguishable alternate. +% +% Fortunately, \LaTeX{} has already redefined \cs{par} for its own +% purposes. As a result there aren't many packages that attempt to +% change \cs{par}, because without a lot of extra care that would +% fail miserably. But bottom line, if you load a package that +% alters \cs{par} then the end of paragraph hooks are most likely +% not executing while that redefinition is +% active.\footnote{Similarly to the \cs{everypar} situation, the +% remedy is that such packages stop doing this and instead add +% their alterations into the paragraph hooks now provided.} +% +% +% +% \subsection{The provided hooks} +% +% +% \begin{variable}{para/before, +% para/begin, +% para/end, +% para/after +% } +% The following four public hooks are defined and executed for +% each paragraph: +% \begin{description} +% +% \item[\hook{para/before}] +% +% This hook is executed after the kernel hook +% \cs{@kernel@before@para@before} (discussed below) in vertical +% mode immediately after \TeX{} has contributed \cs{parskip} to +% the vertical list and before the actual paragraph processing in +% horizontal mode starts. +% +% This hook should either not produce any typeset material or add +% only vertical material. If it starts a paragraph an error is +% generated. The reason is that we are in the starting process of +% processing a paragraph and so this would lead to endless +% recursion.\footnote{One could allow it but only if the newly +% started paragraph is processed without any hooks. Furthermore +% correct spacing would be a bit of a nightmare so for now this +% is forbidden.} +% +% \end{description} +% \end{variable} +% +% \vspace{-\bigskipamount} +% +% \begin{description} +% +% \item[\hook{para/begin}] +% +% This hook is executed after the kernel hook +% \cs{@kernel@before@para@begin} (discussed below) in horizontal +% mode immediately before the indentation box is placed (if there +% is any, i.e., if the paragraph hasn't been started with +% \cs{noindent}). +% +% The indentation box to be typeset is available to the hook as +% \cs{IndentBox} and its automatic placement (after the hook is +% executed) can be prevented through \cs{OmitIndent}. +% More precisely \cs{OmitIndent} voids the box. +% +% The indentation box is then typeset directly +% after the hook execution by something equivalent to +% \cs{box}\cs{IndentBox} followed by the current content of +% the token register \cs{everypar} that it is available to the +% kernel or to packages (that run some legacy code). +% +% One has to be careful not to add any code to the hook that +% starts its own paragraph (e.g., by adding a \cs{parbox} or a +% \cs{marginpar} inside) because that would call the hook inside +% again (as a new paragraph is started there) and thus lead to an +% endless recursion ending only after exhausting the available +% memory. This can only be done by making sure that is not +% executed for the inner paragraphs (or at least not recursively +% forever). +% +% +% \item[\hook{para/end}] +% +% This hook is executed at the end of a paragraph when \TeX{} is +% ready to return to vertical mode and after it has removed the +% last horizontal glue (but not kern) placed on the horizontal +% list. The code is still executed in horizontal mode so it is +% possible to add further horizontal material at this point, but +% it should not alter the mode (even a temporary exit from +% horizontal mode would create chaos---any attempt will cause an +% error message)! After the hook has ended the kernel hook +% \cs{@kernel@after@para@end} is executed and then \TeX{} returns to +% vertical mode. +% +% The hook is offered as public hook, but because of the +% requirement to stay within horizontal mode one needs to be +% careful in what is placed into the hook.\footnote{Maybe we +% should guard against that, but it would be rather tricky to +% implement as mode changes can happen across group boundaries so +% one would need to keep a private stack just for that. Well, +% something to ponder.} +% +% This hook is implemented as a reversed hook. +% +% \item[\hook{para/after}] +% +% This hook is executed directly after \TeX{} has returned to +% vertical mode and after any material that migrated out of the +% horizontal list (e.g., from a \cs{vadjust}) has processed. +% +% This hook should either not produce any typeset material or add +% only vertical material. +% However, for this hook starting a new paragraph is not a +% disaster so that it isn't prevented. +% +% This hook is implemented as a reversed hook. +% +% Once that hook code has been processed the kernel hook +% \cs{@kernel@after@para@after} is executed as the final action +% of the paragraph processing. +% +% \end{description} +% +% \begin{variable}{\@kernel@before@para@before, +% \@kernel@after@para@after, +% \@kernel@before@para@begin, +% \@kernel@after@para@end, +% } +% As already mentioned above there are also four kernel hooks that +% are executed at the start and end of the processing. +% \begin{description} +% +% \item[\cs{@kernel@before@para@before}] +% For future extensions, not currently used by the kernel. +% +% +% \item[\cs{@kernel@after@para@after}] +% For future extensions, not currently used by the kernel. +% +% +% \item[\cs{@kernel@before@para@begin}] +% +% Used by the kernel to implement tagging. This hook is executed +% at the very beginning of a paragraph after \TeX{} has switched to +% horizontal mode but before any indentation box got added or any +% \cs{everypar} was run. +% +% It should not generate typeset material that could alter the +% position. Note that it should never leave hmode, otherwise you +% will end with a loop! We could guard against this, but since it +% is an internal kernel hook that shouldn't be touched this isn't +% checked. +% \end{description} +% \end{variable} +% +% \vspace{-\bigskipamount} +% +% \begin{description} +% +% \item[\cs{@kernel@after@para@end}] +% +% Used by the kernel to implement tagging. It is executed +% directly after the public \hook{para/end} hook. After it there +% is a quick check that we are still in horizontal mode, i.e., +% that the public hook has not mistakenly ended horizontal mode +% prematurely (this is an incomplete check just testing the mode +% and could perhaps be improved (at the cost of speed)). +% +% \end{description} +% +% +% \subsection{Altered and newly provided commands} +% +% \begin{function}{\par,\endgraf,\para_end:} +% An explicit request for ending a paragraph is known in plain +% \TeX{} under the name \cs{endgraf} where it simply calls the +% paragraph primitive (regardless of what \cs{par} may have as its +% current definition). In \LaTeX{} \cs{endgraf} with that behavior +% was also made available. +% +% With the new paragraph handling in \LaTeX{}, ending a paragraph +% means a bit more than just calling the engine's paragraph +% builder: the process also has to add any hook code for the end of +% a paragraph. Thus +% \cs{endgraf} was changed to provide this additional functionality +% (and so by extension \cs{par} subject to its current meaning). +% +% The \pkg{expl3} name for the functionality is \cs{para_end:}. +% \end{function} +% +% \begin{quote} +% \textbf{Note:} \em The next two commands are still under +% discussion and may slightly change their semantics (as described +% in the document) and/or their names between now and the 2021 +% Spring release! +% \end{quote} +% +% \begin{function}{\OmitIndent,\para_omit_indent:} +% Inside the \hook{para/begin} hook one can use this command to +% suppress the indentation box at the start of the +% paragraph. (Technically it is possible to use this command +% outside the hook as well, but this should not be relied upon.) +% The box itself remains available for use. +% +% The \pkg{expl3} name for the function is \cs{para_omit_indent:}. +% \end{function} +% +% \begin{variable}{\IndentBox,\g_para_indent_box} +% The box register holding the indentation box for the paragraph is +% available for inspection (or changes) inside hooks. It remains +% available even if the \cs{OmitIndent} command was +% used; in that case it will just not be automatically placed. +% +% The \pkg{expl3} name for the box register is \cs{g_para_indent_box}. +% \end{variable} +% +% +% \begin{function}{\RawIndent,\para_raw_indent:, +% \RawNoindent,\para_raw_noindent:, +% \RawParEnd,\para_raw_end:} +% \begin{syntax} +% \cs{RawIndent} \textit{hmode material} \cs{RawParEnd} +% \cs{RawNoindent} \textit{hmode material} \cs{RawParEnd} +% \end{syntax} +% +% The commands \cs{RawIndent} and \cs{RawNoindent} are not meant +% for normal paragraph building (where the result is a textual +% paragraph in the the traditional meaning of the word), but for +% special cases where \TeX{}'s low-level algorithm is used to +% achieve special effects, but where the result is not a +% \enquote{paragraph}. +% +% They are called \enquote{raw}, because they bypass \LaTeX{}'s +% hook mechanism for paragraphs and simply invoke the low-level +% \TeX{} algorithm. I.e., they are like the original \TeX{} +% primitives \cs{indent} and \cs{noindent} (that is they execute no +% hooks other than \cs{everypar}) except that they can only be used +% in vertical mode and generate an error if found elsewhere. +% +% To avoid issues a paragraph started by them should always be +% ended by \cs{RawParEnd}\footnote{Technical note for those who +% know their \textit{\TeX book\/}: the \cs{RawParEnd} comand +% invokes the original \TeX{} engine definition of \cs{par} that +% (soley) triggers the paragraph builder in \TeX{} when found +% inside unrestricted horizontal mode and does nothing in other +% processing modes.} +% and not by \cs{par} (or a blank line), because the latter will execute +% hooks which then have no counterpart at the beginning of the +% paragraph. It is the responsibility of the programmer to make +% sure that they are properly paired. This also means that one +% should not put arbitrary user content between these commands if +% that content could contain stray \cs{par}s. +% +% The \pkg{expl3} names for the functions are +% \cs{para_raw_indent:}, \cs{para_raw_indent:} and +% \cs{para_raw_end:}. +% \end{function} +% +% +% +% \subsection{Examples} +% +% None of the examples in this section are meant for real use as +% they are far too simpleminded but they should give some ideas of +% what could be possible if a bit more care is applied. +% +% \subsubsection{Testing the mechanism} +% +% The idea is to output for each paragraph encountered some +% information: a paragraph sequence number, a level number in roman +% numerals, the environment in which this paragraph appears, and +% the line number where the start or end of the paragraph is, e.g., +% something like +%\begin{verbatim} +% PARA: 1-i start (document env. on input line 38) +% PARA: 1-i end (document env. on input line 38) +% PARA: 2-i start (document env. on input line 40) +% PARA: 3-ii start (minipage env. on input line 40) +% PARA: 3-ii end (minipage env. on input line 40) +% PARA: 2-i end (document env. on input line 41) +%\end{verbatim} +% As you can see paragraph 2 starts on line 40 and ends on 41 and +% inside a minipage started paragraph 3 (start and end on line 40). +% If you run this on some document you will find that \LaTeX{} +% considers more things \enquote{a paragraph} than you have +% probably thought. +% +% This was generated by the following hook code: +%\begin{verbatim} +% \newcounter{paracnt} % sequence counter +% \newcounter{paralevel} % level counter +%\end{verbatim} +% +% To support paragraph nesting we need to maintain a stack of the +% sequence numbers. This is most easily done using \pkg{expl3} +% functions, so we switch over. This is not a very general +% implementation, just enough for what we need and a bit of +% \LaTeXe{} thrown in as well. When popping the result gets stored +% in \cs{paracntvalue} and the \cs{ERROR} should never happen +% because it means we have tried to pop from an empty stack. +%\begin{verbatim} +% \ExplSyntaxOn +% \seq_new:N \g_para_seq +% \cs_new:Npn \ParaPush +% {\seq_gpush:No \g_para_seq {\the\value{paracnt}}} +% \cs_new:Npn \ParaPop {\seq_gpop:NNF \g_para_seq \paracntvalue \ERROR } +% \ExplSyntaxOff +%\end{verbatim} +% At the start of the paragraph increment both sequence counter and +% level and also save the then current sequence number on our stack. +%\begin{verbatim} +% \AddToHook{para/begin}{% +% \stepcounter{paracnt}\stepcounter{paralevel}% +% \ParaPush +%\end{verbatim} +% To display the sequence number we \cs{typeout} the current +% sequence and level number. The command \cs{@currenvir} gives us +% the current environment and \cs{on@line} produces a space and +% the current input line number. +%\begin{verbatim} +% \typeout{PARA: \arabic{paracnt}-\roman{paralevel} start +% (\@currenvir\space env.\on@line)}% +%\end{verbatim} +% We also typeset the sequence number as a tiny red number in a box +% that takes up no horizontal space. This helps us seeing where +% \LaTeX{} sees the start and end of the paragraphs in the +% document. +%\begin{verbatim} +% \llap{\color{red}\tiny\arabic{paracnt}\ }% +% } +%\end{verbatim} +% +% At the end of the paragraph we display sequence number and +% level again. The level counter has the correct value but we need +% to retrieve the right sequence value by popping it off the stack +% after which it is available in \cs{paracntvalue} the way we have +% set this up above. +%\begin{verbatim} +% \AddToHook{para/end}{% +% \ParaPop +% \typeout{PARA: \paracntvalue-\roman{paralevel} end \space\space +% (\@currenvir\space env.\on@line)}% +%\end{verbatim} +% We also typeset again a tiny red number with that value, this +% time sticking out to the right.\footnote{Note that this can alter +% the document pagination, because a paragraph ending in a display +% (e.g., an equation) will get an extra line---in that case our tiny number +% has an effect even though it doesn't take up any space, because +% it paragraph is no longer empty and thus isn't dropped!} +% We also decrement the level counter since our level has finished. +%\begin{verbatim} +% \rlap{\color{red}\tiny\ \paracntvalue}% +% \addtocounter{paralevel}{-1}% +% } +% \makeatother +%\end{verbatim} +% +% +% +% \subsubsection{Mark the first paragraph of each \env{itemize}} +% +% The code for this is rather simple. We apply hook code that is +% executed only once inside a hook that is executed at the begin of +% each \env{itemize}. We explicitly change the color back and +% forth so that we don't introduce grouping around the paragraph. +%\begin{verbatim} +% \AddToHook{env/itemize/begin}{% +% \AddToHookNext{para/begin}{\color{blue}}% +% \AddToHookNext{para/end}{\color{black}}% +% } +%\end{verbatim} +% As a result the first paragraph of each \env{itemize} will appear +% in blue. +% +% +% +% \subsection{Some technical notes} +% +% The code tries hard to be transparent for package code, but of +% course any change means that there is a potential for breaking +% other code. So in section we collect a few cases that may be of +% importance if low-level code is dealing with paragraphs that are +% now behaving slightly differently. The notes are from issues we +% observed and will probably grow over time. +% +% \subsubsection{Glue items between paragraphs (found with \pkg{fancypar})} +% +% In the past \LaTeX{} placed two glue items between two +% consecutive paragraph, e.g., +%\begin{verbatim} +% text1 \par text2 \par +%\end{verbatim} +% would show something like +%\begin{verbatim} +% \glue(\parskip) 0.0 plus 1.0 +% \glue(\baselineskip) 5.16669 +%\end{verbatim} +% but now there is anothe \cs{parskip} glue (that is always 0pt): +%\begin{verbatim} +% \glue(\parskip) 0.0 plus 1.0 +% \glue(\parskip) 0.0 +% \glue(\baselineskip) 5.16669 +%\end{verbatim} +% The reason is that we generate a \enquote{fake}'' paragraph to +% gain control and safely add the early hooks, but this generates +% an additional glue item. That item doesn't contribute anything +% vertically but ifsomebody writes code the unravels a constructed +% list using \cs{lastbox}, \cs{unskip} and \cs{unpenalty} then the +% code has to remove one additional glue item or else will fail. + +% +% ^^A \subsubsection{} +% +% +% +% ^^A \subsubsection{} +% +% +% +% +% +% +% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } +% +% +% \section{The Implementation} +% +% \begin{macrocode} +%<@@=para> +% \end{macrocode} +% +% \changes{v1.0g}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} +% +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +\ExplSyntaxOn +%\NewModuleRelease{2021/06/01}{ltpara} +% {Paragraph~handling~and~hooks} +% \end{macrocode} +% +% +% +% \subsection{Providing hooks for paragraphs} +% +% +% \begin{macro}{para/before,para/after,para/begin,para/end} +% The public hooks. They are implemented as a paired set of hooks. +% \begin{macrocode} +\hook_new_pair:nn{para/before}{para/after} +\hook_new_pair:nn{para/begin}{para/end} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@kernel@before@para@before, +% \@kernel@after@para@after, +% \@kernel@before@para@begin, +% \@kernel@after@para@end} +% The corresponding kernel hooks (for tagging and future extensions). +% \begin{macrocode} +\let \@kernel@before@para@before \@empty +\let \@kernel@before@para@begin \@empty +\let \@kernel@after@para@end \@empty +\let \@kernel@after@para@after \@empty +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\g_@@_standard_everypar_tl} +% Whenever \TeX{} starts a paragraph it inserts first an +% indentation box and then executes the tokens stored in +% \cs{tex_everypar:D} (known to \LaTeX{} as \cs{everypar}). We +% alter this behavior slightly here, so that hooks are added +% into the right place. Otherwise the process change remains +% transparent to any legacy code for this space. +% +% We keep the standard code to be used by \cs{tex_everypar:D} in a +% separate token list because we have to switch back and forth +% for error recovery and so altering \cs{tex_everypar:D} all the +% time should be a tiny bit faster. +% \begin{macrocode} +\tl_new:N \g_@@_standard_everypar_tl +% \end{macrocode} +% Here is now its definition: +% \begin{macrocode} +\tl_gset:Nn \g_@@_standard_everypar_tl { +% \end{macrocode} +% First we remove the indentation box and store it in +% \cs{g_para_indent_box}. If there was none because the paragraph +% was started by \cs{noindent} the box register will be void. +% \begin{macrocode} + \box_gset_to_last:N \g_para_indent_box +% \end{macrocode} +% +% This will make the newly started horizontal list empty, so if we +% stop it now and return to vertical mode it will be dropped by +% \TeX{}. We do that but inside a group so that any \cs{parshape} +% settings will not get lost as we need them for later. +% \begin{macrocode} + \group_begin: + \tex_par:D + \group_end: +% \end{macrocode} +% We then change \cs{tex_everypar:D} to generate an error so that +% we can detect and report if the \hook{para/before} hook illegally +% changed out of vmode. +% \begin{macrocode} + \tex_everypar:D { \msg_error:nnnn { hooks }{ para-mode }{before}{vertical} } + \@kernel@before@para@before + \hook_use:n {para/before} +% \end{macrocode} +% Assuming the hooks have been well behaved it is time to return to +% horizontal mode and start the paragraph in earnest. We already +% have the indentation box saved away so we now have to restart the +% paragraph with an empty \cs{tex_everypar:D} and with +% \cs{tex_noindent:D}. And we need to make sure not to get another +% \cs{parskip} or rather (since we can't prevent that) that it is +% of zero size. +% \begin{macrocode} + \group_begin: + \tex_everypar:D {} + \skip_zero:N \tex_parskip:D + \tex_noindent:D + \group_end: +% \end{macrocode} +% That brings us back to the start of the horizontal list but we +% need to change \cs{tex_everypar:D} back to its normal content in +% case there are nested paragraphs coming up. +% \begin{macrocode} + \tex_everypar:D{\g_@@_standard_everypar_tl} +% \end{macrocode} +% +% This is followed by executing the kernel and the public hook. The +% kernel hook is there to enable tagging. +% \begin{macrocode} + \@kernel@before@para@begin + \hook_use:n {para/begin} +% \end{macrocode} +% If we aren't in horizontal mode any longer the hooks above misbehaved. +% \begin{macrocode} + \if_mode_horizontal: \else: + \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi: +% \end{macrocode} +% Finally we reinsert the indentation box (unless suppressed) and +% then call \cs{everypar} the way legacy \LaTeX\ code expects it. +% +% However, adding the public \cs{everypar} is a bit tricky (see below) so +% we add that later, and indirectly. +% \begin{macrocode} + \@@_handle_indent: +% \the \everypar % <--- done differently below +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\tex_everypar:D} +% \cs{tex_everypar:D} then only has to execute +% \cs{g_@@_standard_everypar_tl} by default. +% \begin{macrocode} +\tex_everypar:D{\g_@@_standard_everypar_tl} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}[int]{\everypar} +% +% Tokens inserted at the beginning of the paragraph are placed into +% \cs{everypar} inside legacy \LaTeX{} code, e.g., by the list +% environments or by headings to handle \cs{clubpenalty}, etc. Now +% this isn't any longer the primitive but simply a toks register +% used in the code above but to legacy \LaTeX{} code that is +% transparent. +% +% There is, however, a problem: a handful packages use exactly the +% same trick and replace the primitive with a token register and +% call the token register inside the renamed primitive. That is +% they assume that \cs{everypar} is the primitive and that it will +% still be called at the start of the paragraph even if renamed. +% +% But if we have already replaced it by a token register then all +% they do is to give that token register a new name. Thus our code +% in \cs{tex_everypar:D} would call \cs{everypar} (which is their +% now token register) and the code that they added ends up in our +% token register which is then never used at all. A bit mind +% boggling I guess. +% +% So what we have to do is not to call the token register +% \cs{everypar} by its name inside \cs{tex_everypar:D} but by using +% its actual register number. +% \begin{macrocode} +\newtoks \everypar +% \end{macrocode} +% +% After we have allocated a new toks register with the name +% \cs{everypar} the actual register number is available (briefly) +% inside \cs{allocationnumber}. So instead of \cs{the}\cs{everypar} +% we have to put \cs{the}\cs{toks}\meta{allocated number} at the end of +% \cs{tex_everypar:D}. +% +% So what remains doing is to append a few tokens to the token list +% \cs{g_@@_standard_everypar_tl} which we do now. We use \texttt{x} +% expansion here to get the value of \cs{allocationnumber} in, all +% the other tokens should not be expanded at this point. + +% One important point here is to terminate the register allocation +% number with a real space. This space will get swallowed up when +% the number is read. Anything else, such as \cs{scan_stop:} would +% remain in the input and that would mean that it would interfere +% with \cs{everypar} code that attempts to scan ahead to see how +% the paragraph text starts. +% \begin{macrocode} +\tl_gput_right:Nx \g_@@_standard_everypar_tl { + \exp_not:N \the + \exp_not:N \toks + \the \allocationnumber + \c_space_tl +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\g_para_indent_box} +% For managing the indentation we need to provide a public +% accessible box register +% \begin{macrocode} +\box_new:N \g_para_indent_box +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\@@_handle_indent:} +% Adding (typesetting) the indent box is straight forward. +% If it was emptied before it does nothing. +% \begin{macrocode} +\cs_new:Npn \@@_handle_indent: { + \box_use_drop:N \g_para_indent_box +} +% \end{macrocode} +% The declaration \cs{para_omit_indent:} (or +% \cs{OmitIndent}) changes that to do nothing. +% \begin{macrocode} +\cs_new:Npn \para_omit_indent: { + \box_gclear:N \g_para_indent_box +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\IndentBox,\OmitIndent} +% The \LaTeXe{} names for the indentation box and for suppressing it +% for use in the \hook{para/begin} hook. +% \begin{macrocode} +\cs_set_eq:NN \IndentBox \g_para_indent_box +\cs_set_eq:NN \OmitIndent \para_omit_indent: +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\para_end:} +% Adding hooks to the end of a paragraph is similar but here we +% need to alter the command that is used by \TeX{} to end horizontal +% mode and return to vertical mode, i.e., \cs{par}. +% +% This is a bit more complicated as this command can appear anywhere +% either explicitly or implicitly added by \TeX{} in certain +% situations: +% \begin{itemize} +% \item +% when using \cs{par} in the code or the document +% \item +% when using a blank line (which is converted to \cs{par}) +% \item +% when \TeX{} finds any commands incompatible with horizontal +% mode it issues a \cs{par} and then rereads the command. +% \end{itemize} +% +% Unfortunately, \TeX{} has some (these days) unnecessary +% optimization: if a \cs{vbox} ends and \TeX{} is still in +% horizontal mode it simply exercises the paragraph builder instead +% of issuing a \cs{par}. It is therefore necessary for \LaTeX{} to +% ensure that this case doesn't happen and all boxes internally +% have a \cs{par} command at their end. +% +% This \cs{par} may or may not run the ``par primitive'' (which is +% always available as \cs{tex_par:D} in \pkg{expl3}); it is +% permissible to have a changed meaning and it is in fact changed +% by \LaTeX{} in various ways at various points inside +% \texttt{latex.ltx}. For this \LaTeXe{} code has the following +% conventions: \cs{@@@@par} and \cs{endgraf} both refer to the +% default meaning (in the past this was the initex primitive) while +% \cs{par} is the current meaning which may does something else. +% +% +% We are now going to change this default meaning to run +% \cs{para_end:} instead, which ultimately executes the initex +% primitive but additionally adds our hooks when appropriate. +% This way the change is again transparent to the legacy \LaTeXe{} +% code. +% +% In most cases \cs{para_end:} should behave exactly like the +% primitive and we achieve this by simply expanding it to the +% primitive which is available to us as \cs{tex_par:D}. This way we +% don't have to care about whether \TeX{} just does nothing (e.g., +% if in vertical mode already) or generate an error, etc. +% \begin{macrocode} +\cs_new_protected:Npn \para_end: { +% \end{macrocode} +% +% The only case we care about is when we are in horizontal mode +% (i.e., doing typesetting) and not also in inner mode (i.e., +% making paragraphs and not building an \cs{hbox}. +% \begin{macrocode} +% \bool_lazy_and:nnT +% { \mode_if_horizontal_p: } +% { \bool_not_p:n { \mode_if_inner_p: } } +% { ... +% \end{macrocode} +% Since this is executed for each and every paragraph in a document +% we try to stay a fast as possible, So we are aren't using the +% above construct but two conditionals instead. Using low-level +% \cs{if_mode...} conditions would be even faster but has the +% danger to conflict with conditionals in the user hooks. +% \begin{macrocode} + \mode_if_horizontal:TF { + \mode_if_inner:F { +% \end{macrocode} +% In that case the action of the primitive would be to remove the +% last glue (not kern) from the horizontal list constructed to form +% a paragraph then append the a penalty of 10000 and the +% \cs{parfillskip} at the end and pass the whole list to the +% paragraph builder which breaks it into lines and \TeX{} then +% returns to vertical mode. +% +% What we want to do instead is to add our hook code at the end of +% the horizontal list before that happens and the code is passed to +% the paragraph builder. If there was a glue item at the end then +% it should get removed before the hook code gets added so we have +% to arrange for its removal ourselves. +% +% There is not much point in checking if there was really a glue +% item at the end of the horizontal list, instead we simply try to +% remove one using \cs{tex_unskip:D}, if there wasn't one this will +% do nothing. +% \begin{macrocode} + \tex_unskip:D +% \end{macrocode} +% The we execute the public hook (which may add final typesetting +% material) followed by the kernel hook we need for adding tagging +% support. None of this is supposed to change the mode---at the +% moment we make only a very simple test for this, more devious +% changes go unnoticed, but too bad, that will then probably +% badly backfire. +% \begin{macrocode} + \hook_use:n{para/end} + \@kernel@after@para@end + \mode_if_horizontal:TF { +% \end{macrocode} +% The final action (before getting to the point where +% \cs{tex_par:D} is called) is to add a kern item so that the +% primitive is prevented from removing glue (if there was some). If +% we don't do this and the +% horizontal list ended in several glue items we would end up with +% removing two instead of just the last one, which would be wrong. +% We use a kern as that is minimally faster. +% +% There is however one other \TeX{} optimization that hurts: in a +% sequence like this \verb=$$ ... $$ \par= \TeX{} will be in +% horizontal mode after the display, ready to receive further +% paragraph text, but since the \cs{par} follows immediately there +% is a ``null'' paragraph at the end and \TeX{} simply throws that +% away. The space between \verb=$$= and \cs{par} got already +% dropped during the display processing so the \cs{par} is not +% removing any space and appending \cs{parfillskip}, instead it +% simply goes silently to vmode. Now if we would had added something (to +% prevent glue removal) that would look to \TeX{} like material +% after the display and so we would end up with an empty paragraph +% just containing \cs{parfillskip}. +% +% We therefore check if the current hlist is empty +% (\cs{tex_lastnodetype:D} has the value \texttt{-1} and +% only if not we add our kern. +% \begin{macrocode} + \if_int_compare:w 0 < \tex_lastnodetype:D + \tex_kern:D \c_zero_dim + \fi: +% \end{macrocode} +% To run the \hook{para/after} hook we first end the +% paragraph. This means that the \cs{tex_par:D} at the very end is +% unnecessary but executing it there unnecessarily is better than +% having code that test for all the different mode possibilities. +% \begin{macrocode} + \tex_par:D + \hook_use:n{para/after} + \@kernel@after@para@after + } +% \end{macrocode} +% If we haven't been in horizontal mode then the earlier hook +% \hook{para/end} is at fault and we report that. +% \begin{macrocode} + { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} } +% \end{macrocode} +% Finally close out the nested conditionals. +% \begin{macrocode} + } + } +% \end{macrocode} +% +% \begin{macrocode} + \tex_par:D +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\para_raw_indent:, +% \para_raw_noindent:, +% \para_raw_end:} +% +% The commands \cs{para_raw_indent:} and \cs{para_raw_noindent:} +% are like the primitives \cs{indent} and \cs{noindent} except that +% they can only be used in vertical mode. +% +% To avoid issues a paragraph started by them should always be +% ended by \cs{para_raw_end:} and not by \cs{para_end:} or +% \cs{par} as the latter will execute hooks which then have no +% counterpart at the beginning of the paragraph. It is the +% responsibility of the programmer to make sure that they are +% properly paired. +% \begin{macrocode} +\cs_new:Npn \para_raw_indent: { + \mode_if_vertical:TF + { + \tex_everypar:D { + \box_gset_to_last:N \g_para_indent_box + \tex_everypar:D { \g_@@_standard_everypar_tl } + \@@_handle_indent: + \the\everypar } + } + { \msg_error:nn { kernel }{ raw-para } } + \tex_indent:D +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \para_raw_noindent: { + \mode_if_vertical:TF + { + \tex_everypar:D { + \tex_everypar:D { \g_@@_standard_everypar_tl } + \the\everypar } + } + { \msg_error:nn { kernel }{ raw-para } } + \tex_noindent:D +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \para_raw_end: \tex_par:D +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\RawIndent,\RawNoIndent,\RawParEnd} +% The \LaTeXe{} names for starting and ending a paragraph without adding any hooks. +% \begin{macrocode} +\cs_set_eq:NN \RawIndent \para_raw_indent: +\cs_set_eq:NN \RawNoindent \para_raw_noindent: +\cs_set_eq:NN \RawParEnd \para_raw_end: +% \end{macrocode} +% \end{macro} +% +% +% This ends the \texttt{para} module code. +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \begin{macro}{\par,\endgraf} +% \begin{macro}[int]{\@@par} +% +% Having the new default definition for \cs{par} we also have to +% set it up so that it gets used. This is needed in three places +% \cs{par}, \cs{@@par} (to which \LaTeX{} resets \cs{par} +% occasionally) and \cs{endgraf} which is another name for the +% ``default'' action of \cs{par}. +% \begin{macrocode} +\cs_set_eq:NN \par \para_end: +\cs_set_eq:NN \@@par \para_end: +\cs_set_eq:NN \endgraf \para_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% While this is not integrated properly into the format we have to +% redo the \cs{everypar} setting from the kernel, otherwise that +% gets lost (as it happens before that file is loaded). +% \begin{macrocode} +\everypar{\@nodocument} %% To get an error if text appears before the +% \end{macrocode} +% +% +% \subsection{The error messages} +% +% This one is used when we detect that some hook code has changed +% the mode where it shouldn't, e.g., by starting or ending a +% paragraph. +% The first argument is the hook name second the mode +% it should have stayed in but didn't. +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { para-mode } + { + Illegal~mode~ change~ in~ hook~ 'para/#1'.\\ + Hook~ code~ did~ not~ remain~ in~ #2~ mode. + } + { + Paragraph~ hooks~ cannot~ change~ the~ TeX~ mode~ without~ causing~ + endless~ recursion.~ The~ hook~ code~ in~ 'para/#1'~ needs~ to~ stay~ + in~ #2~ mode,~ but~ it~ didn't.~ Examine~ the~ hook~ + code~ with~ \iow_char:N \\ShowHook~ to~ find~ the~ issue. + } +% \end{macrocode} +% +% And here is one used in the \enquote{raw} commands when they are +% used outside of vertical mode. +% \begin{macrocode} +\msg_new:nnnn { kernel } { raw-para } + { + Not~ in~ vertical~ mode. + } + { + Starting~ a~ paragraph~ with~ \iow_char:N \\RawIndent~ or~ + \iow_char:N \\RawNoindent \\ + (or~ \iow_char:N \\para_raw_indent:~ or~ + \iow_char:N \\para_raw_noindent:)~ is~ only~ allowed \\ + if~ LaTeX~ is~ in~ vertical~ mode. + } +% \end{macrocode} + + +% \begin{macrocode} +% +%\IncludeInRelease{0000/00/00}% +% {ltpara}{Undo~hooks~for~paragraphs} +% +%\let \OmitIndent \@undefined +%\let \IndentBox \@undefined +%\let \RawIndent \@undefined +%\let \RawNoindent \@undefined +%\let \RawParEnd \@undefined +% +%\cs_set_eq:NN \par \tex_par:D +%\cs_set_eq:NN \@@par \tex_par:D +%\cs_set_eq:NN \endgraf \tex_par:D +% +%\EndModuleRelease +\ExplSyntaxOff +% +% \end{macrocode} +% +% +% +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + diff --git a/Master/texmf-dist/source/latex/base/ltpictur.dtx b/Master/texmf-dist/source/latex/base/ltpictur.dtx index 5bef40375cd..ae8b58995da 100644 --- a/Master/texmf-dist/source/latex/base/ltpictur.dtx +++ b/Master/texmf-dist/source/latex/base/ltpictur.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltpictur.dtx} - [2020/08/14 v1.2a LaTeX Kernel (Picture Mode)] + [2021/04/20 v1.2b LaTeX Kernel (Picture Mode)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltpictur.dtx} @@ -454,9 +454,10 @@ % \end{macro} % % \begin{macro}{\@stackcr} +% \changes{v1.2b}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macro}{\@ixstackcr} % \begin{macrocode} -\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr} +\protected\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr} \def\@ixstackcr{\@ifnextchar[\@istackcr{\cr\ignorespaces}} % \end{macrocode} % \end{macro} @@ -1773,7 +1774,7 @@ % % Initialization: ``|\thinlines|'' % \changes{v1.1f}{1995/10/27} -% {Move initialisation to kernel from autoload file} +% {Move initialization to kernel from autoload file} % \begin{macrocode} \let\@linefnt\tenln \let\@circlefnt\tencirc diff --git a/Master/texmf-dist/source/latex/base/ltplain.dtx b/Master/texmf-dist/source/latex/base/ltplain.dtx index 7949b836d46..e0fbcecf1b6 100644 --- a/Master/texmf-dist/source/latex/base/ltplain.dtx +++ b/Master/texmf-dist/source/latex/base/ltplain.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2020/08/20 v2.3d LaTeX Kernel (Plain TeX)] + [2021/04/18 v2.3f LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -695,7 +695,7 @@ % {Define \cs{alloc@} in terms of \cs{e@alloc}} % Since |\e@alloc| was added in 2015, |\@alloc| has not been used, % but was left as some legacy code calls it. However the original -% defnition gives spurious errors once the ``classic'' registers +% definition gives spurious errors once the ``classic'' registers % run out, so it is now defined to call |\e@alloc| internally. % \begin{macrocode} % @@ -754,8 +754,8 @@ \chardef\e@insert@top\e@alloc@top \fi % \end{macrocode} -% If the classic registers are exausted, take an insert from the free float list -% and use |\extrafloats| to add a new float to that list. +% If the classic registers are exhausted, take an insert from the free +% float list and use |\extrafloats| to add a new float to that list. % \changes{v2.2c}{2016/07/29}{fix for tlb-newinsert-001} % \begin{macrocode} \def\newinsert#1{% @@ -823,6 +823,28 @@ % \end{macrocode} % \end{macro} % +% +% +% \begin{macro}{\@inputcheck} +% \begin{macro}{\@unused} +% Allocate read stream for testing and output stream that is never open an +% thus writes to the terminal. +% \changes{v1.0l}{1994/11/07} +% {move here from ltdefns, remove duplicate \cs{@mainaux}} +% \changes{v2.3e}{2021/03/26}{Allocate \cs{@inputcheck} and +% \cs{@unused} early so that they are before expl3 allocates +% more streams (gh/538)} +% \begin{macrocode} +\newread\@inputcheck +\newwrite\@unused +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% % \begin{macro}{\maxdimen} % \begin{macro}{\hideskip} % Here are some examples of allocation. @@ -898,6 +920,37 @@ % \end{macrocode} % \tracingcommands=0 % \tracingrestores=0 +% \end{macrocode} +% +% \begin{macro}{\tracingstacklevels} +% For Lua\TeX, the \cs{tracingstacklevels} functionality was +% implemented as a callback, so here we just define the count register +% to hold the value of the parameter. +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2021/06/01}{\tracingstacklevels}% +% {tracingstacklevels}% +\ifx\directlua\@undefined + % \tracingstacklevels=0 % added in 2021 +\else + \newcount\tracingstacklevels + % Code for \tracingstacklevels defined in ltfinal.dtx +\fi +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\tracingstacklevels}% +% {tracingstacklevels}% +%\ifx\directlua\@undefined +%\else +% \let\tracingstacklevels\@undefined +%\fi +%\EndIncludeInRelease +% +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% % \language=0 % \begin{macrocode} \uchyph=1 @@ -1481,43 +1534,69 @@ % \changes{v1.1x}{2002/02/24}{Macro added} % \changes{v2.0b}{2012/01/20}{etex tracing if available} % \changes{v2.0d}{2015/02/20}{Spell commands correctly :-)} -% \changes{v2.0g}{2015/03/10}{Reorganise to be less noisy} +% \changes{v2.0g}{2015/03/10}{Reorganize to be less noisy} +% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support} +% \changes{v2.3f}{2021/04/18} +% {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3} % \begin{macrocode} -%\IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}% +%\IncludeInRelease{2021/06/01}{\loggingall} +% {\tracingstacklevels and \tracinglostchars=3}% %<*2ekernel|latexrelease> -\ifx\tracingscantokens\@undefined -\gdef\loggingall{% +\edef\loggingall{% \tracingstats\tw@ \tracingpages\@ne - \tracinglostchars\@ne - \tracingparagraphs\@ne - \errorcontextlines\maxdimen - \loggingoutput - \tracingmacros\tw@ - \tracingcommands\tw@ - \tracingrestores\@ne - }% -\else -\gdef\loggingall{% - \tracingstats\tw@ - \tracingpages\@ne - \tracinglostchars\tw@ + \tracinglostchars\thr@@ \tracingparagraphs\@ne \tracinggroups\@ne \tracingifs\@ne \tracingscantokens\@ne \tracingnesting\@ne \errorcontextlines\maxdimen - \loggingoutput + \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi + \noexpand \loggingoutput \tracingmacros\tw@ \tracingcommands\thr@@ \tracingrestores\@ne \tracingassigns\@ne }% -\fi -\gdef\tracingall{\showoverfull\loggingall} +\def\tracingall{\showoverfull\loggingall} % %\EndIncludeInRelease +% +%\IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}% +%\ifx\tracingscantokens\@undefined +%\gdef\loggingall{% +% \tracingstats\tw@ +% \tracingpages\@ne +% \tracinglostchars\@ne +% \tracingparagraphs\@ne +% \errorcontextlines\maxdimen +% \loggingoutput +% \tracingmacros\tw@ +% \tracingcommands\tw@ +% \tracingrestores\@ne +% }% +%\else +%\gdef\loggingall{% +% \tracingstats\tw@ +% \tracingpages\@ne +% \tracinglostchars\tw@ +% \tracingparagraphs\@ne +% \tracinggroups\@ne +% \tracingifs\@ne +% \tracingscantokens\@ne +% \tracingnesting\@ne +% \errorcontextlines\maxdimen +% \loggingoutput +% \tracingmacros\tw@ +% \tracingcommands\thr@@ +% \tracingrestores\@ne +% \tracingassigns\@ne +%}% +%\fi +%\gdef\tracingall{\showoverfull\loggingall} +%\EndIncludeInRelease +% %\IncludeInRelease{0000/00/00}{\loggingall}{etex tracing}% %\gdef\loggingall{\tracingcommands\tw@\tracingstats\tw@ % \tracingpages\@ne\tracinglostchars\@ne @@ -1532,29 +1611,14 @@ % % \begin{macro}{\tracingnone} % \changes{v2.0g}{2015/03/10}{macro added} -% \begin{macro}{\hideoutput} -% \changes{v2.0g}{2015/03/10}{macro added} +% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support} +% \changes{v2.3f}{2021/04/18} +% {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3} % \begin{macrocode} %\IncludeInRelease{2015/01/01}{\tracingnone}% % {turn off etex tracing}% %<*2ekernel|latexrelease> -\ifx\tracingscantokens\@undefined -\def\tracingnone{% - \tracingonline\z@ - \tracingcommands\z@ - \showboxdepth\m@ne - \showboxbreadth\m@ne - \tracingoutput\z@ - \errorcontextlines\m@ne - \tracingrestores\z@ - \tracingparagraphs\z@ - \tracingmacros\z@ - \tracinglostchars\@ne - \tracingpages\z@ - \tracingstats\z@ -}% -\else -\def\tracingnone{% +\edef\tracingnone{% \tracingassigns\z@ \tracingrestores\z@ \tracingonline\z@ @@ -1563,6 +1627,7 @@ \showboxbreadth\m@ne \tracingoutput\z@ \errorcontextlines\m@ne + \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi \tracingnesting\z@ \tracingscantokens\z@ \tracingifs\z@ @@ -1573,30 +1638,77 @@ \tracingpages\z@ \tracingstats\z@ }% -\fi +% +%\EndIncludeInRelease +% +%\IncludeInRelease{2015/01/01}{\tracingnone}% +% {turn off etex tracing}% +%\ifx\tracingscantokens\@undefined +%\def\tracingnone{% +% \tracingonline\z@ +% \tracingcommands\z@ +% \showboxdepth\m@ne +% \showboxbreadth\m@ne +% \tracingoutput\z@ +% \errorcontextlines\m@ne +% \tracingrestores\z@ +% \tracingparagraphs\z@ +% \tracingmacros\z@ +% \tracinglostchars\@ne +% \tracingpages\z@ +% \tracingstats\z@ +%}% +%\else +%\def\tracingnone{% +% \tracingassigns\z@ +% \tracingrestores\z@ +% \tracingonline\z@ +% \tracingcommands\z@ +% \showboxdepth\m@ne +% \showboxbreadth\m@ne +% \tracingoutput\z@ +% \errorcontextlines\m@ne +% \tracingnesting\z@ +% \tracingscantokens\z@ +% \tracingifs\z@ +% \tracinggroups\z@ +% \tracingparagraphs\z@ +% \tracingmacros\z@ +% \tracinglostchars\@ne +% \tracingpages\z@ +% \tracingstats\z@ +%}% +%\fi +%\EndIncludeInRelease +% +%\IncludeInRelease{0000/00/00}{\tracingnone}% +% {turn off etex tracing}% +%\let\tracingnone\@undefined +%\EndIncludeInRelease % \end{macrocode} +% \end{macro} % +% \begin{macro}{\hideoutput} +% \changes{v2.0g}{2015/03/10}{macro added} % \begin{macrocode} +%<*2ekernel|latexrelease> +%\IncludeInRelease{2015/01/01}{\hideoutput}% +% {hide output from tracing}% \def\hideoutput{% \tracingoutput\z@ \showboxbreadth\m@ne \showboxdepth\m@ne \tracingonline\m@ne }% -% \end{macrocode} -% -% \begin{macrocode} -% %\EndIncludeInRelease -%\IncludeInRelease{0000/00/00}{\tracingnone}% -% {turn off etex tracing}% -%\let\tracingnone\@undefined +% +%\IncludeInRelease{0000/00/00}{\hideoutput}% +% {hide output from tracing}% %\let\hideoutput\@undefined %\EndIncludeInRelease +% % \end{macrocode} % \end{macro} -% \end{macro} -% % % \LaTeX\ change: |\showhyphens| Defined later. % diff --git a/Master/texmf-dist/source/latex/base/ltsect.dtx b/Master/texmf-dist/source/latex/base/ltsect.dtx index 359b445f453..29ea142ba6c 100644 --- a/Master/texmf-dist/source/latex/base/ltsect.dtx +++ b/Master/texmf-dist/source/latex/base/ltsect.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -31,7 +31,7 @@ %%% From File: ltsect.dtx %<*driver> % \fi -\ProvidesFile{ltsect.dtx}[2020/07/27 v1.1e LaTeX Kernel (Sectioning)] +\ProvidesFile{ltsect.dtx}[2020/12/05 v1.1e LaTeX Kernel (Sectioning)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltsect.dtx} @@ -779,7 +779,7 @@ % \changes{v1.1c}{2018/09/26}{Sometimes mask the endline char when % writing to files (github/73)} % \changes{v1.1e}{2020/10/01}{add a fourth argument for better -% hyperref compability} +% hyperref compatibility} % \begin{macrocode} % %<*2ekernel|latexrelease> diff --git a/Master/texmf-dist/source/latex/base/ltshipout.dtx b/Master/texmf-dist/source/latex/base/ltshipout.dtx index e226f753f35..f773cd23da2 100644 --- a/Master/texmf-dist/source/latex/base/ltshipout.dtx +++ b/Master/texmf-dist/source/latex/base/ltshipout.dtx @@ -1,6 +1,7 @@ % \iffalse meta-comment %% -%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team +%% Copyright (C) 2020-2021 +%% Frank Mittelbach, LaTeX Team %% % % This file is part of the LaTeX base system. @@ -31,8 +32,8 @@ %%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v1.0d} -\providecommand\ltshipoutdate{2020/11/24} +\providecommand\ltshipoutversion{v1.0i} +\providecommand\ltshipoutdate{2021/03/17} % \end{macrocode} % %<*driver> @@ -55,6 +56,9 @@ } \ExplSyntaxOff +\providecommand\InternalDetectionOff{} +\providecommand\InternalDetectionOn{} + \EnableCrossrefs \CodelineIndex \begin{document} @@ -75,7 +79,7 @@ % \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\ % Project.}} % -% \author{Frank Mittelbach} +% \author{Frank Mittelbach, \LaTeX{} Project Team} % % \maketitle % @@ -108,11 +112,56 @@ % It then stores it in a named box register. This box can then be % manipulated through a set of hooks after which it is shipped out % for real. +% +% Each shipout that actually happens (i.e., where the material is +% not discarded for one or the other reason) is recorded and the +% total number is available in a readonly variable and in a +% \LaTeX{} counter. +% \end{function} +% +% +% \begin{function}{\RawShipout} +% This command implements a simplified shipout that bypasses the +% foreground and background +% hooks, e.g., only \hook{shipout/firstpage} and +% \hook{shipout/lastpage} are executed and the total shipout +% counters are incremented. +% +% The command doesn't use \cs{ShipoutBox} but its own private box +% register so that it can be used inside of shipout hooks to do +% some additional shipouts while already in the output routine with +% the current page being stored in \cs{ShipoutBox}. It does have +% access to \cs{ShipoutBox} if it is used in \hook{shipout/before} +% (or \hook{shipout/after}) and can use its content. +% +% It is safe to use it in \hook{shipout/before} or +% \hook{shipout/after} but not necessarily in the other +% \hook{shipout/...} hooks as they are intended for special +% processing. % \end{function} % % \begin{variable}{\ShipoutBox,\l_shipout_box} -% This box register is called \cs{ShipoutBox} (alternatively available via the -% L3 name \cs{l_shipout_box}). +% This box register is called \cs{ShipoutBox} (alternatively +% available via the L3 name \cs{l_shipout_box}). +% +% This box is a ``local'' box and assignments to it should be done +% only locally. Global assignments (as done by some packages with +% older code where this is box is known as 255) may work but they are +% conceptually wrong and may result in errors under certain +% circumstances. +% +% During the execution of \hook{shipout/before} this box contains +% the accumulated material for the page, but not yet any material +% added by other shipout hooks. +% During execution of \hook{shipout/after}, i.e., after the shipout +% has happened, the box also contains any background or foreground +% material. +% +% Material from the hooks \hook{shipout/firstpage} or +% \hook{shipout/lastpage} is not included (but only used during the +% actual shipout) to facilitate reuse of the box data (e.g., +% \hook{shipout/firstpage} material should never be added to a +% later page of the output). % \end{variable} % % @@ -133,11 +182,11 @@ % % \subsection{Provided hooks} % -% \begin{variable}{shipout/before, +% \begin{variable}{shipout/before,shipout/after, % shipout/foreground,shipout/background, % shipout/firstpage, % shipout/lastpage} -% The code offers a number of hooks into which packages (or the +% The code for \cs{shipout} offers a number of hooks into which packages (or the % user) can add code to support different use cases. % These are: % \begin{description} @@ -148,6 +197,20 @@ % It can be used to alter that box content or to discard it % completely (see \cs{DiscardShipoutBox} below). % +% You can use \cs{RawShipout} inside this hook for special use +% cases. It can make use of \cs{ShipoutBox} (which doesn't yet +% include the background and foreground material). +% +% \textbf{Note:} It is not possible (or say advisable) to try +% and use this hook to typeset material with the intention to +% return it to main vertical list, it will go wrong and give +% unexpected results in many cases---for starters it will appear +% after the current page not before or it will vanish or the +% vertical spacing will be wrong! +% \end{description} +% \end{variable} +% +% \begin{description} % \item[\hook{shipout/background}] % % This hook adds a picture environment into the background of @@ -186,15 +249,22 @@ % not discarded at the last minute). It should only contain % \cs{special} or similar commands needed to direct post processors % handling the \texttt{.dvi} or \texttt{.pdf} output.\footnotemark +% \footnotetext{In +% \LaTeXe{} that was already existing, but implemented using a box +% register with the name \cs{@begindvibox}.} % % ^^A \fmi{not sure it has to be that restrictive.} % +% This hook is added to the very first page regardless of how it +% is shipped out (i.e., with \cs{shipout} or \cs{RawShipout}). % % \item[\hook{shipout/lastpage}] % % The corresponding hook to add \cs{special}s at the very end of -% the output file. It is only executed on the very last page --- +% the output file. It is only executed on the very last page of +% the output file --- % or rather on the page that \LaTeX{} believes is the last one. +% Again it is executed regardless of the shipout method. % % It may not be possible for \LaTeX{} to correctly determine % which page is the last one without several reruns. If this @@ -202,17 +272,32 @@ % extra page to place the material and also request a rerun to % get the correct placement sorted out. % +% \item[\hook{shipout/after}] +% +% This hook is executed after a shipout has happened. If the +% shipout box is discarded this hook is not looked at. +% +% You can use \cs{RawShipout} inside this hook for special use +% cases and the main \cs{ShipoutBox} is still available at this +% point (but in contrast to \hook{shipout/before} it now +% includes the background and foreground material). +% +% \textbf{Note:} Just like \hook{shipout/before} this hook is +% not meant to be used for adding adding typeset material back +% to the main vertical list---it might vanish or the +% vertical spacing will be wrong! +% +% % \end{description} -% \end{variable}\footnotetext{In -% \LaTeXe{} that was already existing, but implemented using a box -% register with the name \cs{@begindvibox}.} % % As mentioned above the hook \hook{shipout/before} is executed % first and can manipulate the prepared shipout box stored in % \cs{ShipoutBox} or set things up for use in \cs{write} during the -% actual shipout. The other hooks are added inside hboxes to the -% box being shipped out in the following -% order: +% 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 +% hboxes to the box being shipped out in the following order: % \begin{center} % \begin{tabular}{ll} % \hook{shipout/firstpage} & only on the first page \\ @@ -225,32 +310,50 @@ % If any of the hooks has no code then that particular no box is % added at that point. % +% 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. +% % In a document that doesn't produce pages, e.g., only makes -% \cs{typeout}s, none of the hooks are executed (as there is no +% \cs{typeout}s, none of the hooks are ever executed (as there is no % \cs{shipout}) not even the \hook{shipout/lastpage} hook. % +% If \cs{RawShipout} is used instead of \cs{shipout} then only the +% hooks \hook{shipout/firstpage} and \hook{shipout/lastpage} are +% executed (on the first or last page), all others are bypassed. +% +% +% +% \subsection{Legacy \LaTeX{} commands} +% % \begin{function}{\AtBeginDvi,\AtEndDvi} % \cs{AtBeginDvi} is the existing \LaTeXe{} interface to fill the % \hook{shipout/firstpage} hook. This is not really a good name % as it is not just supporting \texttt{.dvi} but also \texttt{.pdf} -% output or \texttt{.dvx}. +% output or \texttt{.xdv}. % % \cs{AtEndDvi} is the counterpart that was not available in the % kernel but only through the package \pkg{atenddvi}. It fills the % \hook{shipout/lastpage} hook. +% \end{function} % -% \fmi{better names? Any suggestions?} +% As these two wrappers have been available for a long time we +% continue offering them. However, for new code we suggest using +% the high-level hook management commands directly instead of +% ``randomly-named'' wrappers. This will lead to code that is +% easier to understand and to maintain. For this reason we do not +% provide any other wrapper commands for the above hooks in the +% kernel. % -% \end{function} % % \subsection{Special commands for use inside the hooks} % -% \begin{function}{\DiscardShipoutBox,\shipout_discard_box:} +% \begin{function}{\DiscardShipoutBox,\shipout_discard:} % \begin{syntax} % \cs{AddToHookNext} \texttt{\{shipout/before\} \{...\cs{DiscardShipoutBox}...\}} % \end{syntax} % The \cs{DiscardShipoutBox} declaration (L3 name -% \cs{shipout_discard_box:}) +% \cs{shipout_discard:}) % requests that on the next % shipout the page box is thrown away instead of being shipped to % the \texttt{.dvi} or \texttt{.pdf} file. @@ -261,6 +364,8 @@ % Note that if this declaration is used directly in the document it % may depend on the placement to which page it applies, given that % \LaTeX{} output routine is called in an asynchronous manner! +% Thus normally one would use this only as part of the +% \hook{shipout/before} code. % % \fmi{Once we have a new mark mechanism available we can improve % on that and make sure that the declaration applies to the page @@ -279,12 +384,28 @@ % names as given below. % % +% +% \subsection{Provided Lua\TeX\ callbacks} +% +% \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. +% The signature is +% \begin{verbatim} +% function( head) +% return true +% end +% \end{verbatim} +% The \texttt{head} is the list node corresponding to the box to be shipped out. +% The return value should always be \texttt{true}. +% \end{variable} +% % \subsection{Information counters} % % % \begin{variable}{\ReadonlyShipoutCounter,\g_shipout_readonly_int} % \begin{syntax} -% \cs{ifnum}\cs{ReadOnlyShipoutCounter}\texttt{=...} +% \cs{ifnum}\cs{ReadonlyShipoutCounter}\texttt{=...} % \cs{int_use:N} \cs{g_shipout_readonly_int} \texttt{\% expl3 usage} % \end{syntax} % This integer holds the number of pages shipped out up to now @@ -292,6 +413,7 @@ % routine). More precisely, it is incremented only after it is % clear that a page will be shipped out, i.e., after the % \hook{shipout/before} hook (because that might discard the page)! +% In contrast \hook{shipout/after} sees the incremented value. % % Just like with the \texttt{page} counter its value is % only accurate within the output routine. In the body of the @@ -299,10 +421,11 @@ % asynchronously! % % Also important: it \emph{must not} be set, only read. There are -% no provisions to prevent that but if you do, chaos will be the -% result. To emphasize this fact it is not provided as a \LaTeX{} -% counter but as a \TeX{} counter (i.e., a command), so -% \cs{Alph}\Arg{\cs{ReadonlyShipoutCounter}} etc, would not work. +% no provisions to prevent that restriction, but if you manipulate +% it, chaos will be the result. To emphasize this fact it is not +% provided as a \LaTeX{} counter but as a \TeX{} counter (i.e., a +% command), so \cs{Alph}\verb={=\cs{ReadonlyShipoutCounter}\verb=}= +% etc, would not work. % \end{variable} % % \begin{variable}{totalpages,\g_shipout_totalpages_int} @@ -314,7 +437,8 @@ % \texttt{totalpages} counter is a \LaTeX{} counter and incremented % for each shipout attempt including those pages that are discarded % for one or the other reason. Again \hook{shipout/before} sees -% the counter before it is incremented). +% the counter before it is incremented. In contrast +% \hook{shipout/after} sees the incremented value. % % Furthermore, while it is incremented for each page, its value is % never used by \LaTeX. It can therefore be freely reset or changed by user @@ -331,9 +455,9 @@ % \cs{thetotalpages}/\cs{PreviousTotalPages} % \end{syntax} % Command that expands to the number of total pages from the -% previous run. If there was no previous run or if usedin the +% previous run. If there was no previous run or if used in the % preamble it expands to -% \texttt{0}. Note that this is a command to a counter, so in order +% \texttt{0}. Note that this is a command and not a counter, so in order % to display the number in, say, Roman numerals you have to assign % its value to a counter and then use \cs{Roman} on that counter. % \end{variable} @@ -356,9 +480,15 @@ % % \section{Emulating commands from other packages} % -% The packages in this section are no longer necessary but as they -% are used in other packages they are emulated when they are loaded -% via \cs{usepackage} or \cs{RequirePackage}. +% The packages in this section are no longer necessary, but as they +% are used by other packages, they are emulated when they are +% explicitly loaded with \cs{usepackage} or \cs{RequirePackage}. +% +% Please note that the emulation only happens if the package is +% explicitly requested, i.e., the commands documented below are not +% automatically available in the \LaTeX{} kernel! If you write a +% new package we suggest to use the appropriate kernel hooks +% directly instead of loading the emulation. % % % \subsection{Emulating \pkg{atbegshi}} @@ -410,6 +540,21 @@ % This is the name of the shipout box as \pkg{atbegshi} knows it. % \end{function} % +% +% \begin{function}{\AtBeginShipoutOriginalShipout} +% This is the name of the \cs{shipout} primitive as \pkg{atbegshi} +% knows it. This bypasses all the mechanisms set up by the \LaTeX{} +% kernel and there are various scenarios in which it can therefore +% fail. It should only be used to run existing legacy +% \pkg{atbegshi} code but not in newly developed applications. +% +% The kernel alternative is \cs{RawShipout} which is integrated +% with the \LaTeX{} mechanisms and updates, for example, the +% \cs{ReadonlyShipoutCounter} counter. Please use \cs{RawShipout} +% for new code if you want to bypass the before, foreground and +% background hooks. +% \end{function} +% % \begin{function}{\AtBeginShipoutInit} % By default \pkg{atbegshi} delayed its action until % \verb=\begin{document}=. This command was forcing it in an earlier @@ -434,6 +579,13 @@ % % \subsection{Emulating \pkg{everyshi}} % +% The \pkg{everyshi} package is providing commands to run arbitrary +% code just before the shipout starts. +% One point of difference: in the new shipout hooks the page is +% available as \cs{ShipoutBox} for inspection of change, one should +% not manipulate box 255 directly inside \hook{shipout/before}, so +% old code doing this would change to use \cs{ShipoutBox} instead +% of \texttt{255} or \cs{@cclv}. % % \begin{function}{\EveryShipout} % \begin{syntax} @@ -447,22 +599,49 @@ % \end{syntax} % \end{function} % +% However, most use cases for \pkg{everyshi} are attempts to put +% some picture or text into the background or foreground of the page +% and that can be done today simply by using the +% \hook{shipout/background} and +% \hook{shipout/foreground} hooks without any need to coding. % % % \subsection{Emulating \pkg{atenddvi}} % -% The \pkg{atenddvi} package implemented only a single command: -% \cs{AtEndDvi} and that is now available out of the box. +% The \pkg{atenddvi} package implemented only a single command: +% \cs{AtEndDvi} and that is now available out of the box so the +% emulation makes the package a no-op. % % % % \subsection{Emulating \pkg{everypage}} % -% This page takes over the original \cs{@begindvi} hook and replaces -% it. It should be all covered by the hooks offered here (details -% need checking) and thus could simply use the provided hooks -% rather than defining its own. +% This package patched the original \cs{@begindvi} hook and replaced +% it with its own version. +% Its functionality is now covered by the hooks offered by the +% kernel so that there is no need for such patching any longer. +% +% \begin{function}{\AddEverypageHook} +% \begin{syntax} +% \cs{AddEverypageHook}\Arg{code} $\equiv$ +% \qquad\cs{AddToHook}\texttt{\{shipout/background\}\{\cs{put}(1in,-1in)\Arg{code}\}} +% \end{syntax} +% \cs{AddEverypageHook} is adding something into the +% background of every page at a position of 1in to the right and +% 1in down from the top left corner of the page. +% By using the kernel hook directly you can put your material +% directly to the right place, i.e., use other coordinates in the +% \cs{put} statement above. +% \end{function} % +% \begin{function}{\AddThispageHook} +% \begin{syntax} +% \cs{AddThispageHook}\Arg{code} $\equiv$ +% \qquad\cs{AddToHookNext}\texttt{\{shipout/background\}\{\cs{put}(1in,-1in)\Arg{code}\}} +% \end{syntax} +% The \cs{AddThispageHook} wrapper is similar but uses +% \cs{AddToHookNext}. +% \end{function} % % % \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } @@ -479,7 +658,7 @@ % \begin{macrocode} %<*2ekernel|latexrelease> %\IncludeInRelease{2020/10/01}% -% {\shipout}{Hook mangement (shipout)}% +% {\shipout}{Hook management (shipout)}% % \end{macrocode} % % @@ -540,6 +719,41 @@ % \end{macro} % % +% \begin{macro}{\l_@@_raw_box} +% The \cs{RawShipout} gets its own box but it is internal as there +% is no hook manipulation for it. +% \begin{macrocode} +\box_new:N \l_@@_raw_box +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_finalize_box:} +% For Lua\TeX{} invoke the \texttt{pre\_shipout\_filter} callback. +% \changes{v1.0i}{2021/01/22}{Add \texttt{pre\_shipout\_filter} Lua callback} +% \begin{macrocode} +\sys_if_engine_luatex:TF + { + \newluafunction \@@_finalize_box: + \exp_args:Nx \everyjob { + \exp_not:V \everyjob + \exp_not:N \lua_now:n { + luatexbase.create_callback('pre_shipout_filter', 'list') + local~call, getbox, setbox = luatexbase.call_callback, tex.getbox, tex.setbox~ + lua.get_functions_table()[\the \@@_finalize_box:] = function() + local~result = call('pre_shipout_filter', getbox(\the \l_shipout_box)) + if~not (result == true) then~ + setbox(\the \l_shipout_box, result~or~nil) + end~ + end + } + } + \protected \luadef \@@_finalize_box: \the \@@_finalize_box: + } { + \cs_set_eq:NN \@@_finalize_box: \scan_stop: + } +% \end{macrocode} +% \end{macro} % % % \begin{macro}{\@@_execute:} @@ -567,7 +781,8 @@ % % \begin{macro}{\l_@@_group_level_tl} % Helper token list to record the group level at which -% \cs{@@_execute:} is encountered. \begin{macrocode} +% \cs{@@_execute:} is encountered. +% \begin{macrocode} \tl_new:N \l_@@_group_level_tl % \end{macrocode} % \end{macro} @@ -581,28 +796,78 @@ \cs_new:Npn \@@_execute_test_level: { \int_compare:nNnT \l_@@_group_level_tl < \tex_currentgrouplevel:D - \tex_aftergroup:D - \@@_execute_cont: + \tex_aftergroup:D \@@_execute_cont: } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_execute_cont:} +% This does the actual shipout running several hooks as part of it. +% The code for them is passed as argument \verb=#2= to \verb=#4= +% to \cs{@@_execute_main_cont:Nnnn}; the first argument is the box +% to be shipped out. +% \begin{macrocode} +\cs_new:Npn \@@_execute_cont: { + \@@_execute_main_cont:Nnnn + \l_shipout_box + { \hook_use:n {shipout/before} } + { \hook_if_empty:nF {shipout/foreground} + { \@@_add_foreground_picture:n + { \hook_use:n {shipout/foreground} } } +% \end{macrocode} +% If the user hook for the background (\hook{shipout/background}) has +% no code, there might still code in the kernel hook so we need to +% test for this too. +% We only test for the \cs{@kernel@before@shipout@background} +% though. If the \cs{@kernel@after@shipout@background} needs +% executing even if the user hook is empty then we can add another +% test (or the kernel could put something into the before hook). +% +% \changes{v1.0d}{2020/11/23}{Check for both kernel and user hook (gh/431)} +% \changes{v1.0f}{2021/01/08}{Added another kernel hook for more +% flexibility (cf \texttt{https://github.com/pgf-tikz/pgf/issues/960}} +% \begin{macrocode} + \bool_lazy_and:nnF + { \hook_if_empty_p:n {shipout/background} } + { \tl_if_empty_p:N \@kernel@before@shipout@background } + { \@@_add_background_picture:n + { \@kernel@before@shipout@background + \hook_use:n {shipout/background} + \@kernel@after@shipout@background } + } + } + { \hook_use:n {shipout/after} } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_execute_main_cont:Nnnn} % When we have reached this point the shipout box has been % processed and is available in \cs{l_shipout_box} and ready for -% real ship out (perhaps).. +% real ship out (unless it gets discarded during the process). +% +% The three arguments hold hook code that is executed just before the +% actual shipout (\verb=#1=), within the shipout adding +% background and foreground material (\verb=#2=) and after the +% shipout has happened (\verb=#3=). +% These are passed as arguments because the same code without those +% hooks is also used when doing a ``raw'' shipout implemented by +% \cs{RawShipout}. +% The only hook that is always executed is that for the very last +% page, i.e., \hook{shipout/lastpage}. % % First we quickly check if it is void (can't happen in the % standard \LaTeX{} output routine but \cs{shipout} might be called % from a package that has some special processing logic). If it is % void we aren't shipping anything out and processing ends.\footnote{In that -% case we don't reset the deadcyles, that would be up to the OR +% case we don't reset the deadcycles, that would be up to the OR % processing logic to do.} % \begin{macrocode} -\cs_new:Npn \@@_execute_cont: { - \box_if_empty:NTF \l_shipout_box - { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} } +\cs_new:Npn \@@_execute_main_cont:Nnnn #1#2#3#4 { + \box_if_empty:NTF #1 + { \@latex@warning{Ignoring~ void~ shipout~ box} } { % \end{macrocode} % Otherwise we assume that we will ship something and prepare for @@ -610,7 +875,8 @@ % \cs{protect} while we are running the hook code). % We also save the current \cs{protect} state to restore it later. % \begin{macrocode} - \bool_gset_false:N \g_@@_discard_bool +% \bool_gset_false:N \g_@@_discard_bool % setting this would disable + % \DiscardShipoutBox on doc-level \cs_set_eq:NN \@@_saved_protect: \protect \set@typeset@protect % \end{macrocode} @@ -619,11 +885,12 @@ % necessary as the code could access them via \cs{box_ht:N}, etc., % but it is perhaps convenient.} % \begin{macrocode} - \@@_get_box_size:N \l_shipout_box + \@@_get_box_size:N #1 % \end{macrocode} -% Then we execute the \hook{shipout/before} hook. +% Then we execute the \hook{shipout/before} hook (or nothing in +% case of \cs{RawShipout}). % \begin{macrocode} - \hook_use:n {shipout/before} + #2 % \end{macrocode} % In \cs{g_shipout_totalpages_int} we count all shipout attempts so % we increment that counter already here (the other one is @@ -631,7 +898,8 @@ % \cs{shipout}. % % We increment it after running the above hook so that the values -% for \cs{g_shipout_totalpages_int} and \cs{} are in sync while the +% for \cs{g_shipout_totalpages_int} and \cs{g_shipout_readonly_int} +% are in sync while the % hook is executed (in the case that totalpages isn't manually % altered or through discarding pages that is). % \begin{macrocode} @@ -641,7 +909,7 @@ % we now test for it. % \begin{macrocode} \bool_if:NTF \g_@@_discard_bool - { \PackageInfo{ltshipout}{Completed~ page~ discarded} + { \@latex@info@no@line{Completed~ page~ discarded} \bool_gset_false:N \g_@@_discard_bool % \end{macrocode} % As we are discarding the page box and not shipping anything out, @@ -655,7 +923,7 @@ % needed? Or the resetting of \cs{protect} to its kernel value?} % \begin{macrocode} % \group_begin: -% \box_set_eq_drop:NN \l_shipout_box \l_shipout_box +% \box_set_eq_drop:NN #1 #1 % \group_end: % \cs_set_eq:NN \protect \exp_not:N } @@ -666,8 +934,8 @@ % once more but this time make it a warning, because the best % practice way is to use the request mechanism. % \begin{macrocode} - { \box_if_empty:NTF \l_shipout_box - { \PackageWarning{ltshipout}{ + { \box_if_empty:NTF #1 + { \@latex@warning{ Shipout~ box~ was~ voided~ by~ hook,\MessageBreak ignoring~ shipout~ box } } @@ -691,39 +959,54 @@ % changed) and then look at the hooks \hook{shipout/foreground} % and \hook{shipout/background}. If either or both are non-empty % we add a \texttt{picture} environment to the box (in the -% foreground and or in the background) and execute the hook code +% foreground and/or in the background) and execute the hook code % inside that environment. % % \begin{macrocode} - \@@_get_box_size:N \l_shipout_box - \hook_if_empty:nF {shipout/foreground} - { \@@_add_foreground_picture:n - { \hook_use:n {shipout/foreground} } } - \hook_if_empty:nF {shipout/background} - { \@@_add_background_picture:n - { \@kernel@before@shipout@background - \hook_use:n {shipout/background} } } + \@@_get_box_size:N #1 +% \end{macrocode} +% The first hook we run is the \hook{shipout/firstpage} hook. This +% is only done once, then the \cs{@@_run_firstpage_hook:} +% command redefines itself to do nothing. If the hook contains +% \cs{special}s for integration at the top of the page they will be +% temporarily stored in a safe place and added later with +% \cs{@@_add_firstpage_specials:}. +% \begin{macrocode} + \@@_run_firstpage_hook: +% \end{macrocode} +% Run the hooks for background and foreground or, if this +% is called by \cs{RawShipout}, copy the box \cs{l_@@_raw_box} to +% \cs{l_shipout_box} so that firstpage and lastpage material gets +% added if necessary (that is always done to \cs{l_shipout_box}. +% \begin{macrocode} + #3 % \end{macrocode} -% We then run \cs{@@_execute_firstpage_hook:} that adds +% We then run \cs{@@_add_firstpage_specials:} that adds % the content of the hook \hook{shipout/firstpage} to the % start of the first page (if non-empty). It is then redefined to % do nothing on later pages. % \begin{macrocode} - \@@_execute_firstpage_hook: + \@@_add_firstpage_specials: % \end{macrocode} -% The we check if we have to add the \hook{shipout/lastpage} hook +% Then we check if we have to add the \hook{shipout/lastpage} hook +% or the corresponding kernel hook % because we have reached the last page. This test will be false for % all but one (and hopefully the correct) page. +% \changes{v1.0d}{2020/11/23}{Check for both kernel and user hook (gh/431)} % \begin{macrocode} \int_compare:nNnT \@abspage@last = \g_shipout_readonly_int - { \hook_if_empty:nF {shipout/lastpage} + { \bool_lazy_and:nnF + { \hook_if_empty_p:n {shipout/lastpage} } + { \tl_if_empty_p:N \@kernel@after@shipout@lastpage } { \@@_debug:n { \typeout{Executing~ lastpage~ hook~ - on~ page~ \int_use:N \g_shipout_readonly_int } } - \_@@_add_foreground_box:n { \UseHook{shipout/lastpage} - \@kernel@after@shipout@lastpage } + on~ page~ \int_use:N \g_shipout_readonly_int } } + \_@@_add_foreground_box:n + { \UseHook{shipout/lastpage} + \@kernel@after@shipout@lastpage } } \bool_gset_true:N \g_@@_lastpage_handled_bool } + \@@_finalize_box: % \end{macrocode} % Finally we run the actual \TeX{} primitive for shipout. As that will % expand delayed \cs{write} statements inside the page in which @@ -732,6 +1015,21 @@ % \begin{macrocode} \cs_set_eq:NN \protect \exp_not:N \tex_shipout:D \box_use:N \l_shipout_box +% \end{macrocode} +% The \cs{l_shipout_box} may contain the firstpage material if this +% was the very first shipout. That makes it unsuitable for reuse in +% another shipout, so as a safety measure the next command resets +% \cs{l_shipout_box} to its earlier state if that is necessary. On +% later pages this is then a no-op. +% \begin{macrocode} + \@@_drop_firstpage_specials: +% \end{macrocode} +% The \hook{shipout/after} hook (if in \verb=#4=) needs to run with +% \cs{protect}ed commands again being executed, because that hook +% will ``typeset'' material added at the top of the next page. +% \begin{macrocode} + \set@typeset@protect + #4 } } % \end{macrocode} @@ -746,20 +1044,69 @@ % \end{macro} % % +% +% +% \begin{macro}{\@@_execute_raw:, +% \@@_execute_test_level_raw:} +% +% This implements the ``raw'' shipout which bypasses the before, +% foreground, background and after hooks. It follows the same pattern than +% \cs{_@@_execute_raw:} except that it finally calls +% \cs{_@@_execute_main_cont:Nnnn} with three empty arguments. +% instead of the hook code. +% \begin{macrocode} +\cs_set_protected:Npn \@@_execute_raw: { + \tl_set:Nx \l_@@_group_level_tl + { \int_value:w \tex_currentgrouplevel:D } + \tex_afterassignment:D \@@_execute_test_level_raw: + \tex_setbox:D \l_@@_raw_box +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_execute_test_level_raw: { + \int_compare:nNnT + \l_@@_group_level_tl < \tex_currentgrouplevel:D + \tex_aftergroup:D \@@_execute_nohooks_cont: +} +% \end{macrocode} +% Well, not totally empty arguments, we add some debugging if we +% are actually doing a shipout. +% \begin{macrocode} +\cs_new:Npn \@@_execute_nohooks_cont: { + \@@_execute_main_cont:Nnnn \l_@@_raw_box + {} { \@@_debug:n{ \typeout{Doing~ raw~ shipout~ ...} } + \box_set_eq:NN \l_shipout_box \l_@@_raw_box } {} +} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\RawShipout} +% The interface name for raw shipout. +% \changes{v1.0g}{2021/01/10}{Macro added} +% \begin{macrocode} +\cs_gset_eq:NN \RawShipout \@@_execute_raw: +% \end{macrocode} +% \end{macro} +% +% +% +% % \begin{macro}{\@@_saved_protect:} -% Remeber the current \cs{protect} state. +% Remember the current \cs{protect} state. % \begin{macrocode} \cs_new_eq:NN \@@_saved_protect: \protect % \end{macrocode} % \end{macro} % -% \begin{macro}{shipout/before, +% \begin{macro}{shipout/before,shipout/after, % shipout/foreground,shipout/background, % shipout/firstpage, % shipout/lastpage} % Declaring all hooks for the shipout code. % \begin{macrocode} \hook_new:n{shipout/before} +\hook_new:n{shipout/after} \hook_new:n{shipout/foreground} \hook_new:n{shipout/background} \hook_new:n{shipout/firstpage} @@ -770,36 +1117,71 @@ % % % \begin{macro}{\@kernel@after@shipout@lastpage, -% \@kernel@before@shipout@background} +% \@kernel@before@shipout@background, +% \@kernel@after@shipout@background} % And here are the internal kernel hooks going before or after the % public ones where needed. +% \changes{v1.0g}{2021/01/10}{Internal hook +% \cs{@kernel@after@shipout@background} added} % \begin{macrocode} \let\@kernel@after@shipout@lastpage\@empty \let\@kernel@before@shipout@background\@empty +\let\@kernel@after@shipout@background\@empty % \end{macrocode} % \end{macro} % % -% \begin{macro}{\@@_execute_firstpage_hook: } -% This command adds any specials into a box and adds that to the -% very beginning of the first box shipped out. After that we -% redefine it to do nothing on later pages. +% \begin{macro}{\@@_run_firstpage_hook:} +% +% \changes{v1.0h}{2021/01/19}{Handling of firstpage hook altered} +% +% There are three commands to handle the \hook{shipout/firstpage} +% hook: +% \cs{@@_run_firstpage_hook:}, \cs{@@_add_firstpage_specials:} and +% \cs{@@_drop_firstpage_specials:}. +% +% That hook is supposed to contain \cs{special}s and similar +% material to be placed at the very beginning of the output page +% and so it needs careful placing to avoid that anything else gets +% in front of it. And this means we have to wait with this until +% other hooks such as \hook{shipout/background} have added their +% bits. It is also important that such \cs{special}s show up only +% on the very first page, so if this page gets saved before +% \cs{shipout} for later reuse, we have to make sure that they +% aren't in the saved version. +% +% In addition the hook may also contain code to be executed ``first'', e.g., +% visible from code in \hook{shipout/background} and this conflicts +% with adding the \cs{special}s late. +% +% Therefore the processing is split into different parts: +% \cs{@@_run_firstpage_hook:} is done early and checks if there is +% any material in the hook. % \begin{macrocode} -\cs_new:Npn \@@_execute_firstpage_hook: { +\cs_new:Npn \@@_run_firstpage_hook: { + \hook_if_empty:nTF {shipout/firstpage} % \end{macrocode} -% Adding something to the beginning means adding it to the -% background as that layer is done first in the output. Of course -% that is only needed if the hook actually contains anything. +% If not then we define the other two commands to do nothing. % \begin{macrocode} - \hook_if_empty:nF {shipout/firstpage} - { \@@_add_background_box:n { \UseHook{shipout/firstpage} } } + { + \cs_gset_eq:NN \@@_add_firstpage_specials: \prg_do_nothing: + \cs_gset_eq:NN \@@_drop_firstpage_specials: \prg_do_nothing: + } +% \end{macrocode} +% If there is material we execute inside a box, which means any +% \cs{special} will end up in that box and any other code is +% executed and can have side effects (as long as they are global). +% \begin{macrocode} + { + \hbox_set:Nn \l_@@_firstpage_box { \UseHook{shipout/firstpage} } + } % \end{macrocode} % Once we are here we change the definition to do nothing next time % and we also change the command used to implement \cs{AtBeginDvi} -% to become a warning and not add further material to a hook that +% to become a warning and not add further material to a hook that % is never used again. % \begin{macrocode} - \cs_gset_eq:NN \@@_execute_firstpage_hook: \prg_do_nothing: + \cs_gset_eq:NN \@@_run_firstpage_hook: \prg_do_nothing: \cs_gset:Npn \@@_add_firstpage_material:Nn ##1 ##2 { \@latex@warning{ First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak @@ -807,8 +1189,67 @@ } } % \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_add_firstpage_specials:,\@@_drop_firstpage_specials:} +% The \cs{@@_add_firstpage_specials:} then adds the \cs{special}s +% stored in \cs{l_@@_firstpage_box} to the page to be shipped out +% when the time is ready. Note that if there was no material in the +% \hook{shipout/firstpage} hook then this command gets redefined to +% do nothing. But for most documents there is something, e.g., some +% PostScript header, or some meta data declaration, etc.\ so by +% default we assume there is something to do. +% \begin{macrocode} +\cs_new:Npn \@@_add_firstpage_specials: { +% \end{macrocode} +% First we make a copy of the \cs{l_shipout_box} that we can +% restore it later on. +% \begin{macrocode} + \box_set_eq:NN \l_@@_raw_box \l_shipout_box +% \end{macrocode} +% Adding something to the beginning means adding it to the +% background as that layer is done first in the output. +% \begin{macrocode} + \@@_add_background_box:n { \hbox_unpack_drop:N \l_@@_firstpage_box } +% \end{macrocode} +% After the actual shipout \cs{@@_drop_firstpage_specials:} is +% run to +% restore the earlier content of \cs{l_shipout_box} and then +% redefines itself again to do nothing. +% +% As a final act we change the definition to do nothing next time. +% \begin{macrocode} + \cs_gset_eq:NN \@@_add_firstpage_specials: \prg_do_nothing: +} +% \end{macrocode} +% +% The \cs{@@_drop_firstpage_specials:} is run after the shipout has +% occurred but before the \hook{shipout/afterpage} hook is executed. +% That is the point where we have to restore the \cs{ShipoutBox} to +% its state without the \hook{shipout/firstpage} material. +% \begin{macrocode} +\cs_new:Npn \@@_drop_firstpage_specials: { + \box_set_eq:NN \l_shipout_box \l_@@_raw_box +% \end{macrocode} +% If there was no such material then \cs{@@_run_firstpage_hook:} +% will have changed the definition to a no-op already. Otherwise +% this is what we do here. +% \begin{macrocode} + \cs_gset_eq:NN \@@_drop_firstpage_specials: \prg_do_nothing: + } +% \end{macrocode} % \end{macro} % + +% \begin{macro}{\l_@@_firstpage_box} +% The box to hold any firstpage \cs{special}s. +% \begin{macrocode} +\box_new:N \l_@@_firstpage_box +% \end{macrocode} +% \end{macro} + % % \begin{macro}{\g_@@_lastpage_handled_bool} % A boolean to signal if we have already handled the @@ -849,8 +1290,8 @@ \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 } \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 } \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 } - \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim + - \l_shipout_box_dp_dim } + \dim_set:Nn \l_shipout_box_ht_plus_dp_dim + { \l_shipout_box_ht_dim + \l_shipout_box_dp_dim } } % \end{macrocode} % \end{macro} @@ -883,7 +1324,7 @@ % \begin{macro}{\l_@@_tmp_box,\l_@@_saved_badness_tl} % We need a box for the background and foreground material and a % token register to remember badness settings as we disable them -% during te buildup below. +% during the buildup below. % \begin{macrocode} \box_new:N \l_@@_tmp_box \tl_new:N \l_@@_saved_badness_tl @@ -1088,7 +1529,7 @@ % \begin{macrocode} \cs_new:Npn \@@_picture_overlay:n #1 { % \end{macrocode} -% The very first time this is executed we have to initializes (and +% The very first time this is executed we have to initialize (and % freeze) the origins. % \begin{macrocode} \@@_init_page_origins: @@ -1183,7 +1624,7 @@ % % \begin{macro}{\g_shipout_totalpages_int,\c@totalpages} % We count every shipout attempt (even those that are discarded) in -% tis counter. It is not used in the code but may get used in user +% this counter. It is not used in the code but may get used in user % code. % \begin{macrocode} \int_new:N \g_shipout_totalpages_int @@ -1207,7 +1648,7 @@ % or the statement is missing from it we initialize it with the % largest possible number in \TeX{}. We use this as the default % because then we are inserting the \hook{shipout/lastpage} on -% the last page (or after the last page but not on page 1 for a +% the last page (or after the last page) but not on page 1 for a % multipage document. % \begin{macrocode} \xdef\@abspage@last{\number\maxdimen} @@ -1219,11 +1660,11 @@ % % Instead of using the hooks \hook{enddocument} and % \hook{enddocument/afterlastpage} we add this code to private -% kernel hooks to be 100\% when it is executed and to avoid +% kernel hooks to be 100\% sure when it is executed and to avoid % cluttering the hooks with data that is always there. % % Inside \cs{enddocument} there is a \cs{clearpage}. Just before -% that we execute this code here. There is a good change that we +% that we execute this code here. There is a good chance that we % are on the last page. Therefore, if we don't know the value from % the last run, we assume that the current page is the right % one. So we set \cs{@abspage@last} and as a result the next @@ -1307,7 +1748,7 @@ % At this point we also signal to \LaTeX{}'s endgame that a rerun is % necessary so that an appropriate message can be shown on the % terminal. We do this by simply defining a command used as a flag and -% tested \cs{enddocument}. +% tested in \cs{enddocument}. % \begin{macrocode} \cs_gset_eq:NN \@extra@page@added \relax } @@ -1380,7 +1821,8 @@ % defined so we better not use \cs{cs_new_protected:Npn} here. % \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)} % \begin{macrocode} -\cs_set_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi} +\cs_set_protected:Npn \AtBeginDvi + {\@@_add_firstpage_material:Nn \AtBeginDvi} % \end{macrocode} % \end{macro} % @@ -1409,6 +1851,7 @@ % \@expl@@@shipout@add@foreground@picture@@n} % Some internals needed elsewhere. % +% \InternalDetectionOff % \begin{macrocode} \cs_set_eq:NN \@expl@@@shipout@add@firstpage@material@@Nn \__shipout_add_firstpage_material:Nn @@ -1433,6 +1876,7 @@ \cs_set_eq:NN \@expl@@@shipout@add@foreground@picture@@n \__shipout_add_foreground_picture:n % \end{macrocode} +% \InternalDetectionOn % \end{macro} % % \begin{macrocode} @@ -1449,7 +1893,7 @@ % % \begin{macrocode} %\IncludeInRelease{0000/00/00}% -% {\shipout}{The hook management (shipout)}% +% {\shipout}{Hook management (shipout)}% % % \end{macrocode} % If we roll forward then \cs{tex\_shipout:D} may not be defined in @@ -1462,6 +1906,7 @@ % \csname tex_shipout:D\endcsname %\fi % +%\let \RawShipout\@undefined %\let \ShipoutBox\@undefined %\let \ReadonlyShipoutCounter \@undefined %\let \c@totalpages \@undefined @@ -1485,23 +1930,13 @@ %\let \ShipoutBoxDepth \@undefined %\let \ShipoutBoxWidth \@undefined % -%\let \AtBeginShipoutDiscard \@undefined -% -%\let \AtBeginShipoutAddToBox \@undefined -%\let \AtBeginShipoutAddToBoxForeground \@undefined -%\let \AtBeginShipoutUpperLeft \@undefined -%\let \AtBeginShipoutUpperLeftForeground \@undefined -% % \end{macrocode} % We do not undo a substitution when rolling back. As the file % support gets undone the underlying data is no longer used (and -% sufficiently obscure that should not interfer with existing +% sufficiently obscure that it should not interfere with existing % commands) and properly removing it would mean we need to make the -% \cs{unclare@...} and its support macros available in all earlier +% \cs{undeclare@...} and its support macros available in all earlier % kernel releases which is pointless (and actually worse). -% \begin{macrocode} -%\undeclare@file@substitution{everyshi.sty} -% \end{macrocode} % % \begin{macrocode} % @@ -1509,7 +1944,7 @@ % \end{macrocode} % We do not reenable a disabled package load when rolling back. As the file % support gets undone the underlying data is no longer checked (and -% sufficiently obscure that it should not interfer with existing +% sufficiently obscure that it should not interfere with existing % commands) and properly removing it would mean we need to make the % \cs{reenable@package@load} command available in all earlier % kernel releases which is pointless (and actually worse). @@ -1585,8 +2020,8 @@ % \begin{macrocode} %<*atbegshi-ltx> \ProvidesPackage{atbegshi-ltx} - [2020/08/17 v1.0a - Emulation of the original atbegshi package^^Jwith kernel methods] + [2021/01/10 v1.0c + Emulation of the original atbegshi^^Jpackage with kernel methods] % \end{macrocode} % % @@ -1597,6 +2032,7 @@ % \end{macro} % % +% % \begin{macro}{\AtBeginShipoutInit} % Compatibility only, we aren't delaying \ldots % \begin{macrocode} @@ -1650,15 +2086,27 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\AtBeginShipoutOriginalShipout} +% This offers the raw \cs{shipout} primitive of the engine. A page +% shipped out with this is not counted by +% \cs{ReadonlyShipoutCounter} counter and thus the mechanism to +% place \cs{special}s at the very end of the output might fail, +% etc. It should therefore not be used in new applications but is +% only provided to allow running legacy code. For new code use the +% commands provided by the kernel instead. +% \begin{macrocode} +\ExplSyntaxOn +\cs_new_eq:NN \AtBeginShipoutOriginalShipout \tex_shipout:D +% \end{macrocode} +% \end{macro} % % -% \begin{macro}{\ShipoutBoxHeight,\ShipoutBoxWidth,\ShipoutoBoxDepth} +% \begin{macro}{\ShipoutBoxHeight,\ShipoutBoxWidth,\ShipoutBoxDepth} % This is somewhat different from the original in \pkg{atbegshi} % where \cs{ShipoutBoxHeight} etc.\ only holds the % \verb=\the\ht= value. This may has some implications in some % use cases and if that is a problem then it might need changing. % \begin{macrocode} -\ExplSyntaxOn \cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim } \cs_new:Npn \ShipoutBoxDepth { \dim_use:N \l_shipout_box_dp_dim } \cs_new:Npn \ShipoutBoxWidth { \dim_use:N \l_shipout_box_wd_dim } @@ -1685,56 +2133,8 @@ % % \subsection{Package \pkg{everyshi} emulation} % -% \begin{macrocode} -%<*everyshi-ltx> -% \end{macrocode} -% -% \begin{macrocode} -\ProvidesPackage{everyshi-ltx} - [2020/08/17 v1.0a - Emulation of the original everyshi package^^Jwith kernel methods] -% \end{macrocode} -% -% \begin{macro}{\EveryShipout,\AtNextShipout} -% This package has only two public commands so simulating it is easy: -% \begin{macrocode} -\protected \def \EveryShipout {\AddToHook{shipout/before}} -\protected \def \AtNextShipout {\AddToHookNext{shipout/before}} -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -% This is one difference between \pkg{everyshi} and the kernel -% implementation, the latter does not directly use box 255. -% -% For usage by ordinary users this makes no difference but of a -% package use complicated code together with \pkg{everyshi} and -% directly manipulates box 255 then this package needs updating. -% In most cases the updates are simple because the kernel offers -% hooks that makes such complicated code unnecessary. -% -% We therefore add a little file into the adjusted package -% \begin{macrocode} -%% -%% In normal circumstances the above emulation is sufficient and in -%% all known packages (we know of) that use everyshi it either works or -%% the packages have been adjusted. -%% -%% Code that directly manipulates box 255, however, might fail. -%% If that is the case look at the shipout hooks offered now as -%% they are normally sufficienct to avoid such minpulations (or -%% replace box 255 with \ShipoutBox in the code. -%% -% -% \end{macrocode} -% -% -% If the package is requested we substitute the one above: -% \begin{macrocode} -%<*2ekernel> -\declare@file@substitution{everyshi.sty}{everyshi-ltx.sty} -% -% \end{macrocode} +% This is now directly handled in that package so emulation is not +% necessary any more. % % % Rather important :-) diff --git a/Master/texmf-dist/source/latex/base/ltspace.dtx b/Master/texmf-dist/source/latex/base/ltspace.dtx index 1a672c6455d..17fb0d65185 100644 --- a/Master/texmf-dist/source/latex/base/ltspace.dtx +++ b/Master/texmf-dist/source/latex/base/ltspace.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/lttab.dtx b/Master/texmf-dist/source/latex/base/lttab.dtx index dedd9e5d375..48627f40a3c 100644 --- a/Master/texmf-dist/source/latex/base/lttab.dtx +++ b/Master/texmf-dist/source/latex/base/lttab.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -31,7 +31,7 @@ %%% From File: lttab.dtx %<*driver> % \fi -\ProvidesFile{lttab.dtx}[2020/04/24 v1.1r LaTeX Kernel (Columns)] +\ProvidesFile{lttab.dtx}[2021/04/20 v1.1s LaTeX Kernel (Columns)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{lttab.dtx} @@ -464,7 +464,7 @@ % % \begin{macro}{\@tabcr} % \begin{macrocode} -\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr} +\protected\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr} % \end{macrocode} % \end{macro} % @@ -964,8 +964,9 @@ % % \begin{macro}{\@arraycr} % Array version of |\\|. +% \changes{v1.1s}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macrocode} -\def\@arraycr{% +\protected\def\@arraycr{% ${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr} % \end{macrocode} % \end{macro} @@ -994,8 +995,9 @@ % \end{macro} % % \begin{macro}{\@tabularcr} +% \changes{v1.1s}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macrocode} -\def\@tabularcr{% +\protected\def\@tabularcr{% {\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr} % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/base/lttextcomp.dtx b/Master/texmf-dist/source/latex/base/lttextcomp.dtx index 3b6231dafdf..1efc36d5637 100644 --- a/Master/texmf-dist/source/latex/base/lttextcomp.dtx +++ b/Master/texmf-dist/source/latex/base/lttextcomp.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 2019-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -26,6 +26,9 @@ % extension .ins) which are part of the distribution. % % \fi +% +%%% From File: lttextcomp.dtx +% % \iffalse % %<*driver> @@ -33,7 +36,7 @@ % % \ProvidesFile{lttextcomp.dtx} - [2020/04/29 v1.0d LaTeX Kernel (text companion symbols)] + [2021/04/16 v1.0f LaTeX Kernel (text companion symbols)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -46,7 +49,7 @@ % % % \GetFileInfo{lttextcomp.dtx} -% \title{Providing addtional text symbols\\ +% \title{Providing additional text symbols\\ % (previously available through the \texttt{textcomp} package)\thanks % {This file has version number % \fileversion\ dated \filedate}} @@ -67,20 +70,23 @@ % % \StopEventually{} % +% \changes{v1.0e}{2021/03/19} +% {Use \cs{NewModuleRelease}} +% \begin{macrocode} +%<*2ekernel|latexrelease> +%\NewModuleRelease{2020/02/02}{lttextcomp} +% {Text Companion symbols} +% \end{macrocode} % % \begin{macro}{\oldstylenums} % \begin{macro}{\legacyoldstylenums} % -% % Preserve the old definition of \cs{oldstylenums} under a different name. % % This macro implements old style numerals but only works if we % assume that the standard math fonts are used. Thus it needs % changing in case other math encodings are used. % \begin{macrocode} -%<*2ekernel|latexrelease> -%\IncludeInRelease{2020/02/02}% -% {\oldstylenums}{Old style numerals}% \DeclareRobustCommand\legacyoldstylenums[1]{% \begingroup % \end{macrocode} @@ -112,7 +118,7 @@ \mathgroup\symletters #1% \else % \end{macrocode} -% The \cs{CheckEncodingSubset} is discused below. +% The \cs{CheckEncodingSubset} is discussed below. % \begin{macrocode} \CheckEncodingSubset\@use@text@encoding{TS1}\tc@oldstylesubst2{{#1}}% \fi @@ -154,44 +160,6 @@ % \end{macrocode} % \end{macro} % -% -% \begin{macrocode} -% -%\EndIncludeInRelease -%\IncludeInRelease{0000/00/00}% -% {\oldstylenums}{Old style numerals}% -% -%\DeclareRobustCommand\oldstylenums[1]{% -% \begingroup -% \spaceskip\fontdimen\tw@\font -% \usefont{OML}{\rmdefault}{\f@series}{it}% -% \mathgroup\symletters #1% -% \endgroup -%} -%\let\legacyoldstylenums\@undefined -%\def\textcompsubstdefault{cmr} -% -%\EndIncludeInRelease -% \end{macrocode} -% -% - - - - - -% Everything else in the this file got introduced 2020/02/02, so we do a -% single rollback (for now). -% \begin{macrocode} -%<*2ekernel> -% -%<*2ekernel|latexrelease> -%\IncludeInRelease{2020/02/02}% -% {\DeclareEncodingSubset}{Text companion symbols}% -% \end{macrocode} -% -% -% % \begin{macro}{\DeclareEncodingSubset} % % The declaration takes 3 mandatory arguments: an \emph{encoding} @@ -200,7 +168,7 @@ % declare the subset and finally the \emph{subset} number (between \texttt{0} (all % of the encoding is supported) and \texttt{9} many glyphs are missing. % -% For \texttt{TS1} the numbers have been choosen in a way that most +% For \texttt{TS1} the numbers have been chosen in a way that most % fonts can be fairly correctly categorized, but the default % settings are always conservative, that is they may claim that % less glyphs are supported than there actually are. @@ -362,13 +330,14 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% +% % \begin{macro}{\tc@fake@euro} % |\tc@fake@euro| is an example of a ``fake'' definition to use in arg |#3| of -% |\CheckEncodingSubset| when a symbol is not available in a +% the command |\CheckEncodingSubset| when a symbol is not available in a % certain font family. Here we produce a poor man's Euro symbol by combining % a ``C'' with a ``=''. % \begin{macrocode} @@ -386,10 +355,10 @@ } % \end{macrocode} % \end{macro} - - - - +% +% +% +% % \begin{macro}{\tc@check@symbol} % \begin{macro}{\tc@check@accent} % These are two abbreviations that we use below to check symbols @@ -401,21 +370,22 @@ % to ensure that |\textcurrency| is only typeset if the current % font has a \texttt{TS1} subset id of less than 3. Otherwise % |\tc@error| is called telling the user that for this font family -% |\textcurreny| is not available. +% |\textcurrency| is not available. % \begin{macrocode} \def\tc@check@symbol{\CheckEncodingSubset\UseTextSymbol{TS1}\tc@subst} % \end{macrocode} % -% Accents and been mad an error in the \texttt{textcomp} package when +% Accents have been made an error in the \texttt{textcomp} package when % not available. Now that we provide the functionality in the -% kernel we avoid the eror by swapping in a \texttt{T1} accent if +% kernel we avoid the error by swapping in a \texttt{T1} accent if % the \texttt{TS1} accent is not available. % \begin{macrocode} %\def\tc@check@accent{\CheckEncodingSubset\UseTextAccent{TS1}\tc@error} % \end{macrocode} % % \begin{macrocode} -\def\tc@check@accent#1{\CheckEncodingSubset\UseTextAccent{TS1}{\tc@swap@accent#1}} +\def\tc@check@accent#1{\CheckEncodingSubset\UseTextAccent + {TS1}{\tc@swap@accent#1}} \def\tc@swap@accent#1#2{\UseTextAccent{T1}#1} % \end{macrocode} % \end{macro} @@ -430,17 +400,17 @@ % % \begin{macrocode} \DeclareTextSymbolDefault{\textdollar}{TS1} -\UndeclareTextCommand{\textdollar} {OT1} % don't use the OT1 def any longer +\UndeclareTextCommand{\textdollar}{OT1} % don't use the OT1 def any longer % \end{macrocode} % % \begin{macrocode} \DeclareTextSymbolDefault{\textsterling}{TS1} -\UndeclareTextCommand{\textsterling}{OT1} % don't use the OT1 def any longer +\UndeclareTextCommand{\textsterling}{OT1}% don't use the OT1 def any longer % \end{macrocode} % % \begin{macrocode} \DeclareTextSymbolDefault{\textperthousand}{TS1} -\UndeclareTextCommand{\textperthousand}{T1} % don't use the T1 def +\UndeclareTextCommand{\textperthousand}{T1} % don't use the T1 def % \end{macrocode} % Using \cs{UndeclareTextCommand} above is enough only if the % encoding definition files are not reloaded afterwards. In the @@ -462,9 +432,9 @@ % \end{macrocode} % % And here are the other \texttt{TS1} glyphs that are implemented -% by every font (or nearly everyone---a few are commented out and +% by every font (or nearly every---a few are commented out and % moved to sub-encoding 9, -% because they aren't around in one or two fonts. +% because they aren't around in some fonts. % \begin{macrocode} %%\DeclareTextSymbolDefault{\textbardbl}{TS1} % subst in sub-enc 9 above \DeclareTextSymbolDefault{\textbrokenbar}{TS1} @@ -541,31 +511,49 @@ % % \begin{macrocode} \ifx\Umathcode\@undefined - \DeclareTextCommandDefault{\capitalacute} {\tc@check@accent{\'}2\capitalacute} - \DeclareTextCommandDefault{\capitalbreve} {\tc@check@accent{\u}2\capitalbreve} - \DeclareTextCommandDefault{\capitalcaron} {\tc@check@accent{\v}2\capitalcaron} - \DeclareTextCommandDefault{\capitalcedilla} {\tc@check@accent{\c}2\capitalcedilla} - \DeclareTextCommandDefault{\capitalcircumflex} {\tc@check@accent{\^}2\capitalcircumflex} - \DeclareTextCommandDefault{\capitaldieresis} {\tc@check@accent{\"}2\capitaldieresis} - \DeclareTextCommandDefault{\capitaldotaccent} {\tc@check@accent{\.}2\capitaldotaccent} - \DeclareTextCommandDefault{\capitalgrave} {\tc@check@accent{\`}2\capitalgrave} - \DeclareTextCommandDefault{\capitalhungarumlaut}{\tc@check@accent{\H}2\capitalhungarumlaut} - \DeclareTextCommandDefault{\capitalmacron} {\tc@check@accent{\=}2\capitalmacron} - \DeclareTextCommandDefault{\capitalogonek} {\tc@check@accent{\k}2\capitalogonek} - \DeclareTextCommandDefault{\capitalring} {\tc@check@accent{\r}2\capitalring} - \DeclareTextCommandDefault{\capitaltie} {\tc@check@accent{\t}2\capitaltie} - \DeclareTextCommandDefault{\capitaltilde} {\tc@check@accent{\~}2\capitaltilde} + \DeclareTextCommandDefault{\capitalacute} + {\tc@check@accent{\'}2\capitalacute} + \DeclareTextCommandDefault{\capitalbreve} + {\tc@check@accent{\u}2\capitalbreve} + \DeclareTextCommandDefault{\capitalcaron} + {\tc@check@accent{\v}2\capitalcaron} + \DeclareTextCommandDefault{\capitalcedilla} + {\tc@check@accent{\c}2\capitalcedilla} + \DeclareTextCommandDefault{\capitalcircumflex} + {\tc@check@accent{\^}2\capitalcircumflex} + \DeclareTextCommandDefault{\capitaldieresis} + {\tc@check@accent{\"}2\capitaldieresis} + \DeclareTextCommandDefault{\capitaldotaccent} + {\tc@check@accent{\.}2\capitaldotaccent} + \DeclareTextCommandDefault{\capitalgrave} + {\tc@check@accent{\`}2\capitalgrave} + \DeclareTextCommandDefault{\capitalhungarumlaut} + {\tc@check@accent{\H}2\capitalhungarumlaut} + \DeclareTextCommandDefault{\capitalmacron} + {\tc@check@accent{\=}2\capitalmacron} + \DeclareTextCommandDefault{\capitalogonek} + {\tc@check@accent{\k}2\capitalogonek} + \DeclareTextCommandDefault{\capitalring} + {\tc@check@accent{\r}2\capitalring} + \DeclareTextCommandDefault{\capitaltie} + {\tc@check@accent{\t}2\capitaltie} + \DeclareTextCommandDefault{\capitaltilde} + {\tc@check@accent{\~}2\capitaltilde} % \end{macrocode} % For \cs{newtie} and \cs{capitalnewtie} this is actually wrong, they should pick up % the accent from the substitution font (not done yet). % \begin{macrocode} - \DeclareTextCommandDefault{\newtie} {\tc@check@accent{\t}2\newtie} - \DeclareTextCommandDefault{\capitalnewtie} {\tc@check@accent{\t}2\capitalnewtie} + \DeclareTextCommandDefault{\newtie} + {\tc@check@accent{\t}2\newtie} + \DeclareTextCommandDefault{\capitalnewtie} + {\tc@check@accent{\t}2\capitalnewtie} % \end{macrocode} % % In Unicode engines we just execute the simple accents: -% \changes{v1.0c}{2020/02/10}{Use \cs{@tabacckludge} for tabbing where necessary (gh/271)} -% \changes{v1.0d}{2020/04/29}{Make all captial accents text commands for hyperref (gh/332)} +% \changes{v1.0c}{2020/02/10}{Use \cs{@tabacckludge} for +% tabbing where necessary (gh/271)} +% \changes{v1.0d}{2020/04/29}{Make all capital accents text +% commands for hyperref (gh/332)} % \begin{macrocode} \else \DeclareTextCommandDefault\capitalacute{\@tabacckludge'} @@ -593,8 +581,10 @@ % The next two symbols exist in some fonts (faked?), but we ignore % that to keep the subsets reasonable compact and most important linear. % \begin{macrocode} -\DeclareTextCommandDefault{\textlbrackdbl} {\tc@check@symbol2\textlbrackdbl} -\DeclareTextCommandDefault{\textrbrackdbl} {\tc@check@symbol2\textrbrackdbl} +\DeclareTextCommandDefault{\textlbrackdbl} + {\tc@check@symbol2\textlbrackdbl} +\DeclareTextCommandDefault{\textrbrackdbl} + {\tc@check@symbol2\textrbrackdbl} % \end{macrocode} % % @@ -603,72 +593,118 @@ % claim they aren't in sub-encoding 2 as that's true for most % fonts. % \begin{macrocode} -\DeclareTextCommandDefault{\texteightoldstyle} {\tc@check@symbol2\texteightoldstyle} -\DeclareTextCommandDefault{\textfiveoldstyle} {\tc@check@symbol2\textfiveoldstyle} -\DeclareTextCommandDefault{\textfouroldstyle} {\tc@check@symbol2\textfouroldstyle} -\DeclareTextCommandDefault{\textnineoldstyle} {\tc@check@symbol2\textnineoldstyle} -\DeclareTextCommandDefault{\textoneoldstyle} {\tc@check@symbol2\textoneoldstyle} -\DeclareTextCommandDefault{\textsevenoldstyle} {\tc@check@symbol2\textsevenoldstyle} -\DeclareTextCommandDefault{\textsixoldstyle} {\tc@check@symbol2\textsixoldstyle} -\DeclareTextCommandDefault{\textthreeoldstyle} {\tc@check@symbol2\textthreeoldstyle} -\DeclareTextCommandDefault{\texttwooldstyle} {\tc@check@symbol2\texttwooldstyle} -\DeclareTextCommandDefault{\textzerooldstyle} {\tc@check@symbol2\textzerooldstyle} -% \end{macrocode} -% -% -% -% The next set of glyphs is special to TeX fonts (and available -% with a few older PS fonts supported in the virtual fonts), but +\DeclareTextCommandDefault{\texteightoldstyle} + {\tc@check@symbol2\texteightoldstyle} +\DeclareTextCommandDefault{\textfiveoldstyle} + {\tc@check@symbol2\textfiveoldstyle} +\DeclareTextCommandDefault{\textfouroldstyle} + {\tc@check@symbol2\textfouroldstyle} +\DeclareTextCommandDefault{\textnineoldstyle} + {\tc@check@symbol2\textnineoldstyle} +\DeclareTextCommandDefault{\textoneoldstyle} + {\tc@check@symbol2\textoneoldstyle} +\DeclareTextCommandDefault{\textsevenoldstyle} + {\tc@check@symbol2\textsevenoldstyle} +\DeclareTextCommandDefault{\textsixoldstyle} + {\tc@check@symbol2\textsixoldstyle} +\DeclareTextCommandDefault{\textthreeoldstyle} + {\tc@check@symbol2\textthreeoldstyle} +\DeclareTextCommandDefault{\texttwooldstyle} + {\tc@check@symbol2\texttwooldstyle} +\DeclareTextCommandDefault{\textzerooldstyle} + {\tc@check@symbol2\textzerooldstyle} +% \end{macrocode} +% +% +% +% The next set of glyphs is special to \TeX{} fonts (and available +% with a few older PS fonts supported through virtual fonts), but % not any longer in the majority of fonts provided through % autoinst, so we pretend there aren't available in sub-encoding 2 % and below. % \begin{macrocode} -\DeclareTextCommandDefault{\textacutedbl} {\tc@check@symbol2\textacutedbl} -\DeclareTextCommandDefault{\textasciiacute} {\tc@check@symbol2\textasciiacute} -\DeclareTextCommandDefault{\textasciibreve} {\tc@check@symbol2\textasciibreve} -\DeclareTextCommandDefault{\textasciicaron} {\tc@check@symbol2\textasciicaron} -\DeclareTextCommandDefault{\textasciidieresis} {\tc@check@symbol2\textasciidieresis} -\DeclareTextCommandDefault{\textasciigrave} {\tc@check@symbol2\textasciigrave} -\DeclareTextCommandDefault{\textasciimacron} {\tc@check@symbol2\textasciimacron} -\DeclareTextCommandDefault{\textgravedbl} {\tc@check@symbol2\textgravedbl} -\DeclareTextCommandDefault{\texttildelow} {\tc@check@symbol2\texttildelow} +\DeclareTextCommandDefault{\textacutedbl} + {\tc@check@symbol2\textacutedbl} +\DeclareTextCommandDefault{\textasciiacute} + {\tc@check@symbol2\textasciiacute} +\DeclareTextCommandDefault{\textasciibreve} + {\tc@check@symbol2\textasciibreve} +\DeclareTextCommandDefault{\textasciicaron} + {\tc@check@symbol2\textasciicaron} +\DeclareTextCommandDefault{\textasciidieresis} + {\tc@check@symbol2\textasciidieresis} +\DeclareTextCommandDefault{\textasciigrave} + {\tc@check@symbol2\textasciigrave} +\DeclareTextCommandDefault{\textasciimacron} + {\tc@check@symbol2\textasciimacron} +\DeclareTextCommandDefault{\textgravedbl} + {\tc@check@symbol2\textgravedbl} +\DeclareTextCommandDefault{\texttildelow} + {\tc@check@symbol2\texttildelow} % \end{macrocode} % % % Finally those below are only available in CM-based fonts but in % no font that has its origin outside of the \TeX{} world. % \begin{macrocode} -\DeclareTextCommandDefault{\textbaht} {\tc@check@symbol2\textbaht} -\DeclareTextCommandDefault{\textbigcircle} {\tc@check@symbol2\textbigcircle} -\DeclareTextCommandDefault{\textborn} {\tc@check@symbol2\textborn} -\DeclareTextCommandDefault{\textcentoldstyle} {\tc@check@symbol2\textcentoldstyle} -\DeclareTextCommandDefault{\textcircledP} {\tc@check@symbol2\textcircledP} -\DeclareTextCommandDefault{\textcopyleft} {\tc@check@symbol2\textcopyleft} -\DeclareTextCommandDefault{\textdblhyphenchar} {\tc@check@symbol2\textdblhyphenchar} -\DeclareTextCommandDefault{\textdblhyphen} {\tc@check@symbol2\textdblhyphen} -\DeclareTextCommandDefault{\textdied} {\tc@check@symbol2\textdied} -\DeclareTextCommandDefault{\textdiscount} {\tc@check@symbol2\textdiscount} -\DeclareTextCommandDefault{\textdivorced} {\tc@check@symbol2\textdivorced} -\DeclareTextCommandDefault{\textdollaroldstyle} {\tc@check@symbol2\textdollaroldstyle} -\DeclareTextCommandDefault{\textguarani} {\tc@check@symbol2\textguarani} -\DeclareTextCommandDefault{\textleaf} {\tc@check@symbol2\textleaf} -\DeclareTextCommandDefault{\textlquill} {\tc@check@symbol2\textlquill} -\DeclareTextCommandDefault{\textmarried} {\tc@check@symbol2\textmarried} -\DeclareTextCommandDefault{\textmho} {\tc@check@symbol2\textmho} -\DeclareTextCommandDefault{\textmusicalnote} {\tc@check@symbol2\textmusicalnote} -\DeclareTextCommandDefault{\textnaira} {\tc@check@symbol2\textnaira} -\DeclareTextCommandDefault{\textopenbullet} {\tc@check@symbol2\textopenbullet} -\DeclareTextCommandDefault{\textpeso} {\tc@check@symbol2\textpeso} -\DeclareTextCommandDefault{\textpilcrow} {\tc@check@symbol2\textpilcrow} -\DeclareTextCommandDefault{\textrecipe} {\tc@check@symbol2\textrecipe} -\DeclareTextCommandDefault{\textreferencemark} {\tc@check@symbol2\textreferencemark} -\DeclareTextCommandDefault{\textrquill} {\tc@check@symbol2\textrquill} -\DeclareTextCommandDefault{\textservicemark} {\tc@check@symbol2\textservicemark} -\DeclareTextCommandDefault{\textsurd} {\tc@check@symbol2\textsurd} +\DeclareTextCommandDefault{\textbaht} + {\tc@check@symbol2\textbaht} +\DeclareTextCommandDefault{\textbigcircle} + {\tc@check@symbol2\textbigcircle} +\DeclareTextCommandDefault{\textborn} + {\tc@check@symbol2\textborn} +\DeclareTextCommandDefault{\textcentoldstyle} + {\tc@check@symbol2\textcentoldstyle} +\DeclareTextCommandDefault{\textcircledP} + {\tc@check@symbol2\textcircledP} +\DeclareTextCommandDefault{\textcopyleft} + {\tc@check@symbol2\textcopyleft} +\DeclareTextCommandDefault{\textdblhyphenchar} + {\tc@check@symbol2\textdblhyphenchar} +\DeclareTextCommandDefault{\textdblhyphen} + {\tc@check@symbol2\textdblhyphen} +\DeclareTextCommandDefault{\textdied} + {\tc@check@symbol2\textdied} +\DeclareTextCommandDefault{\textdiscount} + {\tc@check@symbol2\textdiscount} +\DeclareTextCommandDefault{\textdivorced} + {\tc@check@symbol2\textdivorced} +\DeclareTextCommandDefault{\textdollaroldstyle} + {\tc@check@symbol2\textdollaroldstyle} +\DeclareTextCommandDefault{\textguarani} + {\tc@check@symbol2\textguarani} +\DeclareTextCommandDefault{\textleaf} + {\tc@check@symbol2\textleaf} +\DeclareTextCommandDefault{\textlquill} + {\tc@check@symbol2\textlquill} +\DeclareTextCommandDefault{\textmarried} + {\tc@check@symbol2\textmarried} +\DeclareTextCommandDefault{\textmho} + {\tc@check@symbol2\textmho} +\DeclareTextCommandDefault{\textmusicalnote} + {\tc@check@symbol2\textmusicalnote} +\DeclareTextCommandDefault{\textnaira} + {\tc@check@symbol2\textnaira} +\DeclareTextCommandDefault{\textopenbullet} + {\tc@check@symbol2\textopenbullet} +\DeclareTextCommandDefault{\textpeso} + {\tc@check@symbol2\textpeso} +\DeclareTextCommandDefault{\textpilcrow} + {\tc@check@symbol2\textpilcrow} +\DeclareTextCommandDefault{\textrecipe} + {\tc@check@symbol2\textrecipe} +\DeclareTextCommandDefault{\textreferencemark} + {\tc@check@symbol2\textreferencemark} +\DeclareTextCommandDefault{\textrquill} + {\tc@check@symbol2\textrquill} +\DeclareTextCommandDefault{\textservicemark} + {\tc@check@symbol2\textservicemark} +\DeclareTextCommandDefault{\textsurd} + {\tc@check@symbol2\textsurd} % \end{macrocode} % % The \cs{textpertenthousand} also belongs in this group but here -% we have a choice: in T1 there is definition for +% we have a choice: in T1 there is a definition for % \cs{textpertenthousand} making the symbol up from \% and % \verb=\char 24= (twice) but in many fonts that char doesn't exist % and the slot is reused for random ligatures. So better not use it @@ -679,7 +715,8 @@ % Alternatively we could just state that the symbol is unavailable in % those fonts. For now I substitute. % \begin{macrocode} -\DeclareTextCommandDefault{\textpertenthousand} {\tc@check@symbol2\textpertenthousand} +\DeclareTextCommandDefault{\textpertenthousand} + {\tc@check@symbol2\textpertenthousand} \UndeclareTextCommand{\textpertenthousand}{T1} % \end{macrocode} % @@ -691,8 +728,10 @@ % symbols. In the higher-numbered sub-encodings we see only a few % dropped additionally. % \begin{macrocode} -\DeclareTextCommandDefault{\textlangle} {\tc@check@symbol3\textlangle} -\DeclareTextCommandDefault{\textrangle} {\tc@check@symbol3\textrangle} +\DeclareTextCommandDefault{\textlangle} + {\tc@check@symbol3\textlangle} +\DeclareTextCommandDefault{\textrangle} + {\tc@check@symbol3\textrangle} % \end{macrocode} % % @@ -702,14 +741,22 @@ % \subsection{Sub-encoding \texttt{4}} % % \begin{macrocode} -\DeclareTextCommandDefault{\textcolonmonetary} {\tc@check@symbol4\textcolonmonetary} -\DeclareTextCommandDefault{\textdong} {\tc@check@symbol4\textdong} -\DeclareTextCommandDefault{\textdownarrow} {\tc@check@symbol4\textdownarrow} -\DeclareTextCommandDefault{\textleftarrow} {\tc@check@symbol4\textleftarrow} -\DeclareTextCommandDefault{\textlira} {\tc@check@symbol4\textlira} -\DeclareTextCommandDefault{\textrightarrow} {\tc@check@symbol4\textrightarrow} -\DeclareTextCommandDefault{\textuparrow} {\tc@check@symbol4\textuparrow} -\DeclareTextCommandDefault{\textwon} {\tc@check@symbol4\textwon} +\DeclareTextCommandDefault{\textcolonmonetary} + {\tc@check@symbol4\textcolonmonetary} +\DeclareTextCommandDefault{\textdong} + {\tc@check@symbol4\textdong} +\DeclareTextCommandDefault{\textdownarrow} + {\tc@check@symbol4\textdownarrow} +\DeclareTextCommandDefault{\textleftarrow} + {\tc@check@symbol4\textleftarrow} +\DeclareTextCommandDefault{\textlira} + {\tc@check@symbol4\textlira} +\DeclareTextCommandDefault{\textrightarrow} + {\tc@check@symbol4\textrightarrow} +\DeclareTextCommandDefault{\textuparrow} + {\tc@check@symbol4\textuparrow} +\DeclareTextCommandDefault{\textwon} + {\tc@check@symbol4\textwon} % \end{macrocode} % % @@ -720,22 +767,24 @@ % % Most older PS fonts (supported in \TeX{} since the early nineties % when virtual fonts became available) are sorted under this -% sub-encoding. But in reality, many of them don't have all glpyhs +% sub-encoding. But in reality, many of them don't have all glyphs % that should be available in sub-encoding \texttt{5}. Instead they % show little squares, i.e., they produce ``tofu'' if you are % unlucky. % % But the coverage is so random that it is impossible to sort them % properly and if we tried to ensure that they only typeset those -% glyphs that are really always available wouput put them all into -% sub-encoding \texttt{9} so that's a compromise really. +% glyphs that are really always available, we would have to put them all into +% sub-encoding \texttt{9}; so putting them into 5 is really a compromise. % -% Modern fonts that don't typeset a tofu character if a glyph is -% missing are only cataloged as sub-encoding \texttt{5} if they -% really support of its glyph set. +% Modern fonts usually don't typeset a tofu character if a glyph is +% missing. They are therefore only classified as sub-encoding \texttt{5} if they +% really support its glyph set completely. % \begin{macrocode} -\DeclareTextCommandDefault{\textestimated} {\tc@check@symbol5\textestimated} -\DeclareTextCommandDefault{\textnumero} {\tc@check@symbol5\textnumero} +\DeclareTextCommandDefault{\textestimated} + {\tc@check@symbol5\textestimated} +\DeclareTextCommandDefault{\textnumero} + {\tc@check@symbol5\textnumero} % \end{macrocode} % % @@ -744,8 +793,10 @@ % \subsection{Sub-encoding \texttt{6}} % % \begin{macrocode} -\DeclareTextCommandDefault{\textflorin} {\tc@check@symbol6\textflorin} -\DeclareTextCommandDefault{\textcurrency} {\tc@check@symbol6\textcurrency} +\DeclareTextCommandDefault{\textflorin} + {\tc@check@symbol6\textflorin} +\DeclareTextCommandDefault{\textcurrency} + {\tc@check@symbol6\textcurrency} % \end{macrocode} % % @@ -753,10 +804,14 @@ % \subsection{Sub-encoding \texttt{7}} % % \begin{macrocode} -\DeclareTextCommandDefault{\textfractionsolidus}{\tc@check@symbol7\textfractionsolidus} -\DeclareTextCommandDefault{\textohm} {\tc@check@symbol7\textohm} -\DeclareTextCommandDefault{\textmu} {\tc@check@symbol7\textmu} -\DeclareTextCommandDefault{\textminus} {\tc@check@symbol7\textminus} +\DeclareTextCommandDefault{\textfractionsolidus} + {\tc@check@symbol7\textfractionsolidus} +\DeclareTextCommandDefault{\textohm} + {\tc@check@symbol7\textohm} +\DeclareTextCommandDefault{\textmu} + {\tc@check@symbol7\textmu} +\DeclareTextCommandDefault{\textminus} + {\tc@check@symbol7\textminus} % \end{macrocode} % % @@ -764,16 +819,19 @@ % \subsection{Sub-encoding \texttt{8}} % % \begin{macrocode} -\DeclareTextCommandDefault{\textblank} {\tc@check@symbol{8}\textblank} -\DeclareTextCommandDefault{\textinterrobangdown}{\tc@check@symbol{8}\textinterrobangdown} -\DeclareTextCommandDefault{\textinterrobang} {\tc@check@symbol{8}\textinterrobang} +\DeclareTextCommandDefault{\textblank} + {\tc@check@symbol{8}\textblank} +\DeclareTextCommandDefault{\textinterrobangdown} + {\tc@check@symbol{8}\textinterrobangdown} +\DeclareTextCommandDefault{\textinterrobang} + {\tc@check@symbol{8}\textinterrobang} % \end{macrocode} % % Fonts with this sub-encoding don't have a Euro symbol, but % instead of substituting we fake it. % \begin{macrocode} \DeclareTextCommandDefault{\texteuro} - {\CheckEncodingSubset\UseTextSymbol{TS1}\tc@fake@euro{8}\texteuro} + {\CheckEncodingSubset\UseTextSymbol{TS1}\tc@fake@euro{8}\texteuro} % \end{macrocode} % % @@ -782,13 +840,20 @@ % \subsection{Sub-encoding \texttt{9} (most missing)} % % \begin{macrocode} -\DeclareTextCommandDefault{\textcelsius}{\tc@check@symbol{9}\textcelsius} -\DeclareTextCommandDefault{\textonesuperior}{\tc@check@symbol{9}\textonesuperior} -\DeclareTextCommandDefault{\textthreequartersemdash}{\tc@check@symbol{9}\textthreequartersemdash} -\DeclareTextCommandDefault{\textthreesuperior}{\tc@check@symbol{9}\textthreesuperior} -\DeclareTextCommandDefault{\texttwelveudash}{\tc@check@symbol{9}\texttwelveudash} -\DeclareTextCommandDefault{\texttwosuperior}{\tc@check@symbol{9}\texttwosuperior} -\DeclareTextCommandDefault{\textbardbl}{\tc@check@symbol{9}\textbardbl} +\DeclareTextCommandDefault{\textcelsius} + {\tc@check@symbol{9}\textcelsius} +\DeclareTextCommandDefault{\textonesuperior} + {\tc@check@symbol{9}\textonesuperior} +\DeclareTextCommandDefault{\textthreequartersemdash} + {\tc@check@symbol{9}\textthreequartersemdash} +\DeclareTextCommandDefault{\textthreesuperior} + {\tc@check@symbol{9}\textthreesuperior} +\DeclareTextCommandDefault{\texttwelveudash} + {\tc@check@symbol{9}\texttwelveudash} +\DeclareTextCommandDefault{\texttwosuperior} + {\tc@check@symbol{9}\texttwosuperior} +\DeclareTextCommandDefault{\textbardbl} + {\tc@check@symbol{9}\textbardbl} % \end{macrocode} % % @@ -830,20 +895,20 @@ \DeclareTextCommand{\texteightoldstyle}\UnicodeEncodingName{\oldstylenums{8}} \DeclareTextCommand{\textnineoldstyle} \UnicodeEncodingName{\oldstylenums{9}} % \end{macrocode} -% These have Unicode slots so this should be integrated into TU explictly +% These have Unicode slots so this should be integrated into TU explicitly % \begin{macrocode} -\DeclareTextSymbol{\textpilcrow} \UnicodeEncodingName{"00B6} -\DeclareTextSymbol{\textborn} \UnicodeEncodingName{"002A} -\DeclareTextSymbol{\textdied} \UnicodeEncodingName{"2020} -\DeclareTextSymbol{\textlbrackdbl} \UnicodeEncodingName{"27E6} -\DeclareTextSymbol{\textrbrackdbl} \UnicodeEncodingName{"27E7} -\DeclareTextSymbol{\textguarani} \UnicodeEncodingName{"20B2} +\DeclareTextSymbol{\textpilcrow} \UnicodeEncodingName{"00B6} +\DeclareTextSymbol{\textborn} \UnicodeEncodingName{"002A} +\DeclareTextSymbol{\textdied} \UnicodeEncodingName{"2020} +\DeclareTextSymbol{\textlbrackdbl} \UnicodeEncodingName{"27E6} +\DeclareTextSymbol{\textrbrackdbl} \UnicodeEncodingName{"27E7} +\DeclareTextSymbol{\textguarani} \UnicodeEncodingName{"20B2} % \end{macrocode} % We could make \cs{textcentoldstyle} and \cs{textdollaroldstyle} % point to dollar and cent in the Unicode encoding % \begin{macrocode} -%\DeclareTextSymbol{\textcentoldstyle} \UnicodeEncodingName{"00A2} -%\DeclareTextSymbol{\textdollaroldstyle} \UnicodeEncodingName{"0024} +%\DeclareTextSymbol{\textcentoldstyle} \UnicodeEncodingName{"00A2} +%\DeclareTextSymbol{\textdollaroldstyle}\UnicodeEncodingName{"0024} % \end{macrocode} % but I think it is better to pick them up from TS1 even if that % usually means LMR fonts @@ -908,7 +973,8 @@ \DeclareEncodingSubset{TS1}{lmss} {1} \DeclareEncodingSubset{TS1}{lmssq} {1} \DeclareEncodingSubset{TS1}{lmvtt} {1} -\DeclareEncodingSubset{TS1}{lmtt} {1} % missing TM, SM, pertenthousand for some reason +\DeclareEncodingSubset{TS1}{lmtt} {1} % missing TM, SM and + % pertenthousand for some reason % \end{macrocode} % % \begin{macrocode} @@ -918,33 +984,33 @@ % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{bch} {5} % tofu for blank, ohm -\DeclareEncodingSubset{TS1}{futj} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{futs} {5} % tofu for blank, ohm -\DeclareEncodingSubset{TS1}{futx} {5} % probably (currently broken distrib) -\DeclareEncodingSubset{TS1}{pag} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{pbk} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{pcr} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{phv} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{pnc} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{pplj} {5} % tofu for blank -\DeclareEncodingSubset{TS1}{pplx} {5} % tofu for blank -\DeclareEncodingSubset{TS1}{ppl} {5} % tofu for blank interrobang/down -\DeclareEncodingSubset{TS1}{ptm} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{pzc} {5} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{ul9} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{bch} {5} % tofu for blank, ohm +\DeclareEncodingSubset{TS1}{futj}{5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{futs}{5} % tofu for blank, ohm +\DeclareEncodingSubset{TS1}{futx}{5} % probably (currently broken distrib) +\DeclareEncodingSubset{TS1}{pag} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{pbk} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{pcr} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{phv} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{pnc} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{pplj}{5} % tofu for blank +\DeclareEncodingSubset{TS1}{pplx}{5} % tofu for blank +\DeclareEncodingSubset{TS1}{ppl} {5} % tofu for blank interrobang/down +\DeclareEncodingSubset{TS1}{ptm} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{pzc} {5} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{ul9} {5} % tofu for blank, interrobang/down, ohm % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{dayroms} {6} % tofu for blank, interrobang/down, ohm -\DeclareEncodingSubset{TS1}{dayrom} {6} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{dayroms}{6} % tofu for blank, interrobang/down, ohm +\DeclareEncodingSubset{TS1}{dayrom} {6} % tofu for blank, interrobang/down, ohm % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{augie} {8} % really only missing euro -\DeclareEncodingSubset{TS1}{put} {8} -\DeclareEncodingSubset{TS1}{uag} {8} % probably (currently broken distrib) -\DeclareEncodingSubset{TS1}{ugq} {8} +\DeclareEncodingSubset{TS1}{augie}{8} % really only missing euro +\DeclareEncodingSubset{TS1}{put} {8} +\DeclareEncodingSubset{TS1}{uag} {8} % probably (currently broken distrib) +\DeclareEncodingSubset{TS1}{ugq} {8} % \end{macrocode} % % \begin{macrocode} @@ -976,14 +1042,14 @@ % substituted. % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{lato-*} {0} % with a bunch of tofu inside -\DeclareEncodingSubset{TS1}{opensans-*} {0} % with a bunch of tofu inside -\DeclareEncodingSubset{TS1}{cantarell-*} {0} % with a bunch of tofu inside -\DeclareEncodingSubset{TS1}{fbb-*} {0} % missing centoldstyle +\DeclareEncodingSubset{TS1}{lato-*} {0} % with a bunch of tofu inside +\DeclareEncodingSubset{TS1}{opensans-*} {0} % with a bunch of tofu inside +\DeclareEncodingSubset{TS1}{cantarell-*} {0} % with a bunch of tofu inside +\DeclareEncodingSubset{TS1}{fbb-*} {0} % missing centoldstyle % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{tli} {1} % with lots of tofu inside +\DeclareEncodingSubset{TS1}{tli} {1} % with lots of tofu inside % \end{macrocode} % % \begin{macrocode} @@ -1109,7 +1175,7 @@ \DeclareEncodingSubset{TS1}{erewhon-*} {7} \DeclareEncodingSubset{TS1}{ComicNeue-TLF} {7} \DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF} {7} -\DeclareEncodingSubset{TS1}{Forum-LF} {7} % the superiors are missing +\DeclareEncodingSubset{TS1}{Forum-LF} {7} % the superiors are missing % \end{macrocode} % % \begin{macrocode} @@ -1156,7 +1222,7 @@ % \begin{macro}{\textlegacysection} % % Here are new names for the legacy symbols that \LaTeX{} used to -% pick up from the \texttt{OMS} encoded fonts (and used dor itemize +% pick up from the \texttt{OMS} encoded fonts (and used for itemize % lists or footnote symbols. % % We go the roundabout way via separate OMS declarations so that @@ -1199,9 +1265,19 @@ % Supporting rollback \ldots % \begin{macrocode} % -%\EndIncludeInRelease +% %\IncludeInRelease{0000/00/00}% -% {\DeclareEncodingSubset}{Text companion symbols}% +% {lttextcomp}{Undefine text companion symbols}% +% +%\DeclareRobustCommand\oldstylenums[1]{% +% \begingroup +% \spaceskip\fontdimen\tw@\font +% \usefont{OML}{\rmdefault}{\f@series}{it}% +% \mathgroup\symletters #1% +% \endgroup +%} +%\let\legacyoldstylenums\@undefined +%\def\textcompsubstdefault{cmr} % %\let\DeclareEncodingSubset\@undefined %\let\CheckEncodingSubset\@undefined @@ -1237,26 +1313,32 @@ %\let\textbrokenbar\@undefined %\let\textcelsius\@undefined %\let\textcent\@undefined -%\DeclareTextCommandDefault{\textcopyright}{\textcircled{c}} +%\DeclareTextCommandDefault{\textcopyright} +% {\textcircled{c}} %\let\textdegree\@undefined %\let\textdiv\@undefined %\let\textlnot\@undefined %\let\textonehalf\@undefined %\let\textonequarter\@undefined %\let\textonesuperior\@undefined -%\DeclareTextCommandDefault{\textordfeminine}{\textsuperscript{a}} -%\DeclareTextCommandDefault{\textordmasculine}{\textsuperscript{o}} +%\DeclareTextCommandDefault{\textordfeminine} +% {\textsuperscript{a}} +%\DeclareTextCommandDefault{\textordmasculine} +% {\textsuperscript{o}} %\let\textpm\@undefined %\let\textquotesingle\@undefined %\let\textquotestraightbase\@undefined %\let\textquotestraightdblbase\@undefined -%\DeclareTextCommandDefault{\textregistered}{\textcircled{% -% \check@mathfonts\fontsize\sf@size\z@\math@fontsfalse\selectfont R}} +%\DeclareTextCommandDefault{\textregistered} +% {\textcircled{% +% \check@mathfonts\fontsize\sf@size\z@ +% \math@fontsfalse\selectfont R}} %\let\textthreequartersemdash\@undefined %\let\textthreequarters\@undefined %\let\textthreesuperior\@undefined %\let\texttimes\@undefined -%\DeclareTextCommandDefault{\texttrademark}{\textsuperscript{TM}} +%\DeclareTextCommandDefault{\texttrademark} +% {\textsuperscript{TM}} %\let\texttwelveudash\@undefined %\let\texttwosuperior\@undefined %\let\textyen\@undefined @@ -1386,9 +1468,7 @@ %\let\textlegacyperiodcentered\@undefined %\let\textlegacysection\@undefined % -%\EndIncludeInRelease -%<*2ekernel> -% +%\EndModuleRelease % \end{macrocode} % % @@ -1433,9 +1513,12 @@ % kernel is info only). Using the package options you can change this behavior. % \changes{v2.0n}{2020/02/05}{Changed the package default to info (gh/262)} % \begin{macrocode} -\DeclareOption{error}{\gdef\tc@errorwarn{\PackageError{textcomp}}} -\DeclareOption{warn}{\gdef\tc@errorwarn#1#2{\PackageWarning{textcomp}{#1}}} -\DeclareOption{info}{\gdef\tc@errorwarn#1#2{\PackageInfo{textcomp}{#1}}} +\DeclareOption{error} + {\gdef\tc@errorwarn{\PackageError{textcomp}}} +\DeclareOption{warn} + {\gdef\tc@errorwarn#1#2{\PackageWarning{textcomp}{#1}}} +\DeclareOption{info} + {\gdef\tc@errorwarn#1#2{\PackageInfo{textcomp}{#1}}} \DeclareOption{quiet}{\gdef\tc@errorwarn#1#2{}} % \end{macrocode} % @@ -1443,7 +1526,7 @@ % of the default (which, unless changes, is 9 these days), i.e., it % no longer depends on the font in use. This is mainly there % because it might have been used in older documents, but not -% somehting that is recommended. +% something that is recommended. % \begin{macrocode} \DeclareOption{force}{% \def\CheckEncodingSubset#1#2#3#4#5{% @@ -1483,7 +1566,7 @@ % This section contains the old code for the textcomp package and % its documentation. It is only used if we roll back prior to 2020. % Thus all the rest is mainly for historians. Note that the old -% code categorised in the sub-encodings only into 6 classes not 10. +% code categorized in the sub-encodings only into 6 classes not 10. % % \begin{macrocode} %<*TS1oldsty> @@ -1773,7 +1856,7 @@ % to ensure that |\textcurrency| is only typeset if the current % font has a \texttt{TS1} subset id of less than 3. Otherwise % |\tc@error| is called telling the user that for this font family -% |\textcurreny| is not available. +% |\textcurrency| is not available. % \begin{macrocode} \def\tc@check@symbol{\CheckEncodingSubset\UseTextSymbol{TS1}\tc@subst} \def\tc@check@accent{\CheckEncodingSubset\UseTextAccent{TS1}\tc@error} @@ -2008,7 +2091,7 @@ % % Finally input the encoding-specific definitions for % \texttt{TS1} thus making the top-level definitions -% optimised for this encoding (and not for the default +% optimized for this encoding (and not for the default % encoding). % \changes{v1.9o}{1998/03/20}{Load decls after defaults for speed.} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltthm.dtx b/Master/texmf-dist/source/latex/base/ltthm.dtx index 4e3c51ab77e..00fe97c77af 100644 --- a/Master/texmf-dist/source/latex/base/ltthm.dtx +++ b/Master/texmf-dist/source/latex/base/ltthm.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/ltvers.dtx b/Master/texmf-dist/source/latex/base/ltvers.dtx index c42a126a31c..af0688b887b 100644 --- a/Master/texmf-dist/source/latex/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex/base/ltvers.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltvers.dtx} - [2020/03/02 v1.1e LaTeX Kernel (Version Info)] + [2021/04/16 v1.1g LaTeX Kernel (Version Info)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltvers.dtx} @@ -112,10 +112,10 @@ % %\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2020-10-01} + {2021-06-01} % %<*2ekernel> -\def\patch@level{4} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} @@ -125,7 +125,7 @@ % intended to help us internally when we locally install a % format out of some development branch. % \begin{macrocode} -\edef\development@branch@name{} +\edef\development@branch@name{develop \the\year-\the\month-\the\day} % \end{macrocode} % \end{macro} % \end{macro} @@ -181,28 +181,30 @@ % \begin{macrocode} \ifnum0\ifnum\patch@level=0 \ifx\development@branch@name\@empty 1\fi\fi>0 % \everyjob\expandafter{\the\everyjob - \typeout{\fmtname \space<\fmtversion>}} + \typeout{\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}} + \typeout{\fmtname\space <\fmtversion> patch level \patch@level}} \immediate - \write16{\fmtname \space<\fmtversion> patch level \patch@level} + \write16{\fmtname\space <\fmtversion> patch level \patch@level} \else \everyjob\expandafter{\the\everyjob - \typeout{\fmtname \space<\fmtversion> pre-release-\number-\patch@level\space - \ifx\development@branch@name\@undefined \else - \ifx\development@branch@name\@empty \else - \space (\development@branch@name\space branch)% + \typeout{\fmtname\space <\fmtversion> + pre-release-\number-\patch@level\space + \ifx\development@branch@name\@undefined \else + \ifx\development@branch@name\@empty \else + \space (\development@branch@name\space branch)% \fi \fi }} \immediate - \write16{\fmtname \space<\fmtversion> pre-release-\number-\patch@level\space - \ifx\development@branch@name\@undefined \else - \ifx\development@branch@name\@empty \else - \space (\development@branch@name\space branch)% + \write16{\fmtname\space <\fmtversion> + pre-release-\number-\patch@level\space + \ifx\development@branch@name\@undefined \else + \ifx\development@branch@name\@empty \else + \space (\development@branch@name\space branch)% \fi \fi } @@ -212,6 +214,11 @@ % \end{macrocode} % % \begin{macro}{\IncludeInRelease} +% \begin{macro}{\EndIncludeInRelease} +% \begin{macro}{\@IncludeInRelease} +% \begin{macro}{\@IncludeInRele@se} +% \begin{macro}{\@gobble@IncludeInRelease} +% \begin{macro}{\@check@IncludeInRelease} % \changes{v1.0w}{2015/02/21} % {set \cs{@currname} empty here (in case \cs{IncludeInRelease} input early)} % \begin{macrocode} @@ -222,6 +229,7 @@ % \changes{v1.0m}{2015/01/17}{modified with \cs{@currname}} % \changes{v1.0o}{2015/01/19}{Optional argument} % \changes{v1.0q}{2015/02/19}{Swap argument order} +% \changes{v1.1f}{2021/03/18}{Add support for usage in \cs{NewModuleRelease}} % % \begin{macrocode} %<*2ekernel|latexrelease> @@ -235,9 +243,29 @@ {There is an \string\EndIncludeRelease\space missing}% \@includeinreleasefalse \fi - \kernel@ifnextchar[% - {\@IncludeInRelease{#1}} - {\@IncludeInRelease{#1}[#1]}} + \ifnum0% + \ifx\new@moduledate\@empty\else 1\fi + \ifnum \expandafter\@parse@version#1//00\@nil=0 1\fi + =11 + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi + {\finish@module@release{#1}}% + {\kernel@ifnextchar[% + {\@IncludeInRelease{#1}} + {\@IncludeInRelease{#1}[#1]}}} +\def\finish@module@release#1#2#3{% + \toks@{[#1] #3}% + \ifnum\expandafter\@parse@version\new@moduledate//00\@nil + >\expandafter\@parse@version\fmtversion//00\@nil + \GenericInfo{}{Applying: \the\toks@}% + \else + \GenericInfo{}{Skipping: \the\toks@}% + \expandafter\gobble@finish@module@release + \fi} +\long\def\gobble@finish@module@release#1\EndModuleRelease{% + \EndModuleRelease} % \end{macrocode} % % If a specific date has not been specified in |latexrelease| @@ -255,13 +283,13 @@ % that is actually reapplying what is already in the format, i.e., % it is useless and possibly allocating new registers. However, it % makes the logic simpler so this is the way it is for now. In -% theory we could always jump overthe first patch because that is +% theory we could always jump over the first patch because that is % only really needed for rolling forward. So maybe one day \dots % \begin{macrocode} \ifnum\expandafter\@parse@version#1//00\@nil - >\expandafter\@parse@version\fmtversion//00\@nil + >\expandafter\@parse@version\fmtversion//00\@nil \GenericInfo{}{Skipping: \the\toks@}% - \expandafter\expandafter\expandafter\@gobble@IncludeInRelease + \expandafter\expandafter\expandafter\@gobble@IncludeInRelease \else \GenericInfo{}{Applying: \the\toks@}% \@includeinreleasetrue @@ -280,6 +308,9 @@ \@includeinreleasefalse \else \PackageError{latexrelease}{mis-matched EndIncludeInRelease}{}% +\fi +\if@skipping@module + \expandafter\new@module@skip \fi} % \end{macrocode} % @@ -294,13 +325,87 @@ #2#3\@end@check@IncludeInRelease{% \ifx\@check@IncludeInRelease#2\else \PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}% + \fi + \if@skipping@module + \expandafter\new@module@skip \fi} % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % +% \subsection{Declaring an all-new module} +% +% \begin{macro}{\if@skipping@module} +% \begin{macro}{\NewModuleRelease} +% \begin{macro}{\EndModuleRelease} +% \begin{macro}{\new@module@skip} +% \begin{macro}{\new@modulename} +% \begin{macro}{\new@moduledate} +% +% When we have a whole new module, we can't roll back to a date where +% such module exists, otherwise hundreds of \enquote{command already +% defined} errors will pop up. But we can't skip it altogether +% either, because the module might have changes we still want applied, +% so a more detailed cherry-picking of code chunks have to be done. +% +% \changes{v1.1f}{2021/03/18}{Added \cs{NewModuleRelease}.} +% \changes{v1.1g}{2021/04/16} +% {\cs{NewModuleRelease} with the same arguments as \cs{IncludeInRelease}.} % \begin{macrocode} -% +\let\if@skipping@module\iffalse +\def\@skipping@moduletrue{\let\if@skipping@module\iftrue} +\def\@skipping@modulefalse{\let\if@skipping@module\iffalse} +\let\new@modulename\@empty +\let\new@moduledate\@empty +\def\NewModuleRelease#1#2#3{% + \ifx\new@modulename\@empty \else + \@latex@error{Nested \noexpand\NewModuleRelease forbidden.}\@ehd \fi + \edef\new@moduledate{#1}% + \edef\new@modulename{#2}% + \GenericInfo{}{BEGIN module: \new@modulename\space (\new@moduledate)}% + \GenericInfo{}{ \@spaces\@spaces\@spaces\space#3\@gobble}% + \ifnum\sourceLaTeXdate<% + \expandafter\@parse@version\new@moduledate//00\@nil\relax + \ifnum\expandafter\@parse@version\fmtversion//00\@nil<% + \expandafter\@parse@version\new@moduledate//00\@nil\relax + \GenericInfo{}{Skipping module \new@modulename}% + \expandafter\expandafter + \expandafter\gobble@finish@module@release + \else + \GenericInfo{}{Applying module \new@modulename} + \@skipping@modulefalse + \fi + \else + \GenericInfo{}{Skipping module \new@modulename} + \@skipping@moduletrue + \expandafter\new@module@skip + \fi} +\long\def\new@module@skip#1\IncludeInRelease{\IncludeInRelease} +\def\EndModuleRelease{% + \ifx\new@modulename\@empty + \@latex@error{Extra \string\EndModuleRelease.}\@eha + \else + \GenericInfo{}{END module: \new@modulename\space (\new@moduledate)}% + \let\new@modulename\@empty + \let\new@moduledate\@empty + \@skipping@modulefalse + \fi} % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macrocode} +% +% \end{macrocode} +% % \Finale % \endinput diff --git a/Master/texmf-dist/source/latex/base/ltxdoc.dtx b/Master/texmf-dist/source/latex/base/ltxdoc.dtx index 0c7130c3717..7a21f7d871f 100644 --- a/Master/texmf-dist/source/latex/base/ltxdoc.dtx +++ b/Master/texmf-dist/source/latex/base/ltxdoc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,7 +30,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesClass{ltxdoc} -% [2020/10/04 v2.1b Standard LaTeX documentation class] +% [2020/12/05 v2.1b Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -484,7 +484,7 @@ % \end{macrocode} % Set \cs{protect} to a suitable value in the index entries (we % can't use |\set@display@protect| as that would result in different -% numer of spaces after a command depending on the number of +% number of spaces after a command depending on the number of % expansion happening prior to writing the index). % \begin{macrocode} \begingroup diff --git a/Master/texmf-dist/source/latex/base/ltxref.dtx b/Master/texmf-dist/source/latex/base/ltxref.dtx index 56ae09c1650..dd482299b28 100644 --- a/Master/texmf-dist/source/latex/base/ltxref.dtx +++ b/Master/texmf-dist/source/latex/base/ltxref.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltxref.dtx} - [2020/08/23 v1.1o LaTeX Kernel (Cross Referencing)] + [2020/12/05 v1.1o LaTeX Kernel (Cross Referencing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltxref.dtx} @@ -68,10 +68,10 @@ % The user writes |\label|\marg{foo} to define the following % cross-references: % -% |\ref|\marg{foo}: value of most recently incremented referencable +% |\ref|\marg{foo}: value of most recently incremented referenceable % counter. in the current environment. (Chapter, section, % theorem and enumeration counters are -% referencable, footnote counters are not.) +% referenceable, footnote counters are not.) % % |\pageref|\marg{foo}: page number at which |\label{foo}| command % appeared. where foo can be any string of characters not @@ -98,7 +98,7 @@ \message{x-ref,} % \end{macrocode} % -% This is implemented as follows. A referencable counter CNT is +% This is implemented as follows. A referenceable counter CNT is % 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 : diff --git a/Master/texmf-dist/source/latex/base/makeindx.dtx b/Master/texmf-dist/source/latex/base/makeindx.dtx index a149bcf86c5..e8e48e60b06 100644 --- a/Master/texmf-dist/source/latex/base/makeindx.dtx +++ b/Master/texmf-dist/source/latex/base/makeindx.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -28,7 +28,7 @@ % \fi %\iffalse % Copyright (C) 1985 by Leslie Lamport -% Copyright (C) 1994-98 by \LaTeX3 Project and Johannes Braams +% Copyright (C) 1994-98 by LaTeX Project and Johannes Braams %\fi % % \changes{1.0b}{1994/01/21}{added a missing \cs{end\{macro\}}, a diff --git a/Master/texmf-dist/source/latex/base/makeindx.ins b/Master/texmf-dist/source/latex/base/makeindx.ins index 5e86d50579e..427d4c79674 100644 --- a/Master/texmf-dist/source/latex/base/makeindx.ins +++ b/Master/texmf-dist/source/latex/base/makeindx.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/newdc.ins b/Master/texmf-dist/source/latex/base/newdc.ins index 962510313c0..e2ce183f05e 100644 --- a/Master/texmf-dist/source/latex/base/newdc.ins +++ b/Master/texmf-dist/source/latex/base/newdc.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/newlfont.dtx b/Master/texmf-dist/source/latex/base/newlfont.dtx index 91a19196a78..3b6e001075b 100644 --- a/Master/texmf-dist/source/latex/base/newlfont.dtx +++ b/Master/texmf-dist/source/latex/base/newlfont.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/nfssfont.dtx b/Master/texmf-dist/source/latex/base/nfssfont.dtx index ce47cb85543..554c7ae8f07 100644 --- a/Master/texmf-dist/source/latex/base/nfssfont.dtx +++ b/Master/texmf-dist/source/latex/base/nfssfont.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -27,7 +27,7 @@ % % \fi \def\nfssfontfileversion{v2.2e} -\def\nfssfontfiledate{2019/10/12} +\def\nfssfontfiledate{2020/11/26} % % \iffalse @@ -55,7 +55,7 @@ % % Within the \NFSS{} distribution there is a \LaTeX{} file % \texttt{nfssfont.tex} which can be used to test new fonts, produce -% font tables showing all characters, etc. This is an addaption of a +% font tables showing all characters, etc. This is an adaption of a % program originally written by Don Knuth. % When you run this file through \LaTeX{} you will be asked to enter @@ -79,7 +79,7 @@ % |\help|. % % This is at -% the moment only a crude addaption of the test program for the +% the moment only a crude adaption of the test program for the % Computer Modern fonts by Donald Knuth. % % \StopEventually{} diff --git a/Master/texmf-dist/source/latex/base/nfssfont.ins b/Master/texmf-dist/source/latex/base/nfssfont.ins index d6760bcfde8..7d1b9cc41ae 100644 --- a/Master/texmf-dist/source/latex/base/nfssfont.ins +++ b/Master/texmf-dist/source/latex/base/nfssfont.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/olddc.ins b/Master/texmf-dist/source/latex/base/olddc.ins index 85cb077b59c..d878507d8e3 100644 --- a/Master/texmf-dist/source/latex/base/olddc.ins +++ b/Master/texmf-dist/source/latex/base/olddc.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/oldlfont.dtx b/Master/texmf-dist/source/latex/base/oldlfont.dtx index c0c14f2aa26..d04ddb6323b 100644 --- a/Master/texmf-dist/source/latex/base/oldlfont.dtx +++ b/Master/texmf-dist/source/latex/base/oldlfont.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/preload.dtx b/Master/texmf-dist/source/latex/base/preload.dtx index fd9e03ac44f..b2ca24bce5b 100644 --- a/Master/texmf-dist/source/latex/base/preload.dtx +++ b/Master/texmf-dist/source/latex/base/preload.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/proc.dtx b/Master/texmf-dist/source/latex/base/proc.dtx index 8db8fef7f10..7a1329fb82c 100644 --- a/Master/texmf-dist/source/latex/base/proc.dtx +++ b/Master/texmf-dist/source/latex/base/proc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -28,8 +28,8 @@ % \fi % % \iffalse -% Copyright (C) 1991,1992 by Leslie Lamport \and -% Copyright (C) 1994,1995 by the \LaTeX3 project \and Johannes Braams +% Copyright (C) 1991,1992 by Leslie Lamport and +% Copyright (C) 1994-2020 by the LaTeX Project and Johannes Braams % % \changes{v1.1}{1994/01/25}{Made `proc' a document class and provide % a .sty file for compatibility mode} @@ -73,7 +73,7 @@ % %<+class>\ProvidesClass{proc} %<+style>\ProvidesFile{proc.sty} - [2014/09/29 v1.3l + [2020/11/23 v1.3l %<+class> Standard LaTeX document class] %<+style> LaTeX 2.09 compatibility style option `proc'] % \end{macrocode} @@ -147,7 +147,7 @@ % % \section{Implementation} % -% In this case a check is needed to see wether \LaTeXe\ runs in +% In this case a check is needed to see whether \LaTeXe\ runs in % compatibility mode. % \changes{v1.3i}{1994/05/27}{Added missing docstrip guard} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/proc.ins b/Master/texmf-dist/source/latex/base/proc.ins index 2c419c92b94..cfed5bd6a39 100644 --- a/Master/texmf-dist/source/latex/base/proc.ins +++ b/Master/texmf-dist/source/latex/base/proc.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/slides.dtx b/Master/texmf-dist/source/latex/base/slides.dtx index 8b7276f492d..883e7d34f04 100644 --- a/Master/texmf-dist/source/latex/base/slides.dtx +++ b/Master/texmf-dist/source/latex/base/slides.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -28,7 +28,7 @@ % \fi % % \iffalse -% Copyright (C) 1994-97 LaTeX3 project, Frank Mittelbach +% Copyright (C) 1994-97 LaTeX Project, Frank Mittelbach % and Rainer Sch\"opf, all rights reserved. % % \begin{macrocode} @@ -53,7 +53,7 @@ %<*driver> \ProvidesFile{slides.drv} % - [2020/02/20 v2.4b + [2020/11/23 v2.4b %<+class> Standard LaTeX document class] %<+cmd> SLiTeX definitions] % \end{macrocode} @@ -220,7 +220,7 @@ % \end{quote} % % The code is divided into two parts, we first implement the class -% related functions and declarations and then define lowlevel stuff +% related functions and declarations and then define low level stuff % that is necessary within every class. By placing such commands into % a separate file it will be possible to share it with other slide % classes. @@ -288,7 +288,7 @@ % \end{macrocode} % % The option \Lopt{landscape} switches the values of |\paperheight| -% and |\paperwidth|, assuming the dimensions wer given for portrait +% and |\paperwidth|, assuming the dimensions were given for portrait % paper. % \begin{macrocode} \DeclareOption{landscape} @@ -705,7 +705,7 @@ % % \begin{macro}{\clubpenalty} % \begin{macro}{\widowpenalty} -% These penalties are use to discourrage club and widow lines. +% These penalties are use to discourage club and widow lines. % Because we use their default values we only show them here, % commented out. % \begin{macrocode} @@ -718,7 +718,7 @@ % \begin{macro}{\displaywidowpenalty} % \begin{macro}{\predisplaypenalty} % \begin{macro}{\postdisplaypenalty} -% Discourrage (but not so much) widows in front of a math display +% Discourage (but not so much) widows in front of a math display % and forbid breaking directly in front of a display. Allow break % after a display without a penalty. Again the default values are % used, therefore we only show them here. @@ -1721,7 +1721,7 @@ \if@titlepage \break \fi} % \end{macrocode} -% \section{Initialisation} +% \section{Initialization} % % \subsection{Date} % @@ -2348,8 +2348,8 @@ COLOR LAYER\\[.75in]% % any output when the |@visible| switch is false. % % \changes{v2.2j}{1994/03/11}{Corrected \cs{@oval}, like previous -% \changes{v2.4a}{2016/03/29}{initialise in \cs{@oval}tests added for latex/4452} -% change to \file{latex.dtx}.} +% \changes{v2.4a}{2016/03/29}{Initialize in \cs{@oval}tests added for +% latex/4452} change to \file{latex.dtx}.} % \begin{macrocode} \def\line(#1,#2)#3{\if@visible\@xarg #1\relax \@yarg #2\relax \@linelen #3\unitlength diff --git a/Master/texmf-dist/source/latex/base/slides.ins b/Master/texmf-dist/source/latex/base/slides.ins index 0eaa1eb1d7f..43ec2bebdf8 100644 --- a/Master/texmf-dist/source/latex/base/slides.ins +++ b/Master/texmf-dist/source/latex/base/slides.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -96,8 +96,8 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. @@ -138,8 +138,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/slifonts.fdd b/Master/texmf-dist/source/latex/base/slifonts.fdd index d3951cfa574..ec8b802596f 100644 --- a/Master/texmf-dist/source/latex/base/slifonts.fdd +++ b/Master/texmf-dist/source/latex/base/slifonts.fdd @@ -1,7 +1,7 @@ % \iffalse meta-comment % % Copyright 1993-2019 -% The LaTeX3 Project and any individual authors listed elsewhere +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,7 +30,7 @@ %\iffalse This is a META comment % % File `slifonts.fdd'. -% Copyright (C) 1989-1998 LaTeX3 project, Frank Mittelbach and +% Copyright (C) 1989-1998 LaTeX Project, Frank Mittelbach and % Rainer Sch\"opf, all rights reserved. % %\ProvidesFile{ot1lcmss.fd} diff --git a/Master/texmf-dist/source/latex/base/syntonly.dtx b/Master/texmf-dist/source/latex/base/syntonly.dtx index 1f7c5b651d5..b214c49ae4a 100644 --- a/Master/texmf-dist/source/latex/base/syntonly.dtx +++ b/Master/texmf-dist/source/latex/base/syntonly.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/syntonly.ins b/Master/texmf-dist/source/latex/base/syntonly.ins index c4a69c4101a..6b4113ed115 100644 --- a/Master/texmf-dist/source/latex/base/syntonly.ins +++ b/Master/texmf-dist/source/latex/base/syntonly.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 1993-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/tulm.fdd b/Master/texmf-dist/source/latex/base/tulm.fdd index 9308d801ff2..5c1566a5bad 100644 --- a/Master/texmf-dist/source/latex/base/tulm.fdd +++ b/Master/texmf-dist/source/latex/base/tulm.fdd @@ -1,7 +1,7 @@ % \iffalse meta-comment % % Copyright 2016-2019 -% The LaTeX3 Project and any individual authors listed elsewhere +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -30,7 +30,7 @@ %\iffalse This is a META comment % % File `cmfonts.fdd'. -% Copyright (C) 2016-2019 LaTeX3 Project +% Copyright (C) 2016-2019 LaTeX Project % % %\ProvidesFile{tulmr.fd} @@ -51,7 +51,7 @@ \title{The file \texttt{tulm.fdd} for use with \LaTeXe.\thanks{This file has version number \fileversion, dated \filedate.}} -\date{\filedate}\author{LaTeX3 Project} +\date{\filedate}\author{\LaTeX\ Project} \addtolength\textwidth{30pt} \begin{document} \MaintainedByLaTeXTeam{latex} diff --git a/Master/texmf-dist/source/latex/base/tulm.ins b/Master/texmf-dist/source/latex/base/tulm.ins index 9e32e39a63b..98962f2b207 100644 --- a/Master/texmf-dist/source/latex/base/tulm.ins +++ b/Master/texmf-dist/source/latex/base/tulm.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2016-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 2016-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. @@ -48,8 +48,8 @@ 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-2020 -The LaTeX3 Project and any individual authors listed elsewhere +Copyright (C) 2016-2021 +The LaTeX Project and any individual authors listed elsewhere in this file. This file was generated from file(s) of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/unpack.ins b/Master/texmf-dist/source/latex/base/unpack.ins index 3264a401d9e..6332fcb5c00 100644 --- a/Master/texmf-dist/source/latex/base/unpack.ins +++ b/Master/texmf-dist/source/latex/base/unpack.ins @@ -3,8 +3,8 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2020 -%% The LaTeX3 Project and any individual authors listed elsewhere +%% Copyright (C) 1993-2021 +%% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% %% This file is part of the LaTeX base system. diff --git a/Master/texmf-dist/source/latex/base/utf8ienc.dtx b/Master/texmf-dist/source/latex/base/utf8ienc.dtx index 8d454d1c718..79c725915c7 100644 --- a/Master/texmf-dist/source/latex/base/utf8ienc.dtx +++ b/Master/texmf-dist/source/latex/base/utf8ienc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2020 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2021 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -216,7 +216,7 @@ %<+ts1> \ProvidesFile{ts1enc.dfu} %<+x2> \ProvidesFile{x2enc.dfu} %<+all> \ProvidesFile{utf8enc.dfu} -%<-utf8-2018> [2019/11/14 v1.2k UTF-8 support for inputenc] +%<-utf8-2018> [2021/01/27 v1.2l UTF-8 support for inputenc] % \end{macrocode} % % \begin{macrocode} @@ -318,7 +318,7 @@ % However, if we are not doing typesetting, then we execute the % command \cs{UTFviii@two@octets@noexpand} which works like % \cs{UTF@two@octets@string} but uses \cs{noexpand} instead of -% \cs{string}. This way the sequence is temporay rendered harmless, +% \cs{string}. This way the sequence is temporary rendered harmless, % e.g., would display as is or stays put inside a % \cs{protected@edef}. But if the result is later reused the % starting octet is still active and so will be able to construct @@ -363,7 +363,7 @@ % \begin{macro}{\UTFviii@two@octets@noexpand} % \begin{macro}{\UTFviii@three@octets@noexpand} % \begin{macro}{\UTFviii@four@octets@noexpand} -% These tempoarily prevent the active chars from expanding. +% These temporarily prevent the active chars from expanding. % \begin{macrocode} \long\def\UTF@two@octets@noexpand#1#2{\noexpand#2\noexpand} \long\def\UTF@three@octets@noexpand#1#2#3{\noexpand#2\noexpand#3\noexpand} @@ -530,10 +530,11 @@ % % % \begin{macro}{\UTFviii@loop} -% This bit of code derived from \texttt{xmltex} defines the active character -% correspnding to starting octets to call |\UTFviii@two@octets| etc as appropriate. -% The starting octet itself is passed directly as the first argument, the others -% are picked up later en route. +% This bit of code derived from \texttt{xmltex} defines the active +% character corresponding to starting octets to call |\UTFviii@two@octets| +% etc as appropriate. +% The starting octet itself is passed directly as the first +% argument, the others are picked up later en route. % % The |\UTFviii@loop| loops through the numbers starting at % |\count@| and ending at |\@tempcnta|${} - 1$, each time executing @@ -691,7 +692,7 @@ % \end{macrocode} % % Here is an example of what is happening, for the pair \texttt{"C2 "A3} -% (which is the utf8 represenation for the character \textsterling{}). +% (which is the utf8 representation for the character \textsterling{}). % After |\parse@XML@charref| we have, stored in |\UTFviii@tmp|, a % single command with two character tokens as arguments: % \begin{quote} @@ -849,7 +850,7 @@ % % \begin{macro}{\decode@UTFviii} % \changes{v1.1o}{2015/08/28}{Macro added} -% In the reverse direction, take a sequence of octects(bytes) +% In the reverse direction, take a sequence of octets(bytes) % representing a character in UTF-8 and construct the Unicode number. % The sequence is terminated by |\relax|. % @@ -1134,9 +1135,9 @@ % % \changes{v1.1o}{2015/08/28}{Add U+00A0 and U+00AD} % \changes{v1.1q}{2015/12/02}{Add remaining latin uses of accents in T1} -% \changes{v1.1r}{2015/12/03}{Add some more ogoneck cases} +% \changes{v1.1r}{2015/12/03}{Add some more ogonek cases} % \changes{v1.1s}{2016/01/11}{Add some more caron and acute} -% \changes{v1.1t}{2017/01/28}{Add caron cominations for GgYy} +% \changes{v1.1t}{2017/01/28}{Add caron combinations for GgYy} % \begin{macrocode} %\DeclareUnicodeCharacter{00A0}{\nobreakspace} %\DeclareUnicodeCharacter{00A1}{\textexclamdown} @@ -1537,7 +1538,7 @@ % two mappings are wrong or rather the names in OT2 should change for % consistency. % -% On the other hand the names |\CYROTLD| are somewhat questionabled as the +% On the other hand the names |\CYROTLD| are somewhat questionable as the % Unicode standard only describes ``Cyrillic barred O'' while |TLD| refers % to a tilde (which is more less what the ``Cyrillic FITA looks according % to the Unicode book). @@ -1700,6 +1701,18 @@ %\DeclareUnicodeCharacter{0E3F}{\textbaht} %\DeclareUnicodeCharacter{1E02}{\.B} %\DeclareUnicodeCharacter{1E03}{\.b} +% \end{macrocode} +% \changes{v1.2k}{2021/01/27}{Added various additional dot accents (gh/484)} +% \begin{macrocode} +%\DeclareUnicodeCharacter{1E0D}{\d d} +%\DeclareUnicodeCharacter{1E25}{\d h} +%\DeclareUnicodeCharacter{1E37}{\d l} +%\DeclareUnicodeCharacter{1E43}{\d m} +%\DeclareUnicodeCharacter{1E45}{\.n} +%\DeclareUnicodeCharacter{1E47}{\d n} +%\DeclareUnicodeCharacter{1E5B}{\d r} +%\DeclareUnicodeCharacter{1E63}{\d s} +%\DeclareUnicodeCharacter{1E6D}{\d t} %\DeclareUnicodeCharacter{1E9E}{\SS} %\DeclareUnicodeCharacter{200C}{\textcompwordmark} % \end{macrocode} -- cgit v1.2.3