From b0c666dbd315af330424f5d34739d7d4134d0c17 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 2 Jun 2024 20:26:39 +0000 Subject: latex2e (2jun24) git-svn-id: svn://tug.org/texlive/trunk@71408 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/amsmath/amsbsy.ins | 2 +- Master/texmf-dist/source/latex/amsmath/amscd.dtx | 2 +- Master/texmf-dist/source/latex/amsmath/amscd.ins | 4 +- Master/texmf-dist/source/latex/amsmath/amsgen.dtx | 2 +- Master/texmf-dist/source/latex/amsmath/amsgen.ins | 2 +- Master/texmf-dist/source/latex/amsmath/amsmath.dtx | 19 +- Master/texmf-dist/source/latex/amsmath/amsmath.ins | 4 +- Master/texmf-dist/source/latex/amsmath/amsopn.dtx | 2 +- Master/texmf-dist/source/latex/amsmath/amsopn.ins | 4 +- Master/texmf-dist/source/latex/amsmath/amstext.dtx | 2 +- Master/texmf-dist/source/latex/amsmath/amstext.ins | 4 +- Master/texmf-dist/source/latex/amsmath/amsxtra.dtx | 2 +- Master/texmf-dist/source/latex/amsmath/amsxtra.ins | 4 +- Master/texmf-dist/source/latex/base/alltt.dtx | 4 +- Master/texmf-dist/source/latex/base/classes.dtx | 12 +- Master/texmf-dist/source/latex/base/doc.dtx | 227 +- Master/texmf-dist/source/latex/base/docstrip.dtx | 14 +- Master/texmf-dist/source/latex/base/fontdef.dtx | 30 +- Master/texmf-dist/source/latex/base/format.ins | 6 +- Master/texmf-dist/source/latex/base/ifthen.dtx | 29 +- Master/texmf-dist/source/latex/base/inputenc.dtx | 6 +- .../texmf-dist/source/latex/base/latexrelease.ins | 1 + Master/texmf-dist/source/latex/base/ltboxes.dtx | 42 +- Master/texmf-dist/source/latex/base/ltclass.dtx | 160 +- Master/texmf-dist/source/latex/base/ltcmd.dtx | 241 +- Master/texmf-dist/source/latex/base/ltcmdhooks.dtx | 46 +- Master/texmf-dist/source/latex/base/ltcounts.dtx | 19 +- Master/texmf-dist/source/latex/base/ltdefns.dtx | 35 +- Master/texmf-dist/source/latex/base/ltdirchk.dtx | 31 +- Master/texmf-dist/source/latex/base/ltexpl.dtx | 16 +- Master/texmf-dist/source/latex/base/ltfilehook.dtx | 34 +- Master/texmf-dist/source/latex/base/ltfiles.dtx | 57 +- Master/texmf-dist/source/latex/base/ltfinal.dtx | 6 +- Master/texmf-dist/source/latex/base/ltfloat.dtx | 6 +- Master/texmf-dist/source/latex/base/ltfntcmd.dtx | 8 +- Master/texmf-dist/source/latex/base/ltfssaxes.dtx | 10 +- Master/texmf-dist/source/latex/base/ltfssbas.dtx | 4 +- Master/texmf-dist/source/latex/base/ltfssini.dtx | 10 +- Master/texmf-dist/source/latex/base/ltfsstrc.dtx | 23 +- Master/texmf-dist/source/latex/base/lthooks.dtx | 405 +-- Master/texmf-dist/source/latex/base/ltkeys.dtx | 2 +- Master/texmf-dist/source/latex/base/ltluatex.dtx | 26 +- Master/texmf-dist/source/latex/base/ltmarks.dtx | 811 ++++-- Master/texmf-dist/source/latex/base/ltmeta.dtx | 20 +- Master/texmf-dist/source/latex/base/ltmiscen.dtx | 12 +- Master/texmf-dist/source/latex/base/ltoutenc.dtx | 25 +- Master/texmf-dist/source/latex/base/ltoutput.dtx | 4 +- Master/texmf-dist/source/latex/base/ltpara.dtx | 29 +- Master/texmf-dist/source/latex/base/ltplain.dtx | 20 +- .../texmf-dist/source/latex/base/ltproperties.dtx | 75 +- Master/texmf-dist/source/latex/base/ltsect.dtx | 10 +- Master/texmf-dist/source/latex/base/ltshipout.dtx | 32 +- Master/texmf-dist/source/latex/base/ltsockets.dtx | 36 +- Master/texmf-dist/source/latex/base/ltspace.dtx | 12 +- Master/texmf-dist/source/latex/base/lttagging.dtx | 775 ++++++ .../texmf-dist/source/latex/base/lttemplates.dtx | 2634 ++++++++++++++++++++ Master/texmf-dist/source/latex/base/lttextcomp.dtx | 688 ++++- Master/texmf-dist/source/latex/base/ltthm.dtx | 38 +- Master/texmf-dist/source/latex/base/ltvers.dtx | 4 +- Master/texmf-dist/source/latex/base/ltxdoc.dtx | 9 +- Master/texmf-dist/source/latex/base/nfssfont.dtx | 6 +- Master/texmf-dist/source/latex/base/slifonts.fdd | 6 +- Master/texmf-dist/source/latex/base/syntonly.dtx | 6 +- Master/texmf-dist/source/latex/base/utf8ienc.dtx | 5 +- .../texmf-dist/source/latex/cyrillic/cyoutenc.dtx | 11 +- .../texmf-dist/source/latex/firstaid/firstaid.ins | 4 +- .../latex2e-first-aid-for-external-files.dtx | 92 +- Master/texmf-dist/source/latex/graphics/color.dtx | 34 +- .../texmf-dist/source/latex/graphics/drivers.dtx | 2 +- Master/texmf-dist/source/latex/graphics/epsfig.dtx | 8 +- .../texmf-dist/source/latex/graphics/graphics.dtx | 74 +- .../texmf-dist/source/latex/graphics/graphicx.dtx | 2 +- Master/texmf-dist/source/latex/graphics/keyval.dtx | 2 +- Master/texmf-dist/source/latex/graphics/lscape.dtx | 2 +- .../texmf-dist/source/latex/graphics/rotating.dtx | 2 +- Master/texmf-dist/source/latex/graphics/trig.dtx | 6 +- .../latex/latex-lab/documentmetadata-support.dtx | 136 +- .../source/latex/latex-lab/latex-lab-amsmath.dtx | 122 +- .../source/latex/latex-lab/latex-lab-bib.dtx | 19 +- .../source/latex/latex-lab/latex-lab-block.dtx | 187 +- .../source/latex/latex-lab/latex-lab-firstaid.dtx | 194 +- .../source/latex/latex-lab/latex-lab-float.dtx | 77 +- .../source/latex/latex-lab/latex-lab-footnotes.dtx | 90 +- .../source/latex/latex-lab/latex-lab-graphic.dtx | 20 +- .../source/latex/latex-lab/latex-lab-marginpar.dtx | 259 ++ .../source/latex/latex-lab/latex-lab-math.dtx | 1561 +++++++++--- .../source/latex/latex-lab/latex-lab-mathpkg.dtx | 35 +- .../source/latex/latex-lab/latex-lab-mathtools.dtx | 15 +- .../source/latex/latex-lab/latex-lab-minipage.dtx | 4 +- .../source/latex/latex-lab/latex-lab-namespace.dtx | 23 +- .../source/latex/latex-lab/latex-lab-new-or-1.dtx | 2 +- .../source/latex/latex-lab/latex-lab-new-or-2.dtx | 2 +- .../source/latex/latex-lab/latex-lab-sec.dtx | 17 +- .../source/latex/latex-lab/latex-lab-table.dtx | 1350 +++------- .../source/latex/latex-lab/latex-lab-testphase.dtx | 9 +- .../source/latex/latex-lab/latex-lab-text.dtx | 2 +- .../source/latex/latex-lab/latex-lab-title.dtx | 518 ++++ .../latex-lab/latex-lab-toc-hyperref-changes.dtx | 2 +- .../latex-lab/latex-lab-toc-kernel-changes.dtx | 8 +- .../source/latex/latex-lab/latex-lab-toc.dtx | 10 +- .../source/latex/latex-lab/latex-lab.ins | 8 + Master/texmf-dist/source/latex/tools/afterpage.dtx | 2 +- Master/texmf-dist/source/latex/tools/afterpage.ins | 4 +- Master/texmf-dist/source/latex/tools/array.dtx | 480 +++- Master/texmf-dist/source/latex/tools/bm.dtx | 10 +- Master/texmf-dist/source/latex/tools/bm.ins | 4 +- Master/texmf-dist/source/latex/tools/calc.dtx | 2 +- Master/texmf-dist/source/latex/tools/dcolumn.dtx | 2 +- Master/texmf-dist/source/latex/tools/delarray.dtx | 2 +- Master/texmf-dist/source/latex/tools/enumerate.dtx | 2 +- Master/texmf-dist/source/latex/tools/fileerr.dtx | 2 +- Master/texmf-dist/source/latex/tools/fontsmpl.dtx | 2 +- Master/texmf-dist/source/latex/tools/ftnright.dtx | 2 +- Master/texmf-dist/source/latex/tools/hhline.dtx | 2 +- .../texmf-dist/source/latex/tools/indentfirst.dtx | 2 +- .../texmf-dist/source/latex/tools/l3sys-query.dtx | 545 ++++ .../texmf-dist/source/latex/tools/l3sys-query.ins | 76 + Master/texmf-dist/source/latex/tools/layout.dtx | 2 +- Master/texmf-dist/source/latex/tools/longtable.dtx | 371 ++- Master/texmf-dist/source/latex/tools/longtable.ins | 4 +- Master/texmf-dist/source/latex/tools/multicol.dtx | 72 +- Master/texmf-dist/source/latex/tools/multicol.ins | 4 +- Master/texmf-dist/source/latex/tools/rawfonts.dtx | 2 +- Master/texmf-dist/source/latex/tools/shellesc.dtx | 2 +- Master/texmf-dist/source/latex/tools/showkeys.dtx | 15 +- Master/texmf-dist/source/latex/tools/somedefs.dtx | 2 +- Master/texmf-dist/source/latex/tools/tabularx.dtx | 51 +- Master/texmf-dist/source/latex/tools/tabularx.ins | 4 +- Master/texmf-dist/source/latex/tools/theorem.dtx | 2 +- Master/texmf-dist/source/latex/tools/tools.ins | 11 +- Master/texmf-dist/source/latex/tools/trace.dtx | 2 +- Master/texmf-dist/source/latex/tools/varioref.dtx | 96 +- Master/texmf-dist/source/latex/tools/varioref.ins | 4 +- Master/texmf-dist/source/latex/tools/verbatim.dtx | 15 +- Master/texmf-dist/source/latex/tools/xr.dtx | 231 +- Master/texmf-dist/source/latex/tools/xspace.dtx | 2 +- 136 files changed, 11006 insertions(+), 2754 deletions(-) create mode 100644 Master/texmf-dist/source/latex/base/lttagging.dtx create mode 100644 Master/texmf-dist/source/latex/base/lttemplates.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx create mode 100644 Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx create mode 100644 Master/texmf-dist/source/latex/tools/l3sys-query.dtx create mode 100644 Master/texmf-dist/source/latex/tools/l3sys-query.ins (limited to 'Master/texmf-dist/source/latex') diff --git a/Master/texmf-dist/source/latex/amsmath/amsbsy.ins b/Master/texmf-dist/source/latex/amsmath/amsbsy.ins index 62b4e9a67c7..2d0cdd7be32 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsbsy.ins +++ b/Master/texmf-dist/source/latex/amsmath/amsbsy.ins @@ -26,7 +26,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amscd.dtx b/Master/texmf-dist/source/latex/amsmath/amscd.dtx index 85475708cc3..e1eba3aec28 100644 --- a/Master/texmf-dist/source/latex/amsmath/amscd.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amscd.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 1999 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amscd.ins b/Master/texmf-dist/source/latex/amsmath/amscd.ins index 56aedca3757..8f2e5decd42 100644 --- a/Master/texmf-dist/source/latex/amsmath/amscd.ins +++ b/Master/texmf-dist/source/latex/amsmath/amscd.ins @@ -1,6 +1,6 @@ %% %% Copyright (C) 2010 American Mathematical Society. -%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsgen.dtx b/Master/texmf-dist/source/latex/amsmath/amsgen.dtx index 6c4aefed671..a7b1ebc87f3 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsgen.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amsgen.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 1999 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsgen.ins b/Master/texmf-dist/source/latex/amsmath/amsgen.ins index faef4aa275b..8b6f4185955 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsgen.ins +++ b/Master/texmf-dist/source/latex/amsmath/amsgen.ins @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsmath.dtx b/Master/texmf-dist/source/latex/amsmath/amsmath.dtx index bf8aa418df8..ec44957a89e 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsmath.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amsmath.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 2000, 2013 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c @@ -76,17 +76,16 @@ Bug reports can be opened (category \texttt{#1}) at\\% [1994/12/01]% LaTeX date must be December 1994 or later % \end{macrocode} % -% Providing a rollback to earlier version(s) +% Providing a rollback to earlier version(s). Anything prior to +% 2018 we attempt to fulfill by using the version from 2018. % \begin{macrocode} -\providecommand\DeclareRelease[3]{} -\providecommand\DeclareCurrentRelease[2]{} -% +\DeclareRelease{}{1994-06-01}{amsmath-2018-12-01.sty} \DeclareRelease{}{2018-12-01}{amsmath-2018-12-01.sty} \DeclareCurrentRelease{}{2019-04-01} % \end{macrocode} % % \begin{macrocode} -\ProvidesPackage{amsmath}[2023/05/13 v2.17o AMS math features] +\ProvidesPackage{amsmath}[2024/05/23 v2.17q AMS math features] % \end{macrocode} % % \section{Catcode defenses} @@ -1162,7 +1161,7 @@ Foreign command \@backslashchar#1;\MessageBreak % \begin{macrocode} \@xp\Umathch@\meaning@"0"\Umathch@ \ifgtest@ % if \Umathchar - \else % else not \Umathcar + \else % else not \Umathchar % \end{macrocode} % \begin{macrocode} \@xp\macro@\meaning@@\macro@ @@ -4153,6 +4152,12 @@ and fix things up.} % cause \cs{row@} to be advanced twice instead of once. % \begin{macrocode} \global\advance\row@\@ne +% \end{macrocode} +% Also reset \cs{lineht@} to avoid that this is incorrectly picked +% up by a following environment, such as \env{align}. +% \changes{v2.17p}{2024/03/11}{Reset \cs{lineht@} (gh/1289)} +% \begin{macrocode} + \global\lineht@\z@ \cr } % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/amsmath/amsmath.ins b/Master/texmf-dist/source/latex/amsmath/amsmath.ins index f92839f959c..528700f238e 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsmath.ins +++ b/Master/texmf-dist/source/latex/amsmath/amsmath.ins @@ -1,6 +1,6 @@ %% %% Copyright (C) 2010 American Mathematical Society. -%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999, 2000, 2013 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsopn.dtx b/Master/texmf-dist/source/latex/amsmath/amsopn.dtx index b089749c170..11ad62ddc1f 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsopn.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amsopn.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 1999 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsopn.ins b/Master/texmf-dist/source/latex/amsmath/amsopn.ins index 859e3d7e5ad..67b2b3c077e 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsopn.ins +++ b/Master/texmf-dist/source/latex/amsmath/amsopn.ins @@ -1,6 +1,6 @@ %% %% Copyright (C) 2010 American Mathematical Society. -%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amstext.dtx b/Master/texmf-dist/source/latex/amsmath/amstext.dtx index a4bc541d349..68299946b07 100644 --- a/Master/texmf-dist/source/latex/amsmath/amstext.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amstext.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 1999 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amstext.ins b/Master/texmf-dist/source/latex/amsmath/amstext.ins index 11ed56cc3c9..8ecb9523c9e 100644 --- a/Master/texmf-dist/source/latex/amsmath/amstext.ins +++ b/Master/texmf-dist/source/latex/amsmath/amstext.ins @@ -1,6 +1,6 @@ %% %% Copyright (C) 2010 American Mathematical Society. -%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx b/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx index a1f2c6686c3..5ace38995da 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx +++ b/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx @@ -2,7 +2,7 @@ % \iffalse meta-comment % % Copyright (C) 1995, 1999 American Mathematical Society. -% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/amsmath/amsxtra.ins b/Master/texmf-dist/source/latex/amsmath/amsxtra.ins index 47072225138..2ba4f221386 100644 --- a/Master/texmf-dist/source/latex/amsmath/amsxtra.ins +++ b/Master/texmf-dist/source/latex/amsmath/amsxtra.ins @@ -1,6 +1,6 @@ %% %% Copyright (C) 2010 American Mathematical Society. -%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c @@ -25,7 +25,7 @@ \preamble Copyright (C) 1995, 1999 American Mathematical Society. -Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society. +Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society. This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/latex/base/alltt.dtx b/Master/texmf-dist/source/latex/base/alltt.dtx index c7e20ba52d1..4718c004b40 100644 --- a/Master/texmf-dist/source/latex/base/alltt.dtx +++ b/Master/texmf-dist/source/latex/base/alltt.dtx @@ -40,7 +40,7 @@ %\ProvidesPackage{alltt} %\ProvidesFile{alltt.drv} %\ProvidesFile{alltt.dtx} - [2021/01/29 v2.0g defines alltt environment] + [2024/02/08 v2.0g defines alltt environment] % %<*driver> \documentclass{ltxdoc} @@ -97,7 +97,7 @@ % \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 +% be surprised when you switch to italics, because those fonts have % a different set of glyphs: % \begin{alltt} % The glyph at the position of the $ in a slanted font: \textsl{$}. diff --git a/Master/texmf-dist/source/latex/base/classes.dtx b/Master/texmf-dist/source/latex/base/classes.dtx index 688380e3e19..f7c53f0f719 100644 --- a/Master/texmf-dist/source/latex/base/classes.dtx +++ b/Master/texmf-dist/source/latex/base/classes.dtx @@ -53,7 +53,7 @@ %<*driver> \ProvidesFile{classes.drv} % - [2023/05/17 v1.4n + [2024/02/08 v1.4n % Standard LaTeX document class] %<10pt|11pt|12pt> Standard LaTeX file (size option)] % \end{macrocode} @@ -1882,7 +1882,7 @@ % \changes{v1.3a}{1995/05/17}{Use \cs{@makefnmark} in definition of % \cs{@makefntext}} % \changes{v1.3g}{1995/06/26}{Fix definition of \cs{@makefnmark} and -% \cs{@makefntext} to a) work and b) without using math} +% \cs{@makefntext} to (a) work and (b) without using math} % \begin{macrocode} \else \newcommand\maketitle{\par @@ -2002,7 +2002,7 @@ % `section'. % \item[\meta{level}] A number, denoting the depth of the section % -- e.g., chapter=1, section = 2, etc. A section number -% will be printed if and only if \meta{level} $<=$ the value +% will be printed if and only if \meta{level} $\leq$ the value % of the \Lcount{secnumdepth} counter. % \item[\meta{indent}] The indentation of the heading from the left % margin @@ -3068,7 +3068,7 @@ % list environment's parameters. The user types |\\| to end a line. % This is implemented by |\let|'ing |\\| equal |\@centercr|. % -% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with +% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with ^^A ] % \cs{relax}} % \begin{macrocode} \newenvironment{verse} @@ -3091,7 +3091,7 @@ % are set smaller than |\textwidth|. The first line of a paragraph % inside this environment is indented. % -% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with +% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with ^^A ] % \cs{relax}} % \begin{macrocode} \newenvironment{quotation} @@ -3110,7 +3110,7 @@ % The quote environment is like the quotation environment except % that paragraphs are not indented. % -% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with +% \changes{v1.3j}{1995/08/16}{stop \cs{item} scanning for [ with ^^A ] % \cs{relax}} % \begin{macrocode} \newenvironment{quote} diff --git a/Master/texmf-dist/source/latex/base/doc.dtx b/Master/texmf-dist/source/latex/base/doc.dtx index 8b48f59d6a6..946f187389f 100644 --- a/Master/texmf-dist/source/latex/base/doc.dtx +++ b/Master/texmf-dist/source/latex/base/doc.dtx @@ -34,9 +34,9 @@ %\catcode`\<=14 %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01] %<+package> -%<+package>\providecommand\DeclareRelease[3]{} -%<+package>\providecommand\DeclareCurrentRelease[2]{} -%<+package> +% Any rollback request before 2016-02-15 we try to fullfil with the 2016 version: +%<+package>\DeclareRelease{}{1994-06-01} +%<+package> {doc-2016-02-15.sty} %<+package>\DeclareRelease{v2.1g}{2016-02-15} %<+package> {doc-2016-02-15.sty} %<+package>\DeclareRelease{v2}{2021-06-01} @@ -45,7 +45,7 @@ %<+package> %<+package>\ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2022/11/13 v3.0m +%<+package|shortvrb> [2024/04/26 v3.0p %<+package|shortvrb> Standard LaTeX documentation package V3 (FMi)] %\catcode`\<=12 % @@ -57,7 +57,7 @@ % % %% Package `doc' to use with LaTeX 2e -%% Copyright (C) 1989-2022 Frank Mittelbach, all rights reserved. +%% Copyright (C) 1989-2023 Frank Mittelbach, all rights reserved. % % % Version: Date: Changes: @@ -143,8 +143,8 @@ % \MakeShortVerb{\|} % \setcounter{StandardModuleDepth}{1} % -% {\catcode`\p=12 \catcode`\t=12 ^^A hack used later on to print -% \gdef\dimenvalue#1pt{$#1$pt}} ^^A a register value with a - sign +% {\catcode`\p=12 \catcode`\t=12 ^^A hack used later on to print a +% \gdef\dimenvalue#1pt{$#1$pt}} ^^A register value with a - sign % % \newcommand{\DOC}{\texttt{doc}\xspace} % @@ -167,7 +167,7 @@ %\RenewDocElement[macrolike = true , % toplevel = false, % idxtype = , -% idxgroup = LaTeX comands\actualchar\LaTeX{} commands , +% idxgroup = LaTeX commands\actualchar\LaTeX{} commands , % printtype = % ]{Macro}{macro} % @@ -237,7 +237,7 @@ % \changes{v1.9t}{1995/05/11}{Use \cs{GetFileInfo}} % \GetFileInfo{doc.sty} % -% \CheckSum{0} ^^A % keep the checksum in this file but not now :-) +% \CheckSum{0} % % \title{The \DOC{} and \texttt{shortvrb} Packages\thanks % {This file has version number \fileversion{} dated \filedate{}.}} @@ -595,7 +595,16 @@ % class file (like \texttt{ltugboat.cls}) use the |\DocstyleParms| % command described below. Starting with release 2.0a it can now % be changed directly as long as the redefinition happens before -% the |\begin{document}|. +% the |\begin{document}| (if you change it later you might see strange +% typesetting effects if you are unlucky). +% +% |\MacroFont| does not alter the font of +% |\verb| or |\verb*| because it is often used to make the font size of +% the code displays smaller, which would look odd if used within a +% paragraph. If you decide to use a different font family and want to +% use the same family with +% |\verb| you need to alter the font setup for |\ttfamily| in addition +% to |\MacroFont|. % % \DescribeEnv{environment} % For documenting the definition of environments one can use the @@ -695,6 +704,12 @@ % |\NewDocElement{Env}{environment}| % though that's not quite what has been done, as we will see later. % +% \DescribeInterfaceMacro{\ProvideDocElement} +% This declaration does nothing when the doc element is already +% declared, otherwise it works like \cs{NewDocElement}. It can be +% useful if you have many documentation files that you may want to +% process individually as well as together. +% % \DescribeOption[noprint]{macrolike} % \DescribeOption[noprint]{envlike} % \DescribeOption[noprint]{toplevel} @@ -1367,7 +1382,7 @@ %\RenewDocElement[macrolike = true , % toplevel = false, % idxtype = , -% idxgroup = LaTeX comands\actualchar\LaTeX{} commands , +% idxgroup = LaTeX commands\actualchar\LaTeX{} commands , % printtype = % ]{Macro}{macro} %\end{verbatim} @@ -1515,7 +1530,7 @@ % % Thirty years is a long time in the life of computer programs, so % there are a good number of interfaces within \DOC that are really -% only of historical interest (or when processing equally old sources. +% only of historical interest (or when processing equally old sources). % We list them here, but in general we suggest that for new % documentation they should not be used. % @@ -2108,9 +2123,12 @@ % that is, they must be given |\catcode| $12$. % \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, % which handles more ligatures.} +% \changes{v3.0o}{2023/12/30}{Use \cs{@noligs} from the \LaTeX\ +% kernel, so that the \texttt{upquote} package can +% add its patch (gh/1230)} % \begin{macrocode} \obeylines - \let\do\do@noligs \verbatim@nolig@list + \@noligs \let\do\@makeother \dospecials % \end{macrocode} % \changes{v1.5t}{1989/11/07}{Common code added.} @@ -2183,7 +2201,7 @@ % \changes{v1.7a}{1992/03/13}{Added \cs{reset@font} for NFSS.} % \changes{v1.8c}{1993/10/25}{NFSS standard} % \changes{v1.9t}{1995/05/26}{Removed \cs{math@fontsfalse} (different -% math setup /pr1622} +% math setup /pr1622)} % \begin{macrocode} \@ifundefined{MacroFont}{% \if@compatibility @@ -2220,7 +2238,7 @@ % \changes{v1.7m}{1992/10/11}{Use sltt as default.} % \changes{v1.8c}{1993/10/25}{NFSS standard} % \changes{v1.9t}{1995/05/26}{Removed \cs{math@fontsfalse} (different -% math setup /pr1622} +% math setup /pr1622)} % Although most of the macro code is set in |\MacroFont| we want to be % able to switch to indicate module code set in |\AltMacroFont|. % |\macro@font| keeps track of which one we're using. We can't do the @@ -2681,7 +2699,7 @@ % \end{macrocode} % % \changes{v2.1j}{2019/11/03}{Kernel now sets up \cs{verbvisiblespace} (gh/205)} -% \changes{v2.1k}{2019/11/10}{Put the definition into the right command :-( (gh/205)} +% \changes{v2.1k}{2019/11/10}{Put the definition into the right command (gh/205)} % \begin{macrocode} \@setupverbvisiblespace \MacroFont \@vobeyspaces \@sxverbatim} @@ -2895,32 +2913,32 @@ % following tasks: % \begin{itemize} % \parindent4em -% \item[1)] +% \item[(1)] % |\catcode| all characters used in macro names to -% 11 (i.e.\ `letter'). -% \item[2)] +% 11 (i.e., `letter'). +% \item[(2)] % |\catcode| the `|\|' character to 13 -% (i.e.\ `active'). -% \item[3a)] +% (i.e., `active'). +% \item[(3a)] % |\let| the `|\|' equal |\scan@macro| -% (i.e.\ start the macro scanning mechanism) if there is -% no special escape character (i.e.\ the +% (i.e., start the macro scanning mechanism) if there is +% no special escape character (i.e., the % |\special@escape@char| is `|\|'). -% \item[3b)] +% \item[(3b)] % Otherwise |\let| it equal |\bslash|, i.e.\ % produce a printable |\|. -% \item[4)] +% \item[(4)] % Make the \meta{special escape character} active. -% \item[5)] +% \item[(5)] % |\let| the active version of the special escape % character -% (i.e.\ the expansion of |\active@escape@char|) equal +% (i.e., the expansion of |\active@escape@char|) equal % |\scan@macro|. % \end{itemize} % The reader might ask why we bother to |\catcode| the % `|\|' first to 12 (at the end of |\macro@code|) then % re-|\catcode| it to 13 in order to produce a $|\|_{12}$ -% in case 3b) above. This is done because we have to ensure that +% in case (3b) above. This is done because we have to ensure that % `|\|' has |\catcode| 13 within the \env{macrocode} % environment. Otherwise the delimiter for the argument of % |\xmacro@code| would not be found (parameter matching @@ -2930,14 +2948,14 @@ % \begin{macrocode} \begingroup \catcode`\|=\z@ \catcode`\\=\active % \end{macrocode} -% We carry out tasks 2) and 3b) first. +% We carry out tasks (2) and (3b) first. % \SpecialEscapechar\| % \begin{macrocode} |gdef|init@crossref{|catcode`|\|active |let\|bslash % \end{macrocode} % Because of the popularity of the `|@|' character as a % `letter' in macros, we normally have to change its -% |\catcode| here, and thus fulfill task 1). But the macro +% |\catcode| here, and thus fulfill task (1). But the macro % designer might use other characters as private letters as well, % so we use a macro to do the |\catcode| switching. % \SpecialEscapechar\| @@ -2945,8 +2963,8 @@ |MakePrivateLetters % \end{macrocode} % Now we |\catcode| the special escape character to 13 and -% |\let| it equal |\scan@macro|, i.e.\ fulfill tasks 4) -% and 5). Note the use of |\expandafter| to insert the chosen +% |\let| it equal |\scan@macro|, i.e., fulfill tasks (4) +% and (5). Note the use of |\expandafter| to insert the chosen % escape character saved in |\special@escape@char| and % |\active@escape@char|. % \SpecialEscapechar\| @@ -2955,7 +2973,7 @@ |expandafter|let|active@escape@char|scan@macro} |endgroup % \end{macrocode} -% If there is no special escape character, i.e.\ if +% If there is no special escape character, i.e., if % |\SpecialEscapechar| is |\\|, the second last line will % overwrite the previous definition of $|\|_{13}$. In this % way all tasks are fulfilled. @@ -3109,9 +3127,9 @@ % done by the |\ifnot@excluded| macro which assumes that the % macro name is saved in |\macro@namepart|. The character % mustn't be stored with a special category code or exclusion from -% the index won't work, so we we use \cs{string} to normalize it -% the same way it is done in \cs{DoNotIndex}, i.e. everything ends up catcode 12 -% except for the space character. +% the index won't work, so we use \cs{string} to normalize it +% the same way it is done in \cs{DoNotIndex}, i.e. everything ends up +% catcode 12 except for the space character. % \changes{v2.0e}{1998/12/28}{Correctly use the case-changing trick.} % \changes{v3.0l}{2022/11/03}{No longer using the case-changing trick.} % \begin{macrocode} @@ -3254,7 +3272,7 @@ % unnecessarily index within that part of the code. As the sequence % is local it will revert this setting at the end of the % environment so that the command is indexed elsewhere (unless it -% is generally disabled from indexing. +% is generally disabled from indexing). % % \DescribeMacro\g__doc_idxtype_prop % Global property list that holds for all commands that are special @@ -3282,7 +3300,7 @@ % \DescribeInterfaceMacro\RecordIndexType % This command takes two arguments: a command (with escape char) % and its type (i.e., first mandatory -% argument of a |\NewDocElement| declaration. If |#1| should not be +% argument of a |\NewDocElement| declaration). If |#1| should not be % included from the index, then the data is used to record that % this command is of this type. The information is then used to % generate appropriate index entries. Obviously, index entries @@ -3481,7 +3499,7 @@ % \begin{macro}{\__doc_idxtype_put:nn} % This internal command takes two arguments: a command name as % string (no backslash) and its type (i.e., first mandatory -% argument of a |\NewDocElement| declaration. If |#1| is not in +% argument of a |\NewDocElement| declaration). If |#1| is not in % |\l__doc_donotindex_seq| it will add this data to the property % list |\g__doc_idxtype_prop| using |#1| as key and |#2| as its % value. If the key already exist its value will be overwritten. If @@ -3884,7 +3902,8 @@ % \begin{imacro}{\RightBraceIndex} % \changes{v1.5s}{1989/11/05}{Support for code line no. (Undoc)} These % two macros fix the problems with \prg{makeindex}. Note the -% `hack' with |\iffalse}\fi| to satisfy both \TeX{} and the +% `hack' with \iffalse{-to get matching braces\fi |\iffalse}\fi| +% to satisfy both \TeX{} and the % \prg{makeindex} program. When this is written to the % \texttt{.idx} file \TeX{} will see both braces (so we get a % balanced text). \prg{makeindex} will also see balanced braces @@ -5539,7 +5558,7 @@ % \begin{macrocode} \long\def\@doc@env#1#2#3{ % \end{macrocode} -% The |\endgroup| here closes the scanning of names (using special catcodes. +% The |\endgroup| here closes the scanning of names (using special catcodes). % \begin{macrocode} \endgroup \clist_map_inline:nn {#3} { \@doc@env@{#1}{#2}{##1} } @@ -5565,8 +5584,8 @@ % they are technically part of the generated API, only not meant for public % use. % -% \fmi{above docu is no longer right (but code needs further changes -% anyway} +% \fmi{above docu is no longer right (but code probably needs further changes +% anyway)} % % |#1| is either \texttt{TT} (for true = macrolike) or \texttt{TF}. % If true then we drop the first char from |\saved@macroname| and @@ -5580,7 +5599,7 @@ % If the \DOC element described is macrolike but not a normal % ``macro'' then its type should be recorded and this is the places % where this happens. For macros (which should make up the bulk of -% these items we don't do this and for anything else that looks +% these items) we don't do this and for anything else that looks % from an indexing perspective like a macro we don't do that either % to keep the list of exceptions small. That would be the case if % the indexing command |\Code|\meta{doc-element}|Index| is @@ -5635,7 +5654,7 @@ \fi % \end{macrocode} % Suppress further |\index| entries when we are within a -% \texttt{macrolike} environment. (There is no point doing that for +% \texttt{macrolike} environment. There is no point doing that for % non-\texttt{macrolike} environments are index entries are only % generated for items starting with a backslash anyway. % \fmi{fix} @@ -5940,6 +5959,16 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\doc@ignoredinfo} +% +% \begin{macrocode} +\def\doc@ignoredinfo#1#2{% + \PackageInfo{doc}{Doc element '#1/#2' declaration + ignored}% +} +% \end{macrocode} +% \end{macro} +% % % \begin{imacro}{\NewDocElement} % \oarg{options}\marg{name}\marg{envname} @@ -5963,6 +5992,30 @@ % \end{macrocode} % \end{imacro} % +% \begin{imacro}{\ProvideDocElement} +% \oarg{options}\marg{name}\marg{envname} +% This does nothing unless the doc element could be declared with +% \cs{NewDocElement}. +% \begin{macrocode} +\newcommand\ProvideDocElement[3][]{% +% \end{macrocode} +% +% \begin{macrocode} + \@ifundefined{Print#2Name}% + {\@ifundefined{PrintDescribe#2}% + {\@ifundefined{#3}% + {\@ifundefined{end#3}% + {\@NewDocElement{#1}}% + \doc@ignoredinfo + }\doc@ignoredinfo + }\doc@ignoredinfo + }\doc@ignoredinfo + {#2}{#3}% +} +% \end{macrocode} +% \end{imacro} +% +% % \begin{imacro}{\RenewDocElement} % \oarg{options}\marg{name}\marg{envname} % @@ -6098,7 +6151,7 @@ % \end{macrocode} -% \begin{macro}{SpecialMainIndex} +% \begin{macro}{\SpecialMainIndex} % % In \DOC v2 we had \cs{SpecialMainIndex} and % \cs{SpecialMainEnvIndex} but now with additional \DOC elements we @@ -6110,7 +6163,7 @@ % \end{macrocode} % \end{macro} -% \begin{macro}{SpecialUsageIndex} +% \begin{macro}{\SpecialUsageIndex} % \DOC v2 also had \cs{SpecialUsageIndex} which is now called % \cs{SpecialMacroIndex} generating the ``usage'' index entry for % a macro. Again we provide that as an alias via |\def|. @@ -6206,86 +6259,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% \section{Code no longer used} -% -% \begin{imacro}{\verb} -% \changes{v1.7a}{1992/02/27}{Now warns about newlines (from -% newdoc with `@noligs added).} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX \cs{verb}} -% We re-define |\verb| to check for newlines in its argument since a -% missing delimiter is difficult to detect in \DOC{} source. -% The code is the same as in \texttt{latex.tex} of September 19, 1993. -% Perhaps there should be a font-changing -% hook rather than just using |\ttfamily|, but if so it probably should be -% different from |\MacroFont| since that normally includes |\small| -% and would look wrong inline. -% \changes{v1.7a}{1992/02/28}{Added math mode check (from verbatim.sty)} -% \begin{macrocode} -%\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi -% \bgroup \let\do\do@noligs \verbatim@nolig@list -% \ttfamily \verb@eol@error \let\do\@makeother \dospecials -% \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}} -% \end{macrocode} -% \end{imacro} -% -% \begin{macro}{\verb@balance@group} -% \begin{macro}{\verb@egroup} -% \begin{macro}{\verb@eol@error} -% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb@err} to -% \cs{verb@eol@error}, as in new LaTeX verbatim.} -% \begin{macrocode} -%\let\verb@balance@group\@empty -% \end{macrocode} -% -% \begin{macrocode} -%\def\verb@egroup{\global\let\verb@balance@group\@empty\egroup} -% \end{macrocode} -% -% \begin{macrocode} -%\begingroup -% \obeylines% -% \gdef\verb@eol@error{\obeylines% -% \def^^M{\verb@egroup\@latex@error{% -% \noexpand\verb command ended by end of line}\@ehc}}% -%\endgroup -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@sverb} -% \changes{v1.7a}{1992/02/27}{Added for \cs{verb} change.} -% \changes{v1.7a}{1992/02/28}{Now same as in verbatim.sty.} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, -% which has better error trapping.} -% See \cite{art:verbatim} for commentary. -% \changes{v2.1j}{2019/11/03}{Use the kernel definition, no change needed (gh/205)} -% \begin{macrocode} -%\def\@sverb#1{% -% \catcode`#1\active \lccode`\~`#1% -% \gdef\verb@balance@group{\verb@egroup -% \@latex@error{Illegal use of \noexpand\verb command}\@ehc}% -% \aftergroup\verb@balance@group -% \lowercase{\let~\verb@egroup}} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\verbatim@nolig@list} -% \begin{macro}{\do@noligs} -% These macros replace the old |\@noligs| mechanism by an -% extensible version to allow more ligatures to be added. -% \begin{macrocode} -%\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-} -%\def\do@noligs#1{% -% \catcode`#1\active -% \begingroup -% \lccode`\~`#1\relax -% \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}} -% \end{macrocode} -% \end{macro} -% \end{macro} - ^^A Needed for emacs ^^A diff --git a/Master/texmf-dist/source/latex/base/docstrip.dtx b/Master/texmf-dist/source/latex/base/docstrip.dtx index 9677fdad61f..d5366b3fddf 100644 --- a/Master/texmf-dist/source/latex/base/docstrip.dtx +++ b/Master/texmf-dist/source/latex/base/docstrip.dtx @@ -31,7 +31,7 @@ \def\filename{docstrip.dtx} \def\fileversion{v2.6b} \def\filedate{2022-09-03} -\def\docdate {2023-10-10} +\def\docdate {2024-02-08} %% % %\iffalse @@ -450,7 +450,7 @@ % \DescribeMacro{\endbatchfile} % All batch files should end with this command. Any lines after this % in the file are ignored. In old files that start -% |\def\batchfile{|\ldots\ this command is optional, but is a good +% |\def\batchfile{|\ldots\ \iffalse}\fi this command is optional, but is a good % idea anyway. If this command is omitted from a batchfile then % normally \TeX\ will go to its interactive |*| prompt, so you may % stop \ds{} by typing |\endbatchfile| to this prompt. @@ -757,7 +757,7 @@ % \meta{Primary}]*\\ % \meta{Primary} & $::=$ & % \meta{Terminal} $|$ \texttt{!}\meta{Primary} -% $|$ \texttt{(}\meta{Expression}\texttt{)}\\ +% $|$ \texttt(\meta{Expression}\texttt)\\ % \end{tabular} % % The \texttt{|} stands for disjunction, the \texttt{\&} stands for @@ -1712,7 +1712,7 @@ Z % \end{macrocode} % % \begin{macro}{\quote@name} -% \changes{v2.5h}{2020/04/18}{Macro added gfh/221)} +% \changes{v2.5h}{2020/04/18}{Macro added (gh/221)} % A macro copied from \texttt{ltfiles.dtx} in order to be able to % allow spaces in filenames. % \begin{macrocode} @@ -1994,7 +1994,7 @@ Z % \meta{Primary} & $::=$ & % \meta{Terminal} $|$ \texttt{!}\meta{Primary} % $|$ -% \texttt{(}\meta{Expression}\texttt{)}\\ +% \texttt(\meta{Expression}\texttt)\\ % \end{tabular} % % The \texttt{|} stands for disjunction, the \texttt{\&} stands for @@ -2023,7 +2023,7 @@ Z % \begin{eqnarray*} % \tau(\meta{Terminal})&=&"\t@,#1,,\qStop"\\ % \tau(!\meta{Primary})&=&"\if1"\,\tau(\meta{Primary})\,"0\else1\fi"\\ -% \tau(\mbox{\texttt{(}\meta{Expression}\texttt{)}}) +% \tau(\mbox{\texttt(\meta{Expression}\texttt)}) % &=&\tau(\meta{Expression})\\ % \tau(\mbox{\meta{Primary}\texttt{\&}\meta{Secondary}}) % &=&"\if0"\,\tau(\meta{Primary})\,"0\else" @@ -4473,7 +4473,7 @@ for copying and modification in the file \inFileName. % {Macro added (DPC)} % Process the batch file, and then terminate cleanly. % This may be set to |\relax| for `new style' batch files that -% do not start with |\def\batchfile{|\ldots +% do not start with |\def\batchfile{|\ldots \iffalse}\fi % \begin{macrocode} \def\process@first@batchfile{% \processbatchFile diff --git a/Master/texmf-dist/source/latex/base/fontdef.dtx b/Master/texmf-dist/source/latex/base/fontdef.dtx index 82b09709af1..281add29efc 100644 --- a/Master/texmf-dist/source/latex/base/fontdef.dtx +++ b/Master/texmf-dist/source/latex/base/fontdef.dtx @@ -27,7 +27,8 @@ % % \fi % \iffalse -%%% From File: fontdef.dtx +%%% From File: fontdef.dtx +%<*!latexrelease> %<*dtx> \ProvidesFile{fontdef.dtx} % @@ -38,17 +39,24 @@ %<+cfgprel>\ProvidesFile{preload.cfg} %\ProvidesFile{fontdef.drv} % \fi -% \ProvidesFile{fontdef.dtx} -%<-latexrelease> [2021/01/15 v3.0i LaTeX Kernel -% \iftrue (\else -%(Text -%(Math -%<+cfgtext>(Uncustomized text -%<+cfgmath>(Uncustomized math -%<+cfgprel>(Uncustomized preload +% \ProvidesFile{fontdef.dtx} + [2024/02/09 v3.0i LaTeX Kernel +% \iffalse +% (Text font setup) +% (Math font setup) +%<+cfgtext> (Uncustomized text font setup) +%<+cfgmath> (Uncustomized math font setup) +%<+cfgprel> (Uncustomized preload font setup) +%<*dtx> % \fi -%<-latexrelease> font setup)] -% +(font setup) +%\iffalse +% +%\fi +] +% \iffalse +% +%\fi % %\iffalse This is a META comment % diff --git a/Master/texmf-dist/source/latex/base/format.ins b/Master/texmf-dist/source/latex/base/format.ins index 2e14ee0e62a..e20ff094380 100644 --- a/Master/texmf-dist/source/latex/base/format.ins +++ b/Master/texmf-dist/source/latex/base/format.ins @@ -170,6 +170,7 @@ the system are in the document `cfgguide.tex'. \from{lthooks.dtx}{2ekernel} % L3 layer module \from{ltcmdhooks.dtx}{2ekernel} % L3 layer module \from{ltsockets.dtx}{2ekernel} % L3 layer module + \from{lttemplates.dtx}{2ekernel} % L3 layer module \from{ltalloc.dtx}{2ekernel} \from{ltcntrl.dtx}{2ekernel} \from{lterror.dtx}{2ekernel} @@ -206,11 +207,12 @@ the system are in the document `cfgguide.tex'. \from{ltbibl.dtx}{2ekernel} \from{ltmarks.dtx}{trace,2ekernel} % L3 layer module \from{ltpage.dtx}{2ekernel} - \from{ltclass.dtx}{2ekernel,tracerollback} + \from{ltclass.dtx}{2ekernel,tracerollback} \from{ltkeys.dtx}{2ekernel} % L3 layer module \from{ltfilehook.dtx}{2ekernel} % L3 layer module \from{ltshipout.dtx}{2ekernel} % L3 layer module \from{ltoutput.dtx}{2ekernel} + \from{lttagging.dtx}{2ekernel} \from{ltfinal.dtx}{2ekernel}} \file{tracefnt.sty}{% \from{ltfsstrc.dtx}{package,trace}} @@ -228,6 +230,8 @@ the system are in the document `cfgguide.tex'. \from{lttextcomp.dtx}{TS1sty}} \file{textcomp-2018-08-11.sty}{% \from{lttextcomp.dtx}{TS1oldsty}} + \file{checkencodingsubset.tex}{% + \from{lttextcomp.dtx}{TS1check}} } \generateFile{oldlfont.sty}{t}{% diff --git a/Master/texmf-dist/source/latex/base/ifthen.dtx b/Master/texmf-dist/source/latex/base/ifthen.dtx index ef7d8ab3987..0bbe3612115 100644 --- a/Master/texmf-dist/source/latex/base/ifthen.dtx +++ b/Master/texmf-dist/source/latex/base/ifthen.dtx @@ -30,7 +30,7 @@ %% %% File `ifthen.dtx'. %% Copyright (C) 1991 by Leslie Lamport -%% Copyright (C) 1994-2001 LaTeX project, David Carlisle +%% Copyright (C) 1994-2024 LaTeX project, David Carlisle %% all rights reserved. %% % @@ -42,7 +42,7 @@ %\ProvidesFile{ifthen.drv} % \fi % \ProvidesFile{ifthen.dtx} - [2022/04/13 v1.1d Standard LaTeX ifthen package (DPC)] + [2024/03/16 v1.1e Standard LaTeX ifthen package (DPC)] % % \iffalse %<*driver> @@ -273,15 +273,35 @@ \ifx##1\relax\z@\else\expandafter##2##1\fi}}} % \end{macrocode} % \begin{macrocode} +\begingroup +\lccode`\~`\> % +\catcode`\+\active +\lccode`\+`\< % +\catcode`\!\active +\lccode`\!`\= % +\lowercase{\endgroup +% \end{macrocode} +% \begin{macrocode} +\def\TE@repl@active{% + \TE@repl~>% + \TE@repl+<% + \TE@repl!=% +} +% \end{macrocode} +% \begin{macrocode} \long\def\ifthenelse#1{% % \end{macrocode} % \changes{v1.0h}{1994/05/14}{Use \cs{TE@repl}} +% \changes{v1.1e}{2024/03/16}{replace active \cs{ifnum} syntax} % \begin{macrocode} \toks@{#1}% \TE@repl\or\TE@or \TE@repl\and\TE@and \TE@repl\not\TE@neg % \end{macrocode} +% \begin{macrocode} + \TE@repl@active +% \end{macrocode} % % \changes{v1.1c}{2001/05/25}{Added \cs{AND}, \cs{OR} and \cs{NOT} as % boolean operators as alternative to the lower case versions @@ -353,7 +373,10 @@ \expandafter\@firstoftwo \else \expandafter\@secondoftwo - \fi} + \fi}% +% \end{macrocode} +% \begin{macrocode} +} % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/base/inputenc.dtx b/Master/texmf-dist/source/latex/base/inputenc.dtx index 5858743afd8..7ab9713d8e9 100644 --- a/Master/texmf-dist/source/latex/base/inputenc.dtx +++ b/Master/texmf-dist/source/latex/base/inputenc.dtx @@ -142,7 +142,7 @@ % Originally this command was only to be used in vertical mode (with % the idea that it should be only within a document when % using text from several documents to build up a composite work such -% as a volume of journal articles. However, usages in certain +% as a volume of journal articles). However, usages in certain % languages suggested that it might be preferable to allow changing % the input encoding at any time, which is what is possible now % (though that is quite computing resource intensive). @@ -410,7 +410,7 @@ % \ProvidesFile{cp1252.def} % \ProvidesFile{cp1250.def} % \ProvidesFile{cp1257.def} - [2021/02/14 v1.3d Input encoding file] + [2024/02/08 v1.3d Input encoding file] %%% %%% If you need a Euro symbol, try cp858 instead. %%% @@ -2204,7 +2204,7 @@ % \section{The Next encoding} % % This input encoding is based on work by Stefan Ried -% (\texttt{stef@\linebreak[0]theo-phys.uni-essen.de} and Holger Uhr +% (\texttt{stef@\linebreak[0]theo-phys.uni-essen.de}) and Holger Uhr % (\texttt{huhr@\linebreak[0]uni-paderborn.de}). % % Further extended by diff --git a/Master/texmf-dist/source/latex/base/latexrelease.ins b/Master/texmf-dist/source/latex/base/latexrelease.ins index 8ae19b318d3..89c3b0fc3a7 100644 --- a/Master/texmf-dist/source/latex/base/latexrelease.ins +++ b/Master/texmf-dist/source/latex/base/latexrelease.ins @@ -97,6 +97,7 @@ extension .ins) which are part of the distribution. \from{lthooks.dtx} {latexrelease}% L3 layer module \from{ltcmdhooks.dtx} {latexrelease}% L3 layer module \from{ltsockets.dtx} {latexrelease}% L3 layer module + \from{lttemplates.dtx} {latexrelease}% L3 layer module \from{ltalloc.dtx} {latexrelease}% empty \from{ltcntrl.dtx} {latexrelease}% empty \from{lterror.dtx} {latexrelease}% empty diff --git a/Master/texmf-dist/source/latex/base/ltboxes.dtx b/Master/texmf-dist/source/latex/base/ltboxes.dtx index 7c5a7c01397..7e6c787ab89 100644 --- a/Master/texmf-dist/source/latex/base/ltboxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltboxes.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltboxes.dtx} - [2023/10/26 v1.4e LaTeX Kernel (Box Commands)] + [2024/04/22 v1.4f LaTeX Kernel (Box Commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltboxes.dtx} @@ -87,7 +87,7 @@ % Note that in this picture mode version of |\makebox| a [b] aligns on % the \emph{bottom} of the text as documented. If you want to align on % the \emph{baseline} use -% |\makebox( , )[b]{\raisebox{0pt}[\height][0pt]{xyz}}}| +% |\makebox( , )[b]{\raisebox{0pt}[\height][0pt]{xyz}}| % or |\makebox( , )[b]{\smash{xyz}}| % % \DescribeMacro\mbox @@ -235,7 +235,8 @@ % \begin{macro}{\makebox} % \changes{v0.1a}{1993/12/03} % {modified} -% |\makebox| User level command just looks for optional |[| or |(|. +% |\makebox| User level command just looks for optional +% |[| or |(|. \iffalse)]\fi % \changes{v1.1h}{2015/01/08}{Make Robust (latexrelease)} % \begin{macrocode} % @@ -1010,7 +1011,7 @@ % set globally to false when they are definitely true. % % If anyone is unhappy with this argument then both flags should be -% treated as in |\set@nobreak|; otherwise this command will be +% treated as in |\@setnobreak|; otherwise this command will be % redundant. % \changes{v1.1a}{1996/10/24}{Added local settings of flags: dangerous!!} % \begin{macrocode} @@ -1486,9 +1487,40 @@ % % The |\nobreak| was added (1995/10/31) to allow hyphenation of the % final word of the paragraph. +% +% In 2024 we changed the macro to account for vertical mode. In +% that case we use a strut produced with \cs{hrule} to avoid +% starting a new paragraph (resulting in spurious extra line) and +% also account for the \cs{prevdepth} of the previous line. +% \changes{v1.4f}{2024/04/18} +% {Use a \cs{hrule} strut not a \cs{vrule} if already in +% vertical mode (bug seen first with footmisc/14)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2024/06/01}% +% {\@finalstrut}{final strut correction}% \def\@finalstrut#1{% - \unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1} + \unskip + \ifhmode \nobreak \vrule + \else + \ifdim \prevdepth=-\@m\p@ + \else + \vskip-\prevdepth + \fi + \hrule + \fi + \@width\z@\@height\z@\@depth\dp#1} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@finalstrut}{final strut correction}% +%\def\@finalstrut#1{% +% \unskip\ifhmode\nobreak\fi +% \vrule\@width\z@\@height\z@\@depth\dp#1} +% +%\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 139eb7a1a72..35bbb8a55a4 100644 --- a/Master/texmf-dist/source/latex/base/ltclass.dtx +++ b/Master/texmf-dist/source/latex/base/ltclass.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2023/04/14 v1.5h LaTeX Kernel (Class & Package Interface)] + [2024/04/10 v1.5k LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -390,7 +390,7 @@ % package files.) % % |\DeclareOption*{\PassOptionsToPackage{\CurrentOption}|^^A -% |{|\meta{pkg-name}|}|\\ +% |{|\meta{pkg-name}|}}|\\ % Handle the current option by passing it on to the package % \meta{pkg-name}, which will presumably be loaded via % |\RequirePackage| later in the file. This is useful for building @@ -1075,19 +1075,20 @@ % \begin{macrocode} % %<*2ekernel|latexrelease> -%\IncludeInRelease{2021/11/15}% -% {\IfPackageLoadedtTF}{Test package loading}% +%\IncludeInRelease{2024/06/01}% +% {\IfPackageLoadedTF}{Test package loading}% \let \IfPackageLoadedTF \@ifpackageloaded \let \IfClassLoadedTF \@ifclassloaded \let \IfPackageLoadedWithOptionsTF \@ifpackagewith \let \IfClassLoadedWithOptionsTF \@ifclasswith % \end{macrocode} -% For rollback pretend it was available since the beginning of dawn. +% For rollback/rollforward pretend everything was available since +% the beginning of dawn. % \begin{macrocode} % %\EndIncludeInRelease %\IncludeInRelease{0000/00/00}% -% {\IfPackageLoadedtTF}{Test package loading}% +% {\IfPackageLoadedTF}{Test package loading}% % %\let \IfPackageLoadedTF \@ifpackageloaded %\let \IfClassLoadedTF \@ifclassloaded @@ -1102,6 +1103,99 @@ % % % +% \begin{macro}{ +% \IfPackageLoadedT,\IfPackageLoadedF, +% \IfPackageAtLeastT,\IfPackageAtLeastF, +% \IfClassAtLeastT,\IfClassAtLeastF, +% \IfFileAtLeastT,\IfFileAtLeastF, +% \IfFormatAtLeastT,\IfFormatAtLeastF, +% \IfPackageLoadedWithOptionsT,\IfPackageLoadedWithOptionsF, +% \IfClassLoadedT,\IfClassLoadedF, +% \IfClassLoadedWithOptionsF,\IfClassLoadedWithOptionTF +% } +% A few more conditionals for convenience +% \changes{v1.5k}{2024/04/10}{Provide T and F conditionals not just TF +% (gh/1262)} +% \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2024/06/01}% +% {\IfPackageLoadedT}{More conditionals}% +\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}} +\def\IfPackageLoadedF #1{\IfPackageLoadedTF{#1}{}} +\def\IfClassLoadedT #1#2{\IfClassLoadedTF{#1}{#2}{}} +\def\IfClassLoadedF #1{\IfClassLoadedTF{#1}{}} +\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}} +\def\IfPackageAtLeastF #1#2{\IfPackageAtLeastTF{#1}{#2}{}} +\def\IfClassAtLeastT #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}} +\def\IfClassAtLeastF #1#2{\IfClassAtLeastTF{#1}{#2}{}} +\def\IfFileAtLeastT #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}} +\def\IfFileAtLeastF #1#2{\IfFileAtLeastTF{#1}{#2}{}} +\def\IfFormatAtLeastT #1#2{\IfFormatAtLeastTF{#1}{#2}{}} +\def\IfFormatAtLeastF #1{\IfFormatAtLeastTF{#1}{}} +\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}} +\def\IfPackageLoadedWithOptionsF #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}} +\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}} +\def\IfClassLoadedWithOptionsF #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}} +% \end{macrocode} +% +% \begin{macro}{\IfFileLoadedTF,\IfFileLoadedT,\IfFileLoadedF} +% These three commands haven't been there at all in the past. +% \changes{v1.5k}{2024/04/10}{Provide \cs{IfFileLoadedTF} and variants +% (gh/1222)} +% \begin{macrocode} +\def\IfFileLoadedTF#1{% + \expandafter\ifx\csname ver@#1\endcsname\relax + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} +\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}} +\def\IfFileLoadedF #1{\IfFileLoadedTF{#1}{}} +% \end{macrocode} +% For rollback/rollforward pretend everything was available since +% the beginning of dawn. +% \begin{macrocode} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\IfPackageLoadedT}{More conditionals}% +% +%\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}} +%\def\IfPackageLoadedF #1{\IfPackageLoadedTF{#1}{}} +%\def\IfClassLoadedT #1#2{\IfClassLoadedTF{#1}{#2}{}} +%\def\IfClassLoadedF #1{\IfClassLoadedTF{#1}{}} +%\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}} +%\def\IfPackageAtLeastF #1#2{\IfPackageAtLeastTF{#1}{#2}{}} +%\def\IfClassAtLeastT #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}} +%\def\IfClassAtLeastF #1#2{\IfClassAtLeastTF{#1}{#2}{}} +%\def\IfFileAtLeastT #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}} +%\def\IfFileAtLeastF #1#2{\IfFileAtLeastTF{#1}{#2}{}} +%\def\IfFormatAtLeastT #1#2{\IfFormatAtLeastTF{#1}{#2}{}} +%\def\IfFormatAtLeastF #1{\IfFormatAtLeastTF{#1}{}} +%\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}} +%\def\IfPackageLoadedWithOptionsF #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}} +%\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}} +%\def\IfClassLoadedWithOptionsF #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}} +% +%\def\IfFileLoadedTF#1{% +% \expandafter\ifx\csname ver@#1\endcsname\relax +% \expandafter\@secondoftwo +% \else +% \expandafter\@firstoftwo +% \fi} +%\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}} +%\def\IfFileLoadedF #1{\IfFileLoadedTF{#1}{}} +% +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% % \begin{macro}{\ProvidesPackage} % Checks that the current filename is correct, and defines % |\ver@filename|. @@ -1327,11 +1421,11 @@ % \changes{v1.4c}{2021/06/06} % {apply \cs{expandafter} to raw options for gh/580} % \begin{macrocode} - \@ifundefined{@raw@opt@#3.#1}% - {\expandafter\gdef\csname @raw@opt@#3.#1\expandafter\endcsname - \expandafter{#2}}% - {\expandafter\g@addto@macro\csname @raw@opt@#3.#1\expandafter\endcsname - \expandafter{\expandafter,#2}}% + \@ifundefined{@raw@opt@#3.#1}% + {\expandafter\gdef\csname @raw@opt@#3.#1\expandafter\endcsname + \expandafter{#2}}% + {\expandafter\g@addto@macro\csname @raw@opt@#3.#1\expandafter\endcsname + \expandafter{\expandafter,#2}}% } % %\EndIncludeInRelease @@ -1950,12 +2044,34 @@ % \end{macro} % % \begin{macro}{\@fileswithoptions} +% \changes{v1.5i}{2024/01/30}{Test group level} % The common part of |\documentclass| and |\usepackage|. % \begin{macrocode} +% +%\IncludeInRelease{2024/06/01}% +% {\@fileswithoptions}{Check Group}% +%<*2ekernel|latexrelease> \def\@fileswithoptions#1{% + \ifnum\currentgrouplevel>\z@ + \@latex@error + {Loading a class or package in a group}% + {Classes and packages should only be loaded at the top level}% + \fi \@ifnextchar[%] {\@fileswith@ptions#1}% {\@fileswith@ptions#1[]}} +% +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@fileswithoptions}{Check Group}% +%\def\@fileswithoptions#1{% +% \@ifnextchar[%] +% {\@fileswith@ptions#1}% +% {\@fileswith@ptions#1[]}} +%\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \begin{macrocode} \@onlypreamble\@fileswithoptions % \end{macrocode} % @@ -2221,9 +2337,17 @@ % \end{macrocode} % \changes{v1.5d}{2022/10/10}{Use \cs{protected@edef}.} % \begin{macrocode} - \expandafter\protected@edef\csname opt@\@currname.\@currext\endcsname + \expandafter\protected@edef + \csname opt@\@currname.\@currext\endcsname {\zap@space#2 \@empty}% - \@namedef{@raw@opt@\@currname.\@currext}{#2}% +% \end{macrocode} +% \changes{v1.5j}{2024/03/22} +% {Apply one-step expansion to raw option list, +% to be consistent with change for gh/580 (gh/1298).} +% \begin{macrocode} + \expandafter\def + \csname @raw@opt@\@currname.\@currext\expandafter\endcsname + \expandafter{#2}% \@nameuse{opt@handler@\@currname.\@currext}% }% }% @@ -2624,8 +2748,8 @@ % % Allow code to be saved to be executed at specific later times. % -% Save things in macros, I considered using toks registers, (and -% |\addto@hook| from the NFSS code, that would require stacking the +% Here we save things in macros. I considered using toks registers (and +% |\addto@hook| from the NFSS code), but that would require stacking the % contents in the case of required packages, so just generate a new % macro for each package. % \begin{macro}{\@begindocumenthook} @@ -2997,7 +3121,7 @@ \let\do\@makeother\dospecials% % \end{macrocode} % If there are active characters in the upper half (e.g., from -% \texttt{inputenc} there would be confusion so we render everything +% \texttt{inputenc}) there would be confusion so we render everything % harmless. % \changes{v1.2f}{2018/03/27} % {Use full file name for old release} @@ -3585,7 +3709,7 @@ % and therefore we can now test its value. If the value is zero we % assume that the remaining argument string represents a version % and change |\pkgcls@targetdate| and set |\pkgcls@targetlabel| to -% the version name (after stripping off the trailing \texttt{=}. +% the version name (after stripping off the trailing \texttt{=}). % \begin{macrocode} \ifnum \pkgcls@targetdate=\z@ \pkgcls@targetdate\@ne @@ -3695,7 +3819,7 @@ % late, but if there wasn't one (i.e., if current release is the % oldest that exists) we use it as the best choice. However in % that case something is wrong (as there shouldn't be a rollback to -% a date where a package used doesn't yet exists. So we make a +% a date when a package used didn't yet exists). So we make a % complained to the user. % \begin{macrocode} \ifx\pkgcls@candidate\@empty diff --git a/Master/texmf-dist/source/latex/base/ltcmd.dtx b/Master/texmf-dist/source/latex/base/ltcmd.dtx index 0a6cb1a53c5..69bd162e56b 100644 --- a/Master/texmf-dist/source/latex/base/ltcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltcmd.dtx @@ -34,8 +34,8 @@ %%% From File: ltcmd.dtx % % \begin{macrocode} -\def\ltcmdversion{v1.2a} -\def\ltcmddate{2023-08-19} +\def\ltcmdversion{v1.2e} +\def\ltcmddate{2024-04-17} % \end{macrocode} % %<*driver> @@ -415,8 +415,6 @@ \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} @@ -435,17 +433,93 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\@@_all_m_check:n, \@@_all_m_check_aux:n} +% A quick loop to check for all |(+)m|-type arguments. +% \begin{macrocode} +\cs_new:Npn \@@_all_m_check:n #1 + { \tl_map_function:nN {#1} \@@_all_m_check_aux:n } +\cs_new:Npn \@@_all_m_check_aux:n #1 + { + \str_if_eq:nnF {#1} { m } + { + \str_if_eq:nnF {#1} { + } + { X } + } + } +% \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. +% { +% \@@_declare_cmd_optimized:Nnn, +% \@@_declare_cmd_code_aux:Nnn, +% \@@_declare_cmd_code_expandable:Nnn +% } +% \begin{macro}{\@@_start_optimized:} +% \changes{v1.2b}{2023/12/01} +% {Optimize cmd creation for all-\texttt{m} arguments} +% At this stage we can check for a short-cut possibility: if the argument +% specification is made up of just |(+)m| tokens, and if all arguments are +% either short or long, then we can produce an optimized document command. +% This only applies to document commands, not creation of environments (which +% are more complex). +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_cmd_code:Nnn #1#2 + { + \bool_lazy_any:nTF + { + { \l_@@_environment_bool } + { + \bool_lazy_and_p:nn + { \l_@@_some_short_bool } + { \l_@@_some_long_bool } + } + { ! \tl_if_blank_p:e { \@@_all_m_check:n {#2} } } + } + { + \tl_set:Nx \l_@@_fn_tl + { \exp_not:c { \l_@@_function_tl \c_space_tl } } + \bool_if:NTF \l_@@_grab_expandably_bool + { \@@_declare_cmd_code_expandable:Nnn } + { \@@_declare_cmd_code_aux:Nnn } + } + { \@@_declare_cmd_optimized:Nnn } + #1 {#2} + } +% \end{macrocode} +% The optimized version of commands just has to worry about whether to make +% them protected or long. The commands start with an expandable marker so +% that other parts of the kernel know these are set up by \pkg{ltcmd}. +% We need the two layers of redirection so that the \texttt{code} internal +% function has the same form as it would for any other document command. +% Optimization means that there is no \cs{group_align_safe_begin:} before +% grabbing the arguments, so anything involving |&| tokens will not work. +% However, this is really only intended for making optional argument +% processing safe anyway, so in practice should not be an issue. % \begin{macrocode} -\cs_new_protected:Npn \@@_declare_cmd_code:Nnn +\cs_new_protected:Npn \@@_declare_cmd_optimized:Nnn #1#2#3 { - \bool_if:NTF \l_@@_grab_expandably_bool - { \@@_declare_cmd_code_expandable:Nnn } - { \@@_declare_cmd_code_aux:Nnn } - } + \bool_if:NTF \l_@@_expandable_bool + { \cs_set_nopar:Npe } + { \cs_set_protected_nopar:Npe } + #1 + { + \exp_not:N \@@_start_optimized: + \exp_not:c { \l_@@_function_tl \c_space_tl code } + } + \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 } + \bool_if:NF \l_@@_some_long_bool { _nopar } + :Npn + } + \l_@@_current_arg_int + {#3} + } +\cs_new:Npn \@@_start_optimized: { } % \end{macrocode} % Standard functions call \cs{@@_start:nNNnnn}, which receives the % argument specification, an auxiliary used for @@ -544,6 +618,7 @@ % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@@_declare_env:nnnn} % \begin{macro}{\@@_declare_env_internal:nnnn} @@ -1286,7 +1361,7 @@ % 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. +% \iffalse{\fi an~\verb|! Argument of \dots has an extra }| error. % \begin{macrocode} \cs_new_protected:Npn \@@_allowed_token_check:N #1 { @@ -1373,6 +1448,9 @@ % \end{macro} % % \begin{macro}{\@@_add_arg_spec:n, \@@_add_arg_spec_mandatory:n} +% \changes{v1.2c}{2023/12/22} +% {Clarify error message when \texttt{!} prefix is applied to +% non-trailing opt-arg (gh/1198)} % 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. @@ -1414,7 +1492,12 @@ \bool_if:NT \l_@@_some_obey_spaces_bool { \msg_error:nnxx { cmd } { invalid-bang } - { \@@_environment_or_command: } { \tl_to_str:n {#1} } + { \@@_environment_or_command: } + { + \bool_if:NTF \l_@@_obey_spaces_bool + { \tl_to_str:n {'#1'} } + { an~optional~argument~before~mandatory~ \tl_to_str:n {'#1'} } + } \@@_bad_def:wn } \tl_clear:N \l_@@_last_delimiters_tl @@ -1626,8 +1709,10 @@ % argument, so we need to break out of one layer of braces in % \cs{l_@@_process_one_tl}, add copies of the processor as necessary, % and then return the removed brace. The function below does just -% that: it defines \cs{l_@@_process_one_tl} starting with a |}|$_2$ -% and ending with a |{|$_1$, so that it adds as many processors as +% that: it defines \cs{l_@@_process_one_tl} starting with a +% \iffalse{\fi |}|$_2$ +% and ending with a |{|$_1$, \iffalse}\fi +% so that it adds as many processors as % needed when |x|-expanded. % \begin{macrocode} \cs_new_protected:Npn \@@_replicate_processor:nn #1 #2 @@ -2033,7 +2118,7 @@ % \begin{macro}{\@@_copy:NN} % \begin{macro}{\@@_set_eq_if_exist:NN,\@@_set_eq_if_exist:cc} % This macro just branches to the proper copying command by using -% \cs{@@_cmd_type_cases:NnnnnF}. The copying command takes the names +% \cs{@@_cmd_type_cases:NnnnnnF}. The copying command takes the names % of the commands to be copied to and from, and the actual commands % as its four arguments. % \begin{macrocode} @@ -2042,9 +2127,10 @@ \use:x { \int_set:Nn \tex_escapechar:D { 92 } - \exp_not:N \@@_cmd_type_cases:NnnnnF \exp_not:N #2 + \exp_not:N \@@_cmd_type_cases:NnnnnnF \exp_not:N #2 { \@@_copy_command:nnNN } { \@@_copy_expandable:nnNN } + { \@@_copy_optimized:nnNN } { \@@_copy_environment:nnNN } { \@@_copy_environment_end:nnNN } { \@@_cant_copy:nwn { non-ltcmd } } @@ -2186,6 +2272,24 @@ %\EndIncludeInRelease % \end{macrocode} % +% \begin{macro}{\@@_copy_optimized:nnNN} +% Copy the code, simply define the wrapper. +% \begin{macrocode} +\cs_new_protected:Npn \@@_copy_optimized:nnNN #1#2#3#4 + { + \cs_set_eq:cc { #1 ~ code } { #2 ~ code } + \token_if_protected_macro:NTF #4 + { \cs_set_protected_nopar:Npe } + { \cs_set_nopar:Npe } + #3 + { + \exp_not:N \@@_start_optimized: + \exp_not:c { #1 ~ code } + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %\IncludeInRelease{2021/11/15}{\@@_copy:NN (part 2)}% % {Support~\NewCommandCopy~in~ltcmd} @@ -2423,7 +2527,7 @@ % % \begin{macro}{\@@_show:N} % This macro just branches to the proper showing command by using -% \cs{@@_cmd_type_cases:NnnnnF}. The showing command takes the command +% \cs{@@_cmd_type_cases:NnnnnnF}. The showing command takes the command % to be shown as argument. % \begin{macrocode} \cs_new_protected:Npn \@@_show:N #1 @@ -2431,9 +2535,10 @@ \use:x { \int_set:Nn \tex_escapechar:D { 92 } - \exp_not:N \@@_cmd_type_cases:NnnnnF \exp_not:N #1 + \exp_not:N \@@_cmd_type_cases:NnnnnnF \exp_not:N #1 { \@@_show_command:N } { \@@_show_expandable:N } + { \@@_show_optimized:N } { \@@_show_environment:N } { \@@_show_environment_end:N } { \@@_cant_copy:nwn { non-ltcmd } } @@ -2450,6 +2555,7 @@ % \@@_show_command:NnNNwN, % \@@_show_expandable:N, % \@@_show_expandable:NnNNNNnN, +% \@@_show_optimized:N, % \@@_show_command_aux:NnNNn, % \@@_show_environment:N, % \@@_show:x, @@ -2530,6 +2636,48 @@ } % \end{macrocode} % +% Optimized functions need things done a bit differently as we need to +% reconstruct the argument spec. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_optimized:N #1 + { + \exp_args:Nc \@@_show_optimized:NN + { \cs_to_str:N #1 \c_space_tl code } + #1 + } +\cs_new_protected:Npn \@@_show_optimized:NN #1#2 + { + \cs_set:Npe \@@_show_optimized_aux:N ##1 + { + \c_space_tl \c_space_tl \c_hash_str ##1 : + \bool_lazy_or:nnT + { \token_if_long_macro_p:N #1 } + { \token_if_protected_long_macro_p:N #1 } + { + } m + \iow_newline: + } + \tl_show:e + { + \token_to_str:N #2 = + \bool_lazy_or:nnF + { \token_if_protected_macro_p:N #1 } + { \token_if_protected_long_macro_p:N #1 } + { expandable ~ } document~command: + \iow_newline: + \int_step_function:nN + { + \int_div_truncate:nn + { \tl_count:e { \cs_parameter_spec:N #1 } } + { 2 } + } + \@@_show_optimized_aux:N + -> + \cs_replacement_spec:N #1 + } + } +\cs_generate_variant:Nn \tl_count:n { e } +% \end{macrocode} +% % We can reuse most of the above to show an environment, except that % we need to ensure that the proper \cs[no-index]{environment~\ldots} % are passed to \cs{@@_show_command_aux:NnNNn}. Additionally, when @@ -3533,18 +3681,38 @@ % \end{macro} % % \begin{macro}{\@@_grab_v_aux_put:N} +% \changes{v1.2d}{2024/03/21}{Collect \cs{endlinechar} as \cs{obeyedline}} % 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} +%\IncludeInRelease{2024/06/01}{\@@_grab_v_aux_put:N}% +% {Endlines~as~\obeyedline} \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 } + { \exp_not:N #1 } + { + \int_compare:nNnTF {`#1} = \tex_endlinechar:D + { \exp_not:N \obeyedline } + { \token_to_str:N #1 } + } } } +%\EndIncludeInRelease +%\IncludeInRelease{2020/10/01}{\@@_grab_v_aux_put:N}% +% {Endlines~as~\obeyedline} +%\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 } +% } +% } +%\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4376,13 +4544,16 @@ % \end{macro} % % \begin{macro}{\__kernel_cmd_if_xparse:NTF} -% \begin{macro}{\@@_cmd_type_cases:Nnnnn} +% \begin{macro}{\@@_cmd_type_cases:NnnnnnF} % \changes{v1.0d}{2021/04/19}{Renamed \cs{__cmd_cmd_if_xparse:NTF} to % \cs{__kernel_cmd_if_xparse:NTF} for cross-module usage} % \changes{v1.0d}{2021/07/30}{Added \cs{@@_cmd_type_cases:NnnnnF} for % \cs{NewCommandCopy} and \cs{ShowCommand} support} % \changes{v1.0l}{2022/03/18}{Fix \cs{@@_cmd_type_cases:NnnnnF} -%" prematurely expanding macros (gh/795)} +% prematurely expanding macros (gh/795)} +% \changes{v1.2b}{2023/12/01}{Extend for optimized commands} +% \changes{v1.2e}{2024/04/17}{Use \cs{__kernel_cs_parameter_spec:N} instead +% of \cs{cs_argument_spec:N}/\cs{cs_parameter_spec:N}} % \begin{macro}{\@@_cmd_if_xparse_aux:N} % % To determine whether the command is an \pkg{xparse} command check @@ -4390,36 +4561,38 @@ % that its |replacement_spec| starts with either % \cs{@@_start:nNNnnn} (non-expandable command) or % \cs{@@_start_expandable:nNNNNn} (expandable command) or +% \cs{@@_start_optimized:} (optimized command) or % \cs{@@_start_env:nnnnn} (environment) or % \cs[no-index]{environment~\#1~end~aux} (environment end). % % This conditional is needed in several kernel modules and is % therefore has a kernel-internal name. % \begin{macrocode} -\cs_new_protected:Npn \@@_cmd_type_cases:NnnnnF #1 #2 #3 #4 #5 #6 +\cs_new_protected:Npn \@@_cmd_type_cases:NnnnnnF #1 #2 #3 #4 #5 #6 #7 { \exp_args:Ne \str_case_e:nnF { - \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 } + \exp_args:Nf \tl_if_empty:nT { \__kernel_cs_parameter_spec:N #1 } { \exp_not:N \exp_not:n { \exp_not:e { \tl_head:N #1 } } } } { { \exp_not:N \@@_start:nNNnnn } {#2} { \exp_not:N \@@_start_expandable:nNNNNn } {#3} - { \exp_not:N \@@_start_env:nnnnn } {#4} + { \exp_not:N \@@_start_optimized: } {#4} + { \exp_not:N \@@_start_env:nnnnn } {#5} { \exp_after:wN \exp_not:N \cs:w environment~ \exp_last_unbraced:Ne \use_none:nnn { \cs_to_str:N #1 } ~end~aux \cs_end: - } {#5} + } {#6} } - {#6} + {#7} } \cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1 { - \@@_cmd_type_cases:NnnnnF #1 - { } { } { } { } { \use_iii:nnn } + \@@_cmd_type_cases:NnnnnnF #1 + { } { } { } { } { } { \use_iii:nnn } \use_i:nn } % \end{macrocode} @@ -4511,10 +4684,8 @@ \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 } - ' + command ~ + ' \c_backslash_str \tl_to_str:N \l_@@_function_tl ' } } % \end{macrocode} @@ -4522,6 +4693,8 @@ % % Some messages intended as errors when defining commands/environments. % \changes{v1.0f}{2021/06/04}{Normalize various error messages} +% \changes{v1.2c}{2023/12/22} +% {Generalize message \texttt{invalid-bang} (gh/1198)} % \begin{macrocode} \msg_new:nnnn { cmd } { arg-after-body } { Argument~type~'b'~must~be~last~in~#1. } @@ -4612,7 +4785,7 @@ { Invalid~argument~prefix~'!'~in~#1. } { The~prefix~'!'~is~only~allowed~for~trailing~optional~arguments.~ - You~tried~to~apply~it~to~'#2'. + You~tried~to~apply~it~to~#2. \c_@@_ignore_def_tl } \msg_new:nnnn { cmd } { not-definable } diff --git a/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx index 73bd7f63518..f8a8699d7ed 100644 --- a/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx +++ b/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: ltcmdhooks.dtx +%% From File: ltcmdhooks.dtx %% Copyright (C) 2020-2024 %% Frank Mittelbach, Phelype Oleinik, The LaTeX Project % @@ -12,16 +12,20 @@ % https://www.latex-project.org/lppl.txt % % -%%% From File: ltcmdhooks.dtx -% -\def\ltcmdhooksversion{v1.0i} -\def\ltcmdhooksdate{2023/06/16} -% +% \fi % +% \iffalse +%%% From File: lthooks.dtx % %<*driver> +% \fi +\ProvidesFile{ltcmdhooks.dtx} + [2024/04/17 v1.0j LaTeX Kernel (Command hooks)] +% \iffalse +% \documentclass{l3doc} -%\usepackage{ltcmdhooks} +\GetFileInfo{ltcmdhooks.dtx} +% \usepackage{ltcmdhooks} \EnableCrossrefs \CodelineIndex \begin{document} @@ -38,7 +42,7 @@ % \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\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % \author{Frank Mittelbach \and Phelype Oleinik} % @@ -125,8 +129,8 @@ % \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; +% hooks) even if the command itself is not (yet) defined, because the +% defining package has not been loaded at this point; % % \item % @@ -214,6 +218,14 @@ % optional and mandatory arguments. By adding code to the % \hook{cmd/section/after} hook, you get in the way of that scanning. % +% In such a case, where it is known that a specific generic command +% hook does not work if code is added to it, the package author can +% add a \cs{DisableGenericHook}\footnote{Please use +% \cs{DisableGenericHook} if at all, only on hooks that you +% \enquote{own}, i.e., for commands your package or class defines and +% not second guess whether or not hooks of other packages should get +% disabled!} declaration to prevent this from happening in user +% documents and thereby avoiding obscure errors. % % % \section{Package Author Interface} @@ -394,6 +406,8 @@ % \end{macrocode} % % \changes{v1.0b}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}} +% \changes{v1.0j}{2024/04/17}{Use \cs{__kernel_cs_parameter_spec:N} instead +% of \cs{cs_argument_spec:N}/\cs{cs_parameter_spec:N}} % % \begin{macrocode} %<*2ekernel|latexrelease> @@ -643,7 +657,7 @@ } } % \end{macrocode} -% and a conditional \cs{@@_if_public_command:N} to check if a command +% and a conditional \cs{@@_if_public_command:NTF} 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. @@ -838,14 +852,14 @@ \@@_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 +% counting the number of characters in the \cs{cs_parameter_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 + \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2 \bool_if:NT #1 { -1 } } % \end{macrocode} @@ -998,7 +1012,7 @@ % \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } % \int_set:Nn \l_@@_patch_num_args_int % { -% \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2 +% \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2 % \bool_if:NT #1 { -1 } % } % \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } @@ -1248,12 +1262,12 @@ % 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{cs_parameter_spec:N} is empty, and call % \cs{@@_patch_expand_redefine:NNnn}. % \begin{macrocode} \cs_new_protected:Npn \@@_retokenize_patch:Nnn #1 #2 #3 { - \str_if_eq:eeTF { \cs_argument_spec:N #1 } { } + \str_if_eq:eeTF { \__kernel_cs_parameter_spec:N #1 } { } { \@@_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} } { \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning } diff --git a/Master/texmf-dist/source/latex/base/ltcounts.dtx b/Master/texmf-dist/source/latex/base/ltcounts.dtx index c58ad2dcb61..006486d23b2 100644 --- a/Master/texmf-dist/source/latex/base/ltcounts.dtx +++ b/Master/texmf-dist/source/latex/base/ltcounts.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltcounts.dtx} - [2021/07/08 v1.1m LaTeX Kernel (Counters)] + [2021/11/08 v1.1n LaTeX Kernel (Counters)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltcounts.dtx} @@ -305,6 +305,7 @@ % \begin{macro}{\@definecounter} % \changes{v1.1b}{1995/05/20}{Streamlined code} % \changes{v1.1c}{1995/05/20}{And do it right} +% \changes{v1.1n}{2023/11/07}{Do not change \cs{the...} if already defined (gh/823)} % % \begin{macrocode} \def\@definecounter#1{\expandafter\newcount\csname c@#1\endcsname @@ -312,9 +313,21 @@ \global\expandafter\let\csname cl@#1\endcsname\@empty \@addtoreset{#1}{@ckpt}% \global\expandafter\let\csname p@#1\endcsname\@empty +% \end{macrocode} +% If \cs{the\#1} is undefined or \cs{relax} we define it with the +% standard definition for counters, otherwise we warn. This will +% catch, for example, that somebody defines a counter named +% ``index'' conflicting with the \env{theindex} environment. +% \begin{macrocode} \expandafter - \gdef\csname the#1\expandafter\endcsname\expandafter - {\expandafter\@arabic\csname c@#1\endcsname}} + \ifx\csname the#1\endcsname\relax + \expandafter + \gdef\csname the#1\expandafter\endcsname\expandafter + {\expandafter\@arabic\csname c@#1\endcsname}% + \else + \@latex@warning{Command `\string\the#1' already + defined -- not changed}% + \fi} % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/base/ltdefns.dtx b/Master/texmf-dist/source/latex/base/ltdefns.dtx index 24c13696985..d9ec12e75a6 100644 --- a/Master/texmf-dist/source/latex/base/ltdefns.dtx +++ b/Master/texmf-dist/source/latex/base/ltdefns.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2022/11/24 v1.5s LaTeX Kernel (definition commands)] + [2024/04/17 v1.5t LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -91,6 +91,9 @@ % \changes{v1.4b}{2015/02/21} % {Removed autoload support} % \changes{v1.5l}{2020/08/21}{Integration of new hook management interface} +% \changes{v1.5t}{2024/04/17} +% {Rename \cs{@expl@cs@argument@spec@@N} to +% \cs{@expl@cs@parameter@spec@@N} (gh/1014)} % % \section{Definitions} % @@ -215,12 +218,12 @@ % This section defines the following commands: % % \DescribeMacro -% {\@namedef}\marg{NAME}\\ Expands to |\def\|\marg{NAME}, +% {\@namedef}\marg{NAME}\\ Expands to |\def\|\meta{NAME}, % except name can contain any characters. % % \DescribeMacro % {\@nameuse}\marg{NAME}\\ -% Expands to |\|\marg{NAME}. +% Expands to |\|\meta{NAME}. % % \DescribeMacro % {\@ifnextchar} X\marg{YES}\marg{NO}\\ @@ -530,9 +533,11 @@ % This macro encapsulates the most common call to |\@ifnextchar|, saving % several tokens each time it is used in the definition of a command % with an optional argument. -% |#1| The code to execute in the case that there is a |[| need not be +% |#1| The code to execute in the case that there is a |[| \iffalse]\fi +% need not be % a single token but can be any sequence of commands that `expects' to -% be followed by |[|. If this command were only used in |\newcommand| +% be followed by |[|. \iffalse]\fi +% If this command were only used in |\newcommand| % definitions then |#1| would be a single token and the braces could % be omitted from |{#1}| in the definition below, saving a bit of % memory. @@ -595,7 +600,7 @@ % required argument spec by using a delimited argument (delimited % by the digit). This is faster and uses less tokens. The coding % is slightly odd to preserve the old interface (using |#2| = -% |\tw@| as the flag to surround the first argument with |[]|. But +% |\tw@| as the flag to surround the first argument with |[]|). But % the new method did not allow for the number of arguments |#3| not % being given as an explicit digit; hence (further expansion of % this argument and use of) |\number| was added later in 1999. @@ -706,13 +711,14 @@ % \begin{macro}{\newenvironment} % Define a new user environment. % |#1| is the environment name. |#2#| Grabs all the tokens up to -% the first |{|. These will be any optional arguments. They are not +% the first |{|. \iffalse}\fi +% These will be any optional arguments. They are not % parsed at this point, but are just passed to |\@newenv| which % will eventually call |\newcommand|. Any optional arguments will % then be parsed by |\newcommand| as it defines the command that % executes the `begin code' of the environment. % -% This |#2#| trick removed with version 1.2i as it fails if a |{| +% This |#2#| trick removed with version 1.2i as it fails if a |{| \iffalse}\fi % occurs in the optional argument. Now use |\@ifnextchar| directly. % \begin{macrocode} \def\newenvironment{\@star@or@long\new@environment} @@ -888,7 +894,8 @@ % \begin{macro}{\@check@c} % \changes{v1.2i}{1995/04/25}{Make \cs{long} for latex/1346} % |\CheckCommand| itself just grabs all the arguments we need, -% without actually looking for |[| optional argument forms. Now +% without actually looking for |[| \iffalse]\fi +% optional argument forms. Now % define |\reserved@a|. If |\\reserved@a| is then defined, compare it % with the ``|\#1|' otherwise compare |\reserved@a| with |#1|. % \begin{macrocode} @@ -2016,7 +2023,7 @@ \long\def\@show@newcommand@aux#1#2#3{% \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:}% #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% - \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}} + \@expl@cs@parameter@spec@@N#1->\@expl@cs@replacement@spec@@N#1}} % \end{macrocode} % \end{macro} % \end{macro} @@ -2117,7 +2124,7 @@ \@show@environment@end#1} \long\def\@show@environment@begin#1{% \typeout{> \string\begin{\@expl@cs@to@str@@N#1}=environment:}% - \typeout{\@expl@cs@argument@spec@@N#1->% + \typeout{\@expl@cs@parameter@spec@@N#1->% \@expl@cs@replacement@spec@@N#1.^^J}} % \end{macrocode} % \end{macro} @@ -2139,7 +2146,7 @@ \long\def\@show@environment@end@aux#1#2{% \@show@tokens{\string\end{\@expl@cs@to@str@@N#2}% \ifx\relax#1=undefined% - \else:^^J\@expl@cs@argument@spec@@N#1->% + \else:^^J\@expl@cs@parameter@spec@@N#1->% \@expl@cs@replacement@spec@@N#1% \fi}} % \end{macrocode} @@ -2158,7 +2165,7 @@ % \begin{macrocode} \def\@show@nonstop#1{% \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:^^J% - \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1.}} + \@expl@cs@parameter@spec@@N#1->\@expl@cs@replacement@spec@@N#1.}} \def\@show@typeout#1{\typeout{> #1.^^J}} % \end{macrocode} % \end{macro} @@ -2296,7 +2303,7 @@ % \changes{v1.3g}{2004/01/23}{Added macro (pr/3501)} % This macro is the kernel version of |\@ifnextchar| which is used % in a couple of places to prevent the AMS variant from being used -% since in some places this produced chaos (for example +% since in some places this produced chaos. For example, % if an \texttt{fd} file % is loaded in a random place then the optional argument to % |\ProvidesFile| could get printed there instead of being written diff --git a/Master/texmf-dist/source/latex/base/ltdirchk.dtx b/Master/texmf-dist/source/latex/base/ltdirchk.dtx index ef959c56939..917431552b7 100644 --- a/Master/texmf-dist/source/latex/base/ltdirchk.dtx +++ b/Master/texmf-dist/source/latex/base/ltdirchk.dtx @@ -36,8 +36,10 @@ % %<*driver> % \fi +% \fi \ProvidesFile{ltdirchk.dtx} - [2021/12/11 v1.3a LaTeX Kernel (System Dependent Parts)] + [2024/02/11 v1.3a LaTeX Kernel (System Dependent Parts)] +% \iffalse % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdirchk.dtx} @@ -261,6 +263,10 @@ % In current formats enable primitives with unprefixed names. % the \textsf{latexrelease} guards allow the primitives to be % defined with a |\luatex| prefix if older formats are specified. +% +% The unprefixed forms are \emph{not} undefined for improved +% compatibility with external packages when rolling back +% the format. % \begin{macrocode} % % @@ -278,25 +284,6 @@ % "luatex", % tex.extraprimitives("core","omega", "aleph", "luatex") % ) -% local i -% local t = { } -% for _,i in pairs(tex.extraprimitives("luatex")) do -% if not string.match(i,"^U") then -% if not string.match(i, "^luatex") then -% table.insert(t,i) -% end -% else -% if string.match(i,"^Uchar$") then -% table.insert(t,i) -% end -% end -% end -% for _,i in pairs(t) do -% tex.print( -% "\noexpand\\let\noexpand\\" .. i -% .. "\noexpand\\undefined" -% ) -% end %} %\EndIncludeInRelease %\fi @@ -1000,8 +987,8 @@ % \begin{macro}{\@TeXversion} % \TeX\ versions older than 3.141 require |\@TeXversion| to be % set. This can be determined automatically due to a trick suggested -% by Bernd Raichle. (Actually this will not always get the correct -% version number, eg \TeX3.14 would be detected as \TeX3, but \LaTeX\ +% by Bernd Raichle. Actually this will not always get the correct +% version number, e.g., \TeX3.14 would be detected as \TeX3, but \LaTeX\ % only needs to take account of \TeX's older than 3, or between 3 and % 3.14. % \changes{v1.0h}{1994/10/11} diff --git a/Master/texmf-dist/source/latex/base/ltexpl.dtx b/Master/texmf-dist/source/latex/base/ltexpl.dtx index 4aaf799e325..410235a056c 100644 --- a/Master/texmf-dist/source/latex/base/ltexpl.dtx +++ b/Master/texmf-dist/source/latex/base/ltexpl.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltexpl.dtx} - [2023/10/13 v1.3g LaTeX Kernel (expl3-dependent code)] + [2024/04/17 v1.3h LaTeX Kernel (expl3-dependent code)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltexpl.dtx} @@ -356,9 +356,19 @@ % \changes{v1.2e}{2020/08/19} % {Add \cs{@expl@cs@\meta{thing}@spec@@N} % for \cs{ShowCommand} (gh/373)} +% \changes{v1.3h}{2024/04/17} +% {Rename \cs{@expl@cs@argument@spec@@N} to +% \cs{@expl@cs@parameter@spec@@N} (gh/1014)} +% \changes{v1.3h}{2024/04/17} +% {Update name of \pkg{expl3} function} +% \changes{v1.3h}{2024/04/17} +% {Add a kernel-level copy of \cs{cs_parameter_spec:N}} % \begin{macrocode} \cs_gset_eq:NN \@expl@cs@prefix@spec@@N \cs_prefix_spec:N -\cs_gset_eq:NN \@expl@cs@argument@spec@@N \cs_argument_spec:N +\cs_if_exist:NTF \cs_parameter_spec:N + { \cs_gset_eq:NN \@expl@cs@parameter@spec@@N \cs_parameter_spec:N } + { \cs_gset_eq:NN \@expl@cs@parameter@spec@@N \cs_argument_spec:N } +\cs_gset_eq:NN \__kernel_cs_parameter_spec:N \@expl@cs@parameter@spec@@N \cs_gset_eq:NN \@expl@cs@replacement@spec@@N \cs_replacement_spec:N % \end{macrocode} % @@ -387,7 +397,7 @@ %\let \@expl@cs@to@str@@N \@undefined %\let \@expl@str@if@eq@@nnTF \@undefined %\let \@expl@cs@prefix@spec@@N \@undefined -%\let \@expl@cs@argument@spec@@N \@undefined +%\let \@expl@cs@parameter@spec@@N \@undefined %\let \@expl@cs@replacement@spec@@N \@undefined %\let \@expl@str@map@function@@NN \@undefined %\EndIncludeInRelease diff --git a/Master/texmf-dist/source/latex/base/ltfilehook.dtx b/Master/texmf-dist/source/latex/base/ltfilehook.dtx index 4f88b928712..02e95d0f8fa 100644 --- a/Master/texmf-dist/source/latex/base/ltfilehook.dtx +++ b/Master/texmf-dist/source/latex/base/ltfilehook.dtx @@ -30,16 +30,22 @@ % %%% From File: ltfilehook.dtx % -% \begin{macrocode} -\providecommand\ltfilehookversion{v1.0o} -\providecommand\ltfilehookdate{2023/07/10} -% \end{macrocode} -% +% \fi +%\iffalse +%<*driver,structuredlog> +%\fi +\def\ltfilehookdate{2024/03/13} +\def\ltfilehookversion{v1.0o} +%\iffalse +% %<*driver> - +%\fi +\expanded{\noexpand\ProvidesFile{ltfilehook.dtx} +[\ltfilehookdate\space \ltfilehookversion\space LaTeX Kernel (hooks)]} +% \iffalse +% \documentclass{l3doc} - \providecommand\InternalDetectionOff{} \providecommand\InternalDetectionOn{} @@ -375,7 +381,7 @@ % % % -% \subsection{Internal interfaces for \LaTeX{}} +% \subsection{Kernel, class, and package interfaces for \LaTeX{}} % % \begin{function}{\declare@file@substitution,\undeclare@file@substitution} % \begin{syntax} @@ -393,6 +399,8 @@ % example, or to provide a version that makes use of new kernel % functionality while the original package remains available for % use with older releases. +% As such it is mainly meant for use in the \LaTeX{} kernel but +% other use cases are conceivable. % % The \cs{undeclare@file@substitution} declaration undoes a % substitution made earlier. @@ -407,10 +415,10 @@ % % \begin{function}{\disable@package@load,\reenable@package@load} % \begin{syntax} -% \cs{disable@package@load} \Arg{package} \Arg{alternate-code} +% \cs{disable@package@load} \Arg{package} \Arg{alternate-code} % \cs{reenable@package@load} \Arg{package} % \end{syntax} -% If \meta{package} is requested do not load it but instead run +% If \meta{package} is requested, do not load it but instead run % \meta{alternate-code} which could issue a warning, error or any % other code. % @@ -421,7 +429,9 @@ % are not available. % % The function is only implemented for packages not for arbitrary -% files. +% files and again it should only be applied if there are good +% reasons for doing this.\footnote{Just to be sure: \enquote{I don't +% like this package by somebody else} is not a good one :-)} % \end{function} % % @@ -1328,7 +1338,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{flag @@_file_replaced} +% \begin{macro}{@@_file_replaced} % \begin{macro}{\@@_if_file_replaced:TF} % \begin{macro}{\@@_clear_replacement_flag:} % Since the file replacement is done expandably in a \cs{csname}, use diff --git a/Master/texmf-dist/source/latex/base/ltfiles.dtx b/Master/texmf-dist/source/latex/base/ltfiles.dtx index 92a957f6c51..2e2a8884a01 100644 --- a/Master/texmf-dist/source/latex/base/ltfiles.dtx +++ b/Master/texmf-dist/source/latex/base/ltfiles.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2023/06/17 v1.2u LaTeX Kernel (File Handling)] + [2024/02/08 v1.2v LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -1087,7 +1087,7 @@ % \texttt{-1} we ensure that we don't get a backslash in front. As a % result we end up with all characters as catcode 12 (plus % spaces). We then sometimes add quotes around the construct -% (removing any existing inner quotes. Sometimes we only remove the +% (removing any existing inner quotes). Sometimes we only remove the % quotes if they have been supplied by the user. There is clearly % some room for improvement. % @@ -1682,6 +1682,22 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\if@listfiles@hashes} +% \changes{v1.2v}{2023/11/15}{Extend file list information} +% \begin{macro}{\if@listfiles@sizes} +% \changes{v1.2v}{2023/11/15}{Extend file list information} +% \begin{macrocode} +\ExplSyntaxOn +\keys_define:nn { __kernel / listfiles } + { + hashes .legacy_if_set:n = @listfiles@hashes , + sizes .legacy_if_set:n = @listfiles@sizes + } +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}{\listfiles} % A preamble command to cause |\end{document}| to list files input % from the main file. @@ -1693,8 +1709,10 @@ % {Stop \cs{listfiles} being run twice} % \changes{v1.0i}{1994/10/18} % {code moved here from ltclass} +% \changes{v1.2v}{2023/11/15}{Extend file list information} % \begin{macrocode} -\def\listfiles{% +\NewDocumentCommand\listfiles{O{}}{% + \SetKeys[__kernel/listfiles]{#1}% \let\listfiles\relax \def\@listfiles##1##2##3##4##5##6##7##8##9\@@{% \def\reserved@d{\\}% @@ -1730,9 +1748,40 @@ \filename@area\filename@base\\\\\\\\\\\\\\\\\\\@@ \typeout{% \filename@area\reserved@a - \ifx\reserved@b\relax\else\@spaces\reserved@b\fi}}% + \ifx\reserved@b\relax\else\@spaces\reserved@b\fi +% \end{macrocode} +% Now we add the additional information if requested. +% \begin{macrocode} + \ifnum0% + \if@listfiles@hashes1\fi + \if@listfiles@sizes1\fi + >0 % + ^^J\@spaces + (% + \if@listfiles@sizes + size \@dofilelist@size\@currname + \if@listfiles@hashes + , % + \fi + \fi + \if@listfiles@hashes + hash \@dofilelist@hash\@currname + \fi + )% + \fi + }}% \typeout{ ***********^^J}}} % \end{macrocode} +% \begin{macro}{\@dofilelist@hash} +% \begin{macro}{\@dofilelist@size} +% \begin{macrocode} +\ExplSyntaxOn +\cs_new_eq:NN \@dofilelist@hash \file_mdfive_hash:n +\cs_new_eq:NN \@dofilelist@size \file_size:n +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% \end{macro} % % \changes{LaTeX2e}{1994/03/13} % {Reset \cs{@addtofilelist} at begin document} diff --git a/Master/texmf-dist/source/latex/base/ltfinal.dtx b/Master/texmf-dist/source/latex/base/ltfinal.dtx index f495cd41928..648e3e1b8bd 100644 --- a/Master/texmf-dist/source/latex/base/ltfinal.dtx +++ b/Master/texmf-dist/source/latex/base/ltfinal.dtx @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2023/05/30 v2.3c LaTeX Kernel (Final Settings)] + [2024/02/08 v2.3c LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -273,7 +273,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{trace\string_stack\string_levels} +% \begin{macro}{trace_stack_levels} % Now define the Lua function to emulate \cs{tracingstacklevels} and % install it in the |input_level_string| callback. % \begin{macrocode} @@ -1384,7 +1384,7 @@ % \end{macro} % % \begin{macro}{\@filelist} -% \changes{v1.0w}{1995/10/19}{Move after \cs{reserved@a} setting:-)} +% \changes{v1.0w}{1995/10/19}{Move after \cs{reserved@a} setting} % \begin{macro}{\@addtofilelist} % Reset |\@filelist| so files input while making the format are not % listed. The list built up so far may take up a lot of memory and so diff --git a/Master/texmf-dist/source/latex/base/ltfloat.dtx b/Master/texmf-dist/source/latex/base/ltfloat.dtx index a07e5e81dae..ef057def0b8 100644 --- a/Master/texmf-dist/source/latex/base/ltfloat.dtx +++ b/Master/texmf-dist/source/latex/base/ltfloat.dtx @@ -31,7 +31,7 @@ % %<*driver> % \fi -\ProvidesFile{ltfloat.dtx}[2021/10/14 v1.2g LaTeX Kernel (Floats)] +\ProvidesFile{ltfloat.dtx}[2024/04/22 v1.2g LaTeX Kernel (Floats)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfloat.dtx} @@ -559,7 +559,7 @@ % set globally to false when they are definitely true. % % If anyone is unhappy with this argument then both flags should be -% treated as in |\set@nobreak|; otherwise this command will be +% treated as in |\@setnobreak|; otherwise this command will be % redundant. % \changes{v1.1p}{1996/10/24} % {Added local settings of flags: dangerous!!} @@ -1061,7 +1061,7 @@ % set globally to false when they are definitely true. % % If anyone is unhappy with this argument then both flags should be -% treated as in |\set@nobreak|; otherwise this command will be +% treated as in |\@setnobreak|; otherwise this command will be % redundant. % \changes{v1.1p}{1996/10/24} % {Added local settings of flags: dangerous!!} diff --git a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx index 360a4de8a49..097b8f692e4 100644 --- a/Master/texmf-dist/source/latex/base/ltfntcmd.dtx +++ b/Master/texmf-dist/source/latex/base/ltfntcmd.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfntcmd.dtx} - [2021/09/12 v3.5a LaTeX Kernel (Font commands)] + [2023/12/26 v3.5a LaTeX Kernel (Font commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfntcmd.dtx} @@ -393,9 +393,9 @@ % \end{macro} -% \begin{macro}{textulc} -% \begin{macro}{textsw} -% \begin{macro}{textssc} +% \begin{macro}{\textulc} +% \begin{macro}{\textsw} +% \begin{macro}{\textssc} % % \changes{v3.4c}{2019/12/17}{Macro added} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx index 6fefa5cee9a..8b5014a4cc1 100644 --- a/Master/texmf-dist/source/latex/base/ltfssaxes.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssaxes.dtx @@ -28,14 +28,14 @@ % \fi % \iffalse %%% From File: ltfssaxes.dtx -%% Copyright (C) 1999-2020 Frank Mittelbach +%% Copyright (C) 2019-2020 Frank Mittelbach % %<*driver> % \fi % % \ProvidesFile{ltfssaxes.dtx} - [2023/10/30 v1.0i LaTeX Kernel (NFSS Axes handing)] + [2024/02/08 v1.0i LaTeX Kernel (NFSS Axes handing)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -1087,7 +1087,7 @@ % % Shapes are also split in two axes (though it could be more if % that is desirable), essentially building in an ``sc'' -% axis). +% axis. % % \begin{macrocode} %<*2ekernel|latexrelease> @@ -1118,7 +1118,7 @@ % 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 +% 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. % @@ -1494,7 +1494,7 @@ % provide. So its redefinitions for the various shape commands, % such as \cs{itshape} should no longer happen. We therefore force % the standard definitions at \cs{AtBeginDocument} (later when this -% is defined. Once +% is defined). Once % \texttt{fontaxes} is no longer doing such redefinitions that could % be taken out again. % diff --git a/Master/texmf-dist/source/latex/base/ltfssbas.dtx b/Master/texmf-dist/source/latex/base/ltfssbas.dtx index eaea328dac3..df02a5749a7 100644 --- a/Master/texmf-dist/source/latex/base/ltfssbas.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssbas.dtx @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2023/10/21 v3.2l LaTeX Kernel (NFSS Basic Macros)] + [2024/02/08 v3.2l LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -962,7 +962,7 @@ % case, however, we also need the value of |\baselineskip|. As the % first argument to |\set@fontsize| we pass the current value of % |\baselinestretch|. This will either match the internal value (in -% which case nothing changes, or it will be an updated value due to +% which case nothing changes) or it will be an updated value due to % a user change of that macro using |\renewcommand|. If we would % pass the internal |\f@linespread| such a change would be % effectively overwritten by a size change. diff --git a/Master/texmf-dist/source/latex/base/ltfssini.dtx b/Master/texmf-dist/source/latex/base/ltfssini.dtx index 273ed4babd3..255abe03f3a 100644 --- a/Master/texmf-dist/source/latex/base/ltfssini.dtx +++ b/Master/texmf-dist/source/latex/base/ltfssini.dtx @@ -36,7 +36,7 @@ % % \ProvidesFile{ltfssini.dtx} - [2021/09/10 v3.2i LaTeX Kernel (NFSS Initialisation)] + [2024/02/08 v3.2i LaTeX Kernel (NFSS Initialisation)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -864,7 +864,7 @@ % % If \cs{bfdefault} and \cs{bfdefault@previous} are different then % the default got changed directly through the legacy interface -% (i.e., via \cs{def} or \cs{renewcommand}. In that case we reset +% (i.e., via \cs{def} or \cs{renewcommand}). In that case we reset % all meta family defaults so that the document behaves like it was % the case before the new mechanism was introduced. % \changes{v3.1k}{2020/03/19}{Support legacy use of \cs{bfdefault} @@ -885,7 +885,7 @@ \let\bfdefault@previous\bfdefault % \end{macrocode} % And we reset the meta family defaults (\cs{bfdef@ult} is an -% expanded version of \cs{bfdefault}. +% expanded version of \cs{bfdefault}). % \begin{macrocode} \let\bfseries@rm\bfdef@ult \let\bfseries@sf\bfdef@ult @@ -1661,8 +1661,8 @@ % \begin{macrocode} \def\emfontdeclare@clist{#2,#1}% % \end{macrocode} -% Then we execute current declaration. Appending |\selectfont| means one -% can write just |\fontshape{it}}| and that works then too. +% Then we execute the current declaration. Appending |\selectfont| means one +% can write just |\fontshape{it}| and that works then too. % \begin{macrocode} % \typeout{Use: \detokenize{#1}}% #1\selectfont diff --git a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx index f5dc2ad5898..4f0e43021aa 100644 --- a/Master/texmf-dist/source/latex/base/ltfsstrc.dtx +++ b/Master/texmf-dist/source/latex/base/ltfsstrc.dtx @@ -37,7 +37,7 @@ % [2020/12/22 v3.0n Standard LaTeX package (font tracing)] % \fi % \ProvidesFile{ltfsstrc.dtx} -% [2021/04/26 v3.0o LaTeX Kernel (NFSS tracing)] +% [2024/02/08 v3.0o LaTeX Kernel (NFSS tracing)] % % \iffalse %<+checkmem>\CHECKMEM @@ -125,7 +125,7 @@ % % \item[debugshow] In addition to \texttt{infoshow} show also % changing of math fonts as far as possible (this option can produce a -% large amount of output. +% large amount of output). % % \item[loading] Show the name of external fonts when they are % loaded. This option shows only ``newly'' loaded fonts not those @@ -489,8 +489,8 @@ \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 +% Then we run the delayed adjustments (which use the +% \cs{..@without@substitution} commands): % \begin{macrocode} \delayed@f@adjustment % \end{macrocode} @@ -863,14 +863,15 @@ % % \TeX{} uses the math fonts that are current when the end of a % formula is reached. If we don't want to keep font setups local to -% every formula (which would result in an enormous overhead, we have +% every formula (which would result in an enormous overhead), we have % to be careful not to end up with the wrong setup in case formulas % are nested, e.g., we need to be able to handle % \begin{verbatim} % $ a=b+c \mbox{ \small for all $b$ and $c\in Z$}$ %\end{verbatim} % Here the inner formulae |b| and |c\in Z| are typeset in |\small| but -% we have to return to |\normalsize| before we reach the closing |$| +% we have to return to |\normalsize| before we reach the +% closing |$| \iffalse$\fi % of the outer formula. % % This is handled in the following way: @@ -1042,8 +1043,8 @@ % If so we first call the `=' macro (i.e.\ argument three) to set % up special things for the selected math group. Then we call % |\mathgroup| to select the group given by argument two and -% finally we place |#1| (i.e.\ the argument of the \meta{math -% alphabet identifier} at the end. This part of the code is +% finally we place |#1| (i.e., the argument of the \meta{math +% alphabet identifier}) at the end. This part of the code is % surrounded by two commands which behave like |\begingroup| % and |\endgroup| if we want \meta{math alphabet identifier}s % but will expand into |\@empty| if we want simply switches to @@ -1081,7 +1082,7 @@ % \begin{macro}{\math@egroup} % \changes{v1.0q}{1990/07/07}{Tracing code added.} If the % \texttt{margid} option is in force (which can be tested by -% looking at the definition of |\math@bgroup| we change the +% looking at the definition of |\math@bgroup|) we change the % |\math@egroup| command a bit to display the current \meta{math % group number} after it closes the scope of \meta{math alphabet} % with |\endgroup|. @@ -1385,7 +1386,7 @@ % It looks for font ranges with font size functions. It's operation % is rather simple: it discards everything up to the next size % specification and passes this on to |\is@range| for inspection. -% The specification (parameter |#2| is inserted again, in case +% The specification (parameter |#2|) is inserted again, in case % it is needed later. % \begin{macrocode} \def\extract@rangefontinfo#1<#2>{% @@ -1402,7 +1403,7 @@ % % From the way |\is@range| is called inside |\extract@rangefontinfo| % we see that |#2| is the character |>| if the size specification -% found is a simple one (as it does not contain a |-| character. +% found is a simple one (that does not contain a |-| character). % This is checked easily enough and |\extract@rangefontinfo| % called again. Note that the extra tokens inserted after the % |\@nil| in the call to |\is@range| appear at the beginning of diff --git a/Master/texmf-dist/source/latex/base/lthooks.dtx b/Master/texmf-dist/source/latex/base/lthooks.dtx index 446cdaae060..d282ff841c7 100644 --- a/Master/texmf-dist/source/latex/base/lthooks.dtx +++ b/Master/texmf-dist/source/latex/base/lthooks.dtx @@ -27,17 +27,16 @@ % \fi % % \iffalse -% %%% From File: lthooks.dtx % -% \begin{macrocode} -\def\lthooksversion{v1.1f} -\def\lthooksdate{2023/10/02} -% \end{macrocode} -% %<*driver> +% \fi +\ProvidesFile{lthooks.dtx} + [2024/04/22 v1.1h LaTeX Kernel (hooks)] +% \iffalse +% \documentclass{l3doc} - +\GetFileInfo{lthooks.dtx} \providecommand\InternalDetectionOff{} \providecommand\InternalDetectionOn{} @@ -62,7 +61,7 @@ % % % \title{\LaTeX{}'s hook management\thanks{This module has version -% \lthooksversion\ dated \lthooksdate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % % \author{Frank Mittelbach\thanks{Code improvements for speed and other goodies by Phelype Oleinik}} @@ -160,7 +159,7 @@ % \end{function} % % -% \begin{function}{\NewHookWithArguments} +% \begin{function}[added=2023-06-01]{\NewHookWithArguments} % \begin{syntax} % \cs{NewHookWithArguments} \Arg{hook} \Arg{number} % \end{syntax} @@ -172,7 +171,7 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % -% \begin{function}{\NewReversedHookWithArguments} +% \begin{function}[added=2023-06-01]{\NewReversedHookWithArguments} % \begin{syntax} % \cs{NewReversedHookWithArguments} \Arg{hook} \Arg{number} % \end{syntax} @@ -184,7 +183,7 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % -% \begin{function}{\NewMirroredHookPairWithArguments} +% \begin{function}[added=2023-06-01]{\NewMirroredHookPairWithArguments} % \begin{syntax} % \cs{NewMirroredHookPairWithArguments} \Arg{hook-1} \Arg{hook-2} \Arg{number} % \end{syntax} @@ -234,9 +233,9 @@ % (e.g., one used in code with \cs{UseHook} or % \cs{UseOneTimeHook}) without it being explicitly declared with % \cs{NewHook}). -% This command undoes the effect of \cs{DisableGenericHook}. % If the hook is already activated, this command does nothing. % +% Note that this command does not undo the effect of \cs{DisableGenericHook}. % See section~\ref{sec:generic-hooks} for a discussion of when this % declaration is appropriate. % \end{function} @@ -264,7 +263,7 @@ % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\UseHookWithArguments} +% \begin{function}[added=2023-06-01]{\UseHookWithArguments} % \begin{syntax} % \cs{UseHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} @@ -314,7 +313,7 @@ % % \end{function} % -% \begin{function}{\UseOneTimeHookWithArguments} +% \begin{function}[added=2023-06-01]{\UseOneTimeHookWithArguments} % \begin{syntax} % \cs{UseOneTimeHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} @@ -340,7 +339,7 @@ % % \begin{function}{\AddToHook} % \begin{syntax} -% \cs{AddToHook} \Arg{hook}\oarg{label}\Arg{code} +% \cs{AddToHook} \Arg{hook} \oarg{label} \Arg{code} % \end{syntax} % Adds \meta{code} to the \meta{hook} labeled by \meta{label}. % When the optional argument \meta{label} is not provided, the @@ -368,9 +367,9 @@ % See section~\ref{sec:default-label}. % \end{function} % -% \begin{function}{\AddToHookWithArguments} +% \begin{function}[added=2023-06-01]{\AddToHookWithArguments} % \begin{syntax} -% \cs{AddToHookWithArguments} \Arg{hook}\oarg{label}\Arg{code} +% \cs{AddToHookWithArguments} \Arg{hook} \oarg{label} \Arg{code} % \end{syntax} % Works exactly like \cs{AddToHook}, except that the \meta{code} can % access the arguments passed to the hook using \verb|#1|, \verb|#2|, @@ -398,7 +397,7 @@ % % \begin{function}{\RemoveFromHook} % \begin{syntax} -% \cs{RemoveFromHook} \Arg{hook}\oarg{label} +% \cs{RemoveFromHook} \Arg{hook} \oarg{label} % \end{syntax} % Removes any code labeled by \meta{label} from the \meta{hook}. % When the optional argument \meta{label} is not provided, the @@ -459,7 +458,7 @@ % % \begin{function}{\AddToHookNext} % \begin{syntax} -% \cs{AddToHookNext} \Arg{hook}\Arg{code} +% \cs{AddToHookNext} \Arg{hook} \Arg{code} % \end{syntax} % Adds \meta{code} to the next invocation of the \meta{hook}. % The code is executed after the normal hook code has finished and @@ -505,9 +504,9 @@ % \end{function}\footnotetext{There is % no mechanism to reorder such code chunks (or delete them).} % -% \begin{function}{\AddToHookNextWithArguments} +% \begin{function}[added=2023-06-01]{\AddToHookNextWithArguments} % \begin{syntax} -% \cs{AddToHookNextWithArguments} \Arg{hook}\Arg{code} +% \cs{AddToHookNextWithArguments} \Arg{hook} \Arg{code} % \end{syntax} % Works exactly like \cs{AddToHookNext}, but the \meta{code} can % contain references to the arguments of the \meta{hook} as described @@ -522,7 +521,7 @@ % % \begin{function}{\ClearHookNext} % \begin{syntax} -% \cs{ClearHookNext}\Arg{hook} +% \cs{ClearHookNext} \Arg{hook} % \end{syntax} % Normally \cs{AddToHookNext} is only used when you know precisely % where it will apply and why you want some extra code at that @@ -746,7 +745,7 @@ % % \begin{function}{\DeclareHookRule} % \begin{syntax} -% \cs{DeclareHookRule} \Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2} +% \cs{DeclareHookRule} \Arg{hook} \Arg{label1} \Arg{relation} \Arg{label2} % \end{syntax} % Defines a relation between \meta{label1} and \meta{label2} for a % given \meta{hook}. If \meta{hook} is \texttt{??} this defines a default @@ -807,7 +806,7 @@ % % \begin{function}{\ClearHookRule} % \begin{syntax} -% \cs{ClearHookRule}\Arg{hook}\Arg{label1}\Arg{label2} +% \cs{ClearHookRule} \Arg{hook} \Arg{label1} \Arg{label2} % \end{syntax} % Syntactic sugar for saying that \meta{label1} and \meta{label2} % are unrelated for the given \meta{hook}. @@ -817,7 +816,7 @@ % % \begin{function}{\DeclareDefaultHookRule} % \begin{syntax} -% \cs{DeclareDefaultHookRule}\Arg{label1}\Arg{relation}\Arg{label2} +% \cs{DeclareDefaultHookRule} \Arg{label1} \Arg{relation} \Arg{label2} % \end{syntax} % This sets up a relation between \meta{label1} and \meta{label2} % for all hooks unless overwritten by a specific rule for a hook. @@ -1004,7 +1003,7 @@ % % \begin{function}{\DebugHooksOn,\DebugHooksOff} % \begin{syntax} -% \cs{DebugHooksOn} +% \cs{DebugHooksOn} \ldots\ \cs{DebugHooksOff} % \end{syntax} % 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 @@ -1044,7 +1043,7 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % -% \begin{function}{ +% \begin{function}[added=2023-06-01]{ % \hook_new_with_args:nn, % \hook_new_reversed_with_args:nn, % \hook_new_pair_with_args:nnn @@ -1100,9 +1099,14 @@ % % % -% \begin{function}{\hook_use:n,\hook_use:nnw} +% \begin{function}{\hook_use:n} +% \begin{syntax} +% ~~\cs{hook_use:n} \Arg{hook} +% \end{syntax} +% \end{function} +% \vskip-1.2\baselineskip +% \begin{function}[added=2023-06-01]{\hook_use:nnw} % \begin{syntax} -% \cs{hook_use:n} \Arg{hook} % \cs{hook_use:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % Executes the \Arg{hook} code followed (if set up) by the code for next @@ -1118,9 +1122,14 @@ % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\hook_use_once:n,\hook_use_once:nnw} +% \begin{function}{\hook_use_once:n} % \begin{syntax} % \cs{hook_use_once:n} \Arg{hook} +% \end{syntax} +% \end{function} +% \vskip-1.2\baselineskip +% \begin{function}[added=2023-06-01]{\hook_use_once:nnw} +% \begin{syntax} % \cs{hook_use_once:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % Changes the \Arg{hook} status so that from now on any addition to @@ -1139,10 +1148,16 @@ % % \begin{function}{ % \hook_gput_code:nnn, +% } +% \begin{syntax} +% ~~~~~~~~~\cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code} +% \end{syntax} +% \end{function} +% \vskip -1.2\baselineskip +% \begin{function}[added=2023-06-01]{ % \hook_gput_code_with_args:nnn % } % \begin{syntax} -% \cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code} % \cs{hook_gput_code_with_args:nnn} \Arg{hook} \Arg{label} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} to the \meta{hook} labeled @@ -1168,10 +1183,17 @@ % % \begin{function}{ % \hook_gput_next_code:nn, +% } +% \begin{syntax} +% ~~~~~~~~~~~~~\cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code} +% \end{syntax} +% \end{function} +% \vskip-1.2\baselineskip +% \begin{function}[added=2023-06-01]{ % \hook_gput_next_code_with_args:nn, % } % \begin{syntax} -% \cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code} +% \cs{hook_gput_next_code_with_args:nn} \Arg{hook} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} for use only in the next invocation of the % \meta{hook}. Once used it is gone. @@ -1183,6 +1205,7 @@ % In that case, if an actual parameter token should be added to the % code, it should be doubled. % +% \end{function} % This is simpler than \cs{hook_gput_code:nnn}, the code is simply % appended to the hook in the order of declaration at the very end, % i.e., after all standard code for the hook got executed. @@ -1191,7 +1214,6 @@ % % 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_gclear_next_code:n} @@ -1527,7 +1549,7 @@ % \hook{cmd}, % \hook{env}, % \hook{file}, -% \hook{include} +% \hook{include}, % \hook{package}, and % \hook{class}, % and all these are available out of the box: you only have to @@ -1862,15 +1884,17 @@ % \item[\hook{env/\meta{env}/begin}] % % This hook is executed as part of \cs{begin} directly in front -% of the code specific to the environment start (e.g., the -% second argument of \cs{newenvironment}). Its scope is the -% environment body. +% of the code specific to the environment start (e.g., +% the third argument of \cs{NewDocumentEnvironment} and +% the second argument of \cs{newenvironment}). +% Its scope is the environment body. % % \item[\hook{env/\meta{env}/end}] % % This hook is executed as part of \cs{end} directly in front of the -% code specific to the end of the environment (e.g., the third -% argument of \cs{newenvironment}). +% code specific to the end of the environment (e.g., +% the forth argument of \cs{NewDocumentEnvironment} and +% the third argument of \cs{newenvironment}). % % \item[\hook{env/\meta{env}/after}] % @@ -2701,7 +2725,7 @@ % \hook_new:n, % \hook_new_with_args:nn % } -% \begin{macro}{@@_new:nn} +% \begin{macro}{\@@_new:nn} % The \cs{hook_new:n} declaration declares a new hook and expects % the hook \meta{name} as its argument, e.g., % \hook{begindocument}. @@ -3509,7 +3533,8 @@ \msg_error:nnnnn { hooks } { set-top-level } { for } { SetDefaultHookLabel } {#1} } - { \exp_args:Nx \@@_set_default_label:n { \@@_make_name:n {#1} } } + { \exp_args:Nx + \@@_set_default_label:n { \@@_make_name:n {#1} } } } \cs_new_protected:Npn \@@_set_default_label:n #1 { @@ -3722,7 +3747,8 @@ %\IncludeInRelease{2020/10/01}{\hook_gput_code:nnn} % {Providing~hooks} %\cs_gset_protected:Npn \hook_gput_code:nnn #1 #2 -% { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +% { \@@_normalize_hook_args:Nnn +% \@@_gput_code:nnn {#1} {#2} } %\cs_gset_protected:Npn \@@_gput_code:nnn #1 #2 #3 % { % \@@_if_execute_immediately:nTF {#1} @@ -3736,7 +3762,8 @@ % { % \@@_if_disabled:nTF {#1} % { \msg_error:nnn { hooks } { hook-disabled } {#1} } -% { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } +% { \@@_try_declaring_generic_hook:nnn +% {#1} {#2} {#3} } % } % } % } @@ -3748,7 +3775,8 @@ % \on@line\space <-~ \tl_to_str:n{#3}} } % \str_if_eq:nnTF {#2} { top-level } % { -% \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } +% \str_if_eq:eeTF { top-level } +% { \@@_currname_or_default: } % { % \@@_init_structure:n {#1} % \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} @@ -3756,7 +3784,8 @@ % { \msg_error:nnn { hooks } { misused-top-level } {#1} } % } % { -% \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +% \prop_get:cnNTF +% { g_@@_#1_code_prop } {#2} \l_@@_return_tl % { % \prop_gput:cno { g_@@_#1_code_prop } {#2} % { \l_@@_return_tl #3 } @@ -3840,7 +3869,8 @@ % \changes{v1.1d}{2023/05/21} % {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} -%\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:nnn} +%\IncludeInRelease{2023/06/01} +% {\@@_try_declaring_generic_hook:nnn} % {Hooks~with~args} \cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 { @@ -3857,31 +3887,38 @@ {#1} } %\EndIncludeInRelease -%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn} +%\IncludeInRelease{2021/11/15} +% {\@@_try_declaring_generic_hook:nnn} % {Standardise~generic~hook~names} %\cs_gset_protected:Npn \@@_try_declaring_generic_hook:nnn #1 % { -% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: +% {#1} % \hook_gput_code:nnn % \@@_gput_undeclared_hook:nnn % {#1} % } -%\cs_gset_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 +%\cs_gset_protected:Npn +% \@@_try_declaring_generic_next_hook:nn #1 % { -% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: +% {#1} % \hook_gput_next_code:nn % \@@_gput_next_do:nn % {#1} % } %\EndIncludeInRelease -%\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:nnn} +%\IncludeInRelease{2020/10/01} +% {\@@_try_declaring_generic_hook:nnn} % {Standardise~generic~hook~names} -%\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 +%\cs_new_protected:Npn +% \@@_try_declaring_generic_hook:nnn #1 % { % \@@_try_declaring_generic_hook:nNNnn {#1} % \hook_gput_code:nnn \@@_gput_undeclared_hook:nnn % } -%\cs_new_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 +%\cs_new_protected:Npn +% \@@_try_declaring_generic_next_hook:nn #1 % { % \@@_try_declaring_generic_hook:nNNnn {#1} % \hook_gput_next_code:nn \@@_gput_next_do:nn @@ -3904,12 +3941,15 @@ % % \changes{v1.0s}{2021/09/28} % {Correct usage of older \cs{@@_if_file_hook:wTF} (gh/675)} +% \changes{v1.1h}{2024/01/24} +% {Correct usage of older \cs{@@_if_file_hook:wTF} (gh/1243)} % \begin{macrocode} %\cs_new_protected:Npn \@@_try_declaring_generic_hook:nNNnn #1 % { -% \@@_if_file_hook:wTF #1 / \s_@@_mark +% \@@_if_file_hook:wTF #1 / / \s_@@_mark % { -% \exp_args:Ne \@@_try_declaring_generic_hook_split:nNNnn +% \exp_args:Ne +% \@@_try_declaring_generic_hook_split:nNNnn % { \exp_args:Ne \@@_file_hook_normalize:n {#1} } % } % { \@@_try_declaring_generic_hook_split:nNNnn {#1} } @@ -3917,9 +3957,11 @@ % \end{macrocode} % % \begin{macrocode} -%\cs_new_protected:Npn \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3 +%\cs_new_protected:Npn +% \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3 % { -% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +% \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: +% {#1} % { #2 } % { #3 } {#1} % } @@ -3931,9 +3973,11 @@ % \changes{v1.1a}{2023/04/06} % {Changes to add hook arguments (hook-args).} % \begin{macrocode} -%\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:wn} +%\IncludeInRelease{2023/06/01} +% {\@@_try_declaring_generic_hook:wn} % {Hooks~with~args} -\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +\prg_new_protected_conditional:Npnn + \@@_try_declaring_generic_hook:wn #1 / #2 / #3 / #4 \scan_stop: #5 { TF } { \@@_if_generic:nTF {#5} @@ -4052,9 +4096,11 @@ % \end{macro} % % \begin{macrocode} -%\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn} +%\IncludeInRelease{2021/11/15} +% {\@@_try_declaring_generic_hook:wn} % {Standardise~generic~hook~names} -%\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +%\prg_new_protected_conditional:Npnn +% \@@_try_declaring_generic_hook:wn % #1 / #2 / #3 / #4 \scan_stop: #5 { TF } % { % \@@_if_generic:nTF {#5} @@ -4083,9 +4129,11 @@ % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2021/06/01}{\@@_try_declaring_generic_hook:wn} +%\IncludeInRelease{2021/06/01} +% {\@@_try_declaring_generic_hook:wn} % {Support~cmd~hooks} -%\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +%\prg_new_protected_conditional:Npnn +% \@@_try_declaring_generic_hook:wn % #1 / #2 / #3 / #4 \scan_stop: #5 { TF } % { % \tl_if_empty:nTF {#2} @@ -4099,10 +4147,12 @@ % { \@@_try_put_cmd_hook:n {#5} } % \@@_make_usable:n {#5} % } -% \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2} +% \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} +% \prop_if_in:NnT +% \c_@@_generics_reversed_iii_prop {#3} % { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } % } % \prg_return_true: @@ -4114,9 +4164,11 @@ % \end{macrocode} % % \begin{macrocode} -%\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn} +%\IncludeInRelease{2020/10/01} +% {\@@_try_declaring_generic_hook:wn} % {Support~cmd~hooks} -%\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +%\prg_new_protected_conditional:Npnn +% \@@_try_declaring_generic_hook:wn % #1 / #2 / #3 / #4 \scan_stop: #5 { TF } % { % \tl_if_empty:nTF {#2} @@ -4125,10 +4177,12 @@ % \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} +% \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} +% \prop_if_in:NnT +% \c_@@_generics_reversed_iii_prop {#3} % { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } % } % \prg_return_true: @@ -4204,11 +4258,11 @@ % \changes{v1.0h}{2021/01/07}{Assume hook name has at least three % nonempty parts (gh/464)} % \begin{macrocode} -%\cs_new:Npn \@@_strip_double_slash:w #1/#2/#3 // #4 \s_@@_mark +%\cs_new:Npn \@@_strip_double_slash:w #1/#2/#3//#4\s_@@_mark % { % \tl_if_empty:nTF {#4} % { #1/#2/#3 } -% { \@@_strip_double_slash:w #1/#2/#3 / #4 \s_@@_mark } +% { \@@_strip_double_slash:w #1/#2/#3 /#4\s_@@_mark } % } %\EndIncludeInRelease % \end{macrocode} @@ -4287,9 +4341,12 @@ % \begin{macrocode} %\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop} % {Standardise~generic~hook~names} -%\prop_const_from_keyval:Nn \c_@@_generics_reversed_ii_prop {after=,end=} -%\prop_const_from_keyval:Nn \c_@@_generics_reversed_iii_prop {after=} -%\prop_const_from_keyval:Nn \c_@@_generics_file_prop {before=,after=} +%\prop_const_from_keyval:Nn +% \c_@@_generics_reversed_ii_prop {after=,end=} +%\prop_const_from_keyval:Nn +% \c_@@_generics_reversed_iii_prop {after=} +%\prop_const_from_keyval:Nn +% \c_@@_generics_file_prop {before=,after=} %\EndIncludeInRelease % \end{macrocode} % \end{macro} @@ -4369,7 +4426,8 @@ \str_if_eq:nnTF {#2} { top-level } { \@@_toplevel_gset:nn {#1} { } } { - \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl + \prop_gpop:cnNF { g_@@_#1_code_prop } + {#2} \l_@@_return_tl { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } } } @@ -4387,7 +4445,8 @@ \@@_if_deprecated_generic:nTF {#1} { \@@_deprecated_generic_warn:n {#1} - \@@_do_deprecated_generic:Nn \@@_gremove_code:nn {#1} {#2} + \@@_do_deprecated_generic:Nn + \@@_gremove_code:nn {#1} {#2} } { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } } @@ -4412,8 +4471,10 @@ % \str_if_eq:nnTF {#2} { top-level } % { \@@_tl_gclear:c { @@_toplevel~#1 } } % { -% \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl -% { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +% \prop_gpop:cnNF { g_@@_#1_code_prop } +% {#2} \l_@@_return_tl +% { \msg_warning:nnnn { hooks } { cannot-remove } +% {#1} {#2} } % } % } % \@@_if_usable:nT {#1} @@ -4423,9 +4484,11 @@ % \@@_if_deprecated_generic:nTF {#1} % { % \@@_deprecated_generic_warn:n {#1} -% \@@_do_deprecated_generic:Nn \@@_gremove_code:nn {#1} {#2} +% \@@_do_deprecated_generic:Nn +% \@@_gremove_code:nn {#1} {#2} % } -% { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +% { \msg_warning:nnnn { hooks } { cannot-remove } +% {#1} {#2} } % } % } %\EndIncludeInRelease @@ -4467,7 +4530,8 @@ {#1} {#2} } \cs_new_protected:Npn \@@_cs_gput_right_fast:nnn #1 #2 #3 - { \cs_gset:cpx { @@#1~#2 } { \exp_not:v { @@#1~#2 } \exp_not:n {#3} } } + { \cs_gset:cpx { @@#1~#2 } + { \exp_not:v { @@#1~#2 } \exp_not:n {#3} } } \cs_new_protected:Npn \@@_cs_gput_right_slow:nnn #1 #2 #3 { % \end{macrocode} @@ -4693,7 +4757,8 @@ % \begin{macrocode} \exp_last_unbraced:NNf \cs_set:Npn \@@_tmp:w { \@@_parameter:n {#1} } { } - \tl_set:Ne \l_@@_tmpa_tl { \@@_braced_cs_parameter:n { @@_tmp:w } } + \tl_set:Ne \l_@@_tmpa_tl + { \@@_braced_cs_parameter:n { @@_tmp:w } } % \end{macrocode} % Now this function does the fun part. It is meant to be used with % \cs{prop_map_function:NN}, taking a label name in \verb|##1| and the @@ -5069,8 +5134,8 @@ % \@@_if_deprecated_generic:nT {#1} % { % \@@_deprecated_generic_warn:n {#1} -% \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn {#1} -% {#2} {#3} {#4} +% \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn +% {#1} {#2} {#3} {#4} % \exp_after:wN \use_none:nnnnnnnnn \use_none:n % } % \@@_init_structure:n {#1} @@ -5110,7 +5175,8 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_before_gset:nnn #1#2#3 { - \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx + { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { < } { > } } } \cs_new_eq:cN { @@_rule_<_gset:nnn } \@@_rule_before_gset:nnn @@ -5119,7 +5185,8 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_after_gset:nnn #1#2#3 { - \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } + \@@_tl_gset:cx + { g_@@_#1_rule_ \@@_label_pair:nn {#3} {#2} _tl } { \@@_label_ordered:nnTF {#3} {#2} { < } { > } } } \cs_new_eq:cN { @@_rule_>_gset:nnn } \@@_rule_after_gset:nnn @@ -5132,7 +5199,8 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_rule_voids_gset:nnn #1#2#3 { - \@@_tl_gset:cx { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } + \@@_tl_gset:cx + { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { \@@_label_ordered:nnTF {#2} {#3} { -> } { <- } } } % \end{macrocode} @@ -5146,11 +5214,15 @@ % 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} % @@ -5268,7 +5340,7 @@ } % \end{macrocode} % After all hooks are initialized we change the ``use'' to just -% call the hook code and not initialize it (as it was done in the +% call the hook code and not initialize it (as this was already done in the % preamble. % \begin{macrocode} \@@_post_initialization_defs: @@ -5281,7 +5353,8 @@ % {Hooks~with~args} %\cs_gset_protected:Npn \@@_initialize_all: % { -% \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n +% \cs_gset_eq:NN \@@_update_hook_code:n +% \@@_initialize_hook_code:n % \@@_debug:n { \prop_gclear:N \g_@@_used_prop } % \seq_map_inline:Nn \g_@@_all_seq % { \@@_update_hook_code:n {##1} } @@ -5291,7 +5364,8 @@ % \prop_map_inline:Nn \g_@@_used_prop % { % \iow_term:x -% { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ } +% { ^^J ~ ##1 ~ -> ~ +% \cs_replacement_spec:c { @@~##1 } ~ } % } % } % \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n @@ -5350,8 +5424,10 @@ % after the \verb|_next| and \verb|_toplevel| macros, so that the % arguments passed to the hook are forwarded to them. % \begin{macrocode} - \exp_not:c { @@_toplevel~#1 } \@@_braced_parameter:n {#1} - \exp_not:c { @@_next~#1 } \@@_braced_parameter:n {#1} + \exp_not:c { @@_toplevel~#1 } + \@@_braced_parameter:n {#1} + \exp_not:c { @@_next~#1 } + \@@_braced_parameter:n {#1} } } { @@ -5400,7 +5476,8 @@ %\cs_gset_protected:Npn \@@_initialize_hook_code:n #1 % { % \@@_debug:n -% { \iow_term:x { ^^J Update~code~for~hook~'#1' \on@line :^^J } } +% { \iow_term:x { ^^J Update~code~for~hook~'#1' +% \on@line :^^J } } % \@@_include_legacy_code_chunk:n {#1} % \@@_if_usable:nT {#1} % { @@ -5414,15 +5491,21 @@ % } % { % \@@_if_reversed:nTF {#1} -% { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_left:Nn -% \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV } -% { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_right:Nn -% \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } -% \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } +% { \cs_set_eq:NN \@@_tl_gput:Nn +% \@@_tl_gput_left:Nn +% \cs_set_eq:NN \@@_clist_gput:NV +% \clist_gput_left:NV } +% { \cs_set_eq:NN \@@_tl_gput:Nn +% \@@_tl_gput_right:Nn +% \cs_set_eq:NN \@@_clist_gput:NV +% \clist_gput_right:NV } +% \prop_set_eq:Nc \l_@@_work_prop +% { g_@@_#1_code_prop } % \@@_initialize_single:ccn % { @@~#1 } { g_@@_#1_labels_clist } {#1} % \@@_debug:n -% { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1} { } } +% { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop +% {#1} { } } % } % } % } @@ -5621,7 +5704,8 @@ \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 { - \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} + \tl_set:cn + { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} \tl_set:Nn \l_@@_rear_tl {##1} } } @@ -5703,42 +5787,50 @@ % {#3} % } % } -% \@@_debug:n { \@@_debug_label_data:N \l_@@_work_prop } +% \@@_debug:n +% { \@@_debug_label_data:N \l_@@_work_prop } % \tl_set:Nn \l_@@_rear_tl { 0 } % \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } % \seq_map_inline:Nn \l_@@_labels_seq % { -% \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 -% { -% \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } }{##1} -% \tl_set:Nn \l_@@_rear_tl {##1} -% } +% \int_compare:nNnT +% { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +% { +% \tl_set:cn { \@@_tl_csname:n +% { \l_@@_rear_tl } } {##1} +% \tl_set:Nn \l_@@_rear_tl {##1} +% } % } % \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { 0 } } % \@@_tl_gclear:N #1 % \clist_gclear:N #2 -% \bool_while_do:nn { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } } +% \bool_while_do:nn +% { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } } % { % \int_decr:N \l_@@_labels_int -% \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl +% \prop_get:NVN \l_@@_work_prop +% \l_@@_front_tl \l_@@_return_tl % \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl % \@@_clist_gput:NV #2 \l_@@_front_tl -% \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } -% \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } } +% \@@_debug:n{ \iow_term:x +% {Handled~ code~ for~ \l_@@_front_tl} } +% \seq_map_inline:cn +% { \@@_seq_csname:n { \l_@@_front_tl } } % { % \tl_set:cx { \@@_tl_csname:n {##1} } -% { \int_eval:n -% { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } -% } +% { \int_eval:n +% { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } +% } % \int_compare:nNnT -% { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 -% { -% \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} -% \tl_set:Nn \l_@@_rear_tl {##1} -% } +% { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +% { +% \tl_set:cn { \@@_tl_csname:n +% { \l_@@_rear_tl } } {##1} +% \tl_set:Nn \l_@@_rear_tl {##1} +% } % } % \tl_set_eq:Nc \l_@@_front_tl -% { \@@_tl_csname:n { \l_@@_front_tl } } +% { \@@_tl_csname:n { \l_@@_front_tl } } % } % \int_compare:nNnF \l_@@_labels_int = 0 % { @@ -5747,7 +5839,8 @@ % \@@_debug_label_data:N \l_@@_work_prop % \iow_term:x{====================} % } -% \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } +% \exp_args:NNo \@@_tl_gput:Nn #1 +% { \cs:w @@_toplevel~#3 \cs_end: } % \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } % } %\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No } @@ -6008,6 +6101,8 @@ % % \changes{v1.1a}{2023/04/06} % {Changes to add hook arguments (hook-args).} +% \changes{v1.1g}{2024/01/03} +% {Fix expansion of \cs{@@_print_args:nn} argument (gh/1221).} % \begin{macrocode} %\IncludeInRelease{2023/06/01}{\@@_log:nN} % {Hooks~with~args} @@ -6027,7 +6122,7 @@ hook~'#1' \@@_if_disabled:nF {#1} { - \exp_args:Nf \@@_print_args:nn {#1} + \exp_args:Nne \@@_print_args:nn {#1} { \int_eval:n { \str_count:e { \@@_parameter:n {#1} } / 3 } @@ -6164,7 +6259,8 @@ % } % \@@_preamble_hook:n {#1} % \@@_log_cmd:x -% { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': } +% { ^^J ->~The~ \@@_if_generic:nT +% {#1} { generic~ } hook~'#1': } % \@@_if_usable:nF {#1} % { \@@_log_line:x { The~hook~is~not~declared. } } % \@@_if_disabled:nT {#1} @@ -6177,26 +6273,30 @@ % { \@@_log_line_indent:x { --- } } % { % \prop_map_inline:cn { g_@@_#1_code_prop } -% { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } +% { \@@_log_line_indent:x +% { ##1~->~\tl_to_str:n {##2} } } % } % \@@_log_line:x % { % Document-level~(top-level)~code % \@@_if_usable:nT {#1} -% { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } : +% { ~(executed~ +% \@@_if_reversed:nTF {#1} {first} {last} ) } : % } % \@@_log_line_indent:x % { % \tl_if_empty:cTF { @@_toplevel~#1 } % { --- } -% { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } +% { -> ~ \exp_args:Nv \tl_to_str:n +% { @@_toplevel~#1 } } % } % \@@_log_line:x { Extra~code~for~next~invocation: } % \@@_log_line_indent:x % { % \tl_if_empty:cTF { @@_next~#1 } % { --- } -% { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } } +% { ->~ \exp_args:Nv \@@_log_next_code:n +% { @@_next~#1 } } % } % \@@_log_line:x { Rules: } % \bool_set_true:N \l_@@_tmpa_bool @@ -6220,7 +6320,8 @@ % { % Execution~order % \bool_if:NTF \l_@@_tmpa_bool -% { \@@_if_reversed:nT {#1} { ~(after~reversal) } } +% { \@@_if_reversed:nT +% {#1}{ ~(after~reversal) } } % { ~(after~ % \@@_if_reversed:nT {#1} { reversal~and~ } % applying~rules) @@ -6231,16 +6332,19 @@ % \@spaces % \clist_if_empty:cTF { g_@@_#1_labels_clist } % { --- } -% { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } } +% { \clist_use:cn +% { g_@@_#1_labels_clist } { ,~ } } % } % } % { % \@@_log_line:x { Execution~order: } % #2 % { -% \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1} +% \@spaces Not~set~because~the~hook~ +% \@@_if_usable:nTF {#1} % { code~pool~is~empty } -% { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} } +% { is~\@@_if_disabled:nTF +% {#1} {disabled} {undeclared} } % } % } % } @@ -6388,7 +6492,8 @@ %\IncludeInRelease{2020/10/01}{\hook_gput_next_code:nn} % {Hooks~with~args} %\cs_gset_protected:Npn \hook_gput_next_code:nn #1 -% { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +% { \@@_normalize_hook_args:Nn +% \@@_gput_next_code:nn {#1} } %\cs_gset_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 { } %\EndIncludeInRelease % \end{macrocode} @@ -6580,7 +6685,8 @@ % \fi: % \cs:w @@~#1 \@@_use_end: % } -%\cs_new:Npn \@@_use_undefined:w #1 #2 @@~#3 \@@_use_end: +%\cs_new:Npn \@@_use_undefined:w +% #1 #2 @@~#3 \@@_use_end: % { % #1 % fi % \@@_use:wn #3 / \s_@@_mark {#3} @@ -6680,15 +6786,18 @@ % % \changes{v1.0s}{2021/09/28} % {Correct usage of older \cs{@@_if_file_hook:wTF} (gh/675)} +% \changes{v1.1h}{2024/01/24} +% {Correct usage of older \cs{@@_if_file_hook:wTF} (gh/1243)} % \begin{macrocode} %\cs_new_protected:Npn \@@_try_file_hook:n #1 % { -% \@@_if_file_hook:wTF #1 / \s_@@_mark +% \@@_if_file_hook:wTF #1 / / \s_@@_mark % { % \exp_args:Ne \@@_if_usable_use:n % { \exp_args:Ne \@@_file_hook_normalize:n {#1} } % } -% { \@@_if_usable_use:n {#1} } % file/ generic hook (e.g. file/before) +% { \@@_if_usable_use:n {#1} } +% % file/ generic hook (e.g. file/before) % } % \end{macrocode} % @@ -6726,12 +6835,14 @@ \cs_new_protected:Npn \hook_use_once:n #1 { \@@_if_execute_immediately:nF {#1} - { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } { 0 } } + { \@@_normalize_hook_args:Nn \@@_use_once:nn + { \use:n {#1} } { 0 } } } \cs_new_protected:Npn \hook_use_once:nnw #1 #2 { \@@_if_execute_immediately:nF {#1} - { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } {#2} } + { \@@_normalize_hook_args:Nn \@@_use_once:nn + { \use:n {#1} } {#2} } } %\EndIncludeInRelease % \end{macrocode} @@ -6743,7 +6854,8 @@ %\cs_gset_protected:Npn \hook_use_once:n #1 % { % \@@_if_execute_immediately:nF {#1} -% { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } } +% { \@@_normalize_hook_args:Nn \@@_use_once:n +% { \use:n {#1} } } % } %\cs_gset:Npn \hook_use_once:nnw #1 #2 % { \use:c { use_none: \prg_replicate:nn {#2} { n } } } @@ -6768,7 +6880,8 @@ % along with the next execution code. % \begin{macrocode} \@@_replacing_args_false: - \@@_cs_gput_right:nnn { _next } {#1} { \@@_use_once_clear:n {#1} } + \@@_cs_gput_right:nnn { _next } {#1} + { \@@_use_once_clear:n {#1} } \@@_replacing_args_reset: \@@_if_usable:nTF {#1} { \@@_use_initialized:n {#1} } @@ -7215,7 +7328,8 @@ { 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_generic:n~or~\iow_char:N\\DisableGenericHook,~so~ + with~\iow_char:N\\hook_disable_generic:n~or~ + \iow_char:N\\DisableGenericHook,~so~ it~cannot~have~code~added~to~it. } % \end{macrocode} @@ -7383,7 +7497,7 @@ % {Hooks~with~args} %\cs_new_protected:Npn \NewHookWithArguments #1 #2 { } %\cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { } -%\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3 { } +%\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3{} %\EndIncludeInRelease % \end{macrocode} % \end{macro} @@ -7835,7 +7949,8 @@ % \exp_args:No \exp_not:o % { % \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: -% { \@@_braced_cs_parameter:n { @@#1~#2 } } +% { \@@_braced_cs_parameter:n +% { @@#1~#2 } } % } % } % } diff --git a/Master/texmf-dist/source/latex/base/ltkeys.dtx b/Master/texmf-dist/source/latex/base/ltkeys.dtx index da8340ea9d0..34a0ab4b477 100644 --- a/Master/texmf-dist/source/latex/base/ltkeys.dtx +++ b/Master/texmf-dist/source/latex/base/ltkeys.dtx @@ -100,7 +100,7 @@ % \texttt{second-name} can be given anywhere, and will save its value in % \cs{@mypkg@other@name}. % -% Keys created \emph{before} the use of \cs{ProcessKeyOptions}act as +% Keys created \emph{before} the use of \cs{ProcessKeyOptions} act as % package options. % \end{function} % diff --git a/Master/texmf-dist/source/latex/base/ltluatex.dtx b/Master/texmf-dist/source/latex/base/ltluatex.dtx index c310ac8ecff..a15019dcd55 100644 --- a/Master/texmf-dist/source/latex/base/ltluatex.dtx +++ b/Master/texmf-dist/source/latex/base/ltluatex.dtx @@ -23,16 +23,22 @@ % \ProvidesFile\undefined\begingroup\def\ProvidesFile % #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}} %\fi -%\ProvidesFile{ltluatex.tex}% -%<*driver> +%<*dtx> \ProvidesFile{ltluatex.dtx} -% -%<*tex> -[2023/08/03 v1.2c -% -% LuaTeX support for plain TeX (core) -%<*tex> +% +%\ProvidesFile{ltluatex.tex} +%<*plain> +% \fi +% \ProvidesFile{ltluatex.dtx} +[2024/02/11 v1.2c +% LaTeX Kernel (LuaTeX support)^^A +%\iffalse +% LuaTeX support for plain TeX (core)% +%\fi ] +% \iffalse +% +%<*tex> \edef\etatcatcode{\the\catcode`\@} \catcode`\@=11 % @@ -541,9 +547,9 @@ \csname globbox\endcsname % \end{macrocode} % -% Define|\e@alloc| as in latex (the existing macros in |etex.src| +% Define|\e@alloc| as in \LaTeX{} (the existing macros in |etex.src| are % hard to extend to further register types as they assume specific -% 26x and 27x count range. For compatibility the existing register +% 26x and 27x count range). For compatibility the existing register % allocation is not changed. % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltmarks.dtx b/Master/texmf-dist/source/latex/base/ltmarks.dtx index f8268564841..a9f3bb0184f 100644 --- a/Master/texmf-dist/source/latex/base/ltmarks.dtx +++ b/Master/texmf-dist/source/latex/base/ltmarks.dtx @@ -14,21 +14,14 @@ % %%% From File: ltmarks.dtx % -% \begin{macrocode} -\def\ltmarksversion{v1.0d} -\def\ltmarksdate{2022/06/01} -% \end{macrocode} %<*driver> +% \fi +\ProvidesFile{ltmarks.dtx} + [2024/05/31 v1.0g LaTeX Kernel (Marks)] +% \iffalse +% \documentclass{l3doc} - -%\usepackage{ltmarks} - -% 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}}} +\GetFileInfo{ltmarks.dtx} \EnableCrossrefs \CodelineIndex @@ -45,7 +38,7 @@ % % % \title{The \texttt{ltmarks.dtx} code\thanks{This file has version -% \ltmarksversion\ dated \ltmarksdate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % \author{^^A % Frank Mittelbach, \LaTeX{} Project\thanks @@ -156,7 +149,7 @@ % \begin{function}{\InsertMark,\mark_insert:nn} % \begin{syntax} % \cs{InsertMark} \Arg{class} \Arg{text} -% \cs{mark_insert:nn} \Arg{class} \Arg{text} +% \cs{mark_insert:nn} \Arg{class} \Arg{text} % \end{syntax} % Adds a mark to the current galley for the \meta{class}, containing the % \meta{text}. @@ -291,6 +284,11 @@ % The \meta{pos\textsubscript{\itshape i}} argument can be either % \texttt{top}, \texttt{first}, or \texttt{last}. % +% Important to note is that the comparison is not with respect to +% the textual content of the marks but whether or not they +% originated from the same \cs{InsertMark} command (or the L3 layer +% version \cs{mark_insert:nn}). +% % If you wish to compare marks across different regions or across % different classes, you have to do it using the generic test only % available in the L3 programming layer or do it manually, i.e., @@ -299,6 +297,8 @@ % \emph{true}; if a declared and an undeclared mark class is used % it is always \emph{false}.} % +% \subsection{Use cases for conditionals} +% % However, the basic version is enough for the following typical use cases: % \begin{description} % \item[Test for at most one mark of class \texttt{myclass} on current @@ -353,7 +353,7 @@ % \begin{function}{\DebugMarksOn,\DebugMarksOff, % \mark_debug_on:,\mark_debug_off:} % \begin{syntax} -% \cs{DebugMarksOn} ... \cs{DebugMarksOff} +% \cs{DebugMarksOn} \ldots\ \cs{DebugMarksOff} % \end{syntax} % % Commands to turn the debugging of mark code on or off. The @@ -397,8 +397,8 @@ % % \begin{function}{\markboth, \markright} % \begin{syntax} -% \cs{markboth} \Arg{left} \Arg{right} -% \cs{markright} \Arg{right} +% \cs{markboth} \Arg{left} \Arg{right} +% \cs{markright} \Arg{right} % \end{syntax} % \LaTeXe{} uses two marks which aren't fully independent. A % \enquote{left} mark generated by the first argument of \cs{markboth} @@ -610,9 +610,9 @@ % marks. It too is called as part of \cs{@opcol}. % \end{function} % -% \begin{function}{\@@_update_structure:nn} +% \begin{function}{\@@_update_structure_from_material:nn} % \begin{syntax} -% \cs{@@_update_structure:nn} \Arg{region} \Arg{material with marks} +% \cs{@@_update_structure_from_material:nn} \Arg{region} \Arg{material with marks} % \end{syntax} % Helper function that inspects the marks % inside the second argument and assigns new mark values based on @@ -627,8 +627,8 @@ % \texttt{page} and \texttt{column} because only they have % \texttt{previous-...} counterparts. % -% Another important part to keep in mind is that marks are only -% recognized if they appear on top-level, e.g., if we want to +% Another important aspect to keep in mind is that marks are recognized +% only if they appear on the top level, e.g., if we want to % process material stored in boxes we need to put it unboxed (using % \cs{unvcopy} etc.)\ into the second argument. % \end{function} @@ -642,7 +642,7 @@ % Helper function that copies all mark values in the \meta{source} % region to \meta{alias}, i.e., make the structures identical. Used % to update the \texttt{previous-...} structures inside -% \cs{@@_update_structure:nn} and \texttt{first-column} and +% \cs{@@_update_structure_from_material:nn} and \texttt{first-column} and % \texttt{last-column} structures inside % \cs{@@_update_singlecol_structures:} or % \cs{@@_update_dblcol_structures:}. @@ -650,7 +650,6 @@ % % % -% % \begin{function}{\@@_update_structure_to_err:n} % \begin{syntax} % \cs{@@_update_structure_to_err:n} \Arg{region} @@ -662,6 +661,37 @@ % \end{function} % % +% \begin{function}{\@@_get_marks_for_reinsertion:nNN} +% \begin{syntax} +% \cs{@@_get_marks_for_reinsertion:nNN} \Arg{source} +% \qquad \meta{token-list-var for collecting first marks} +% \qquad \meta{token-list-var for collecting last marks} +% \end{syntax} +% Helper function for extracting marks that would otherwise get +% lost, for example when they are hidden inside a box. This helper +% does not update mark structures and can therefore be used outside +% the output routine as well. +% +% It collect all the top-level marks from inside the \meta{source} +% and adds suitable \cs{mark_insert:nn} in the two token +% lists. These token lists can then be executed at the right place +% to reinsert the marks, e.g., directly after the box. This is, for +% example, used by \pkg{multicol} when a short balanced +% \env{multicols} is returned to the galley for typesetting. +% +% If the \meta{source} consists of a single vertical box (plus +% possibly followed by some glue but nothing else) then the box is +% unpacked and the top-level marks are collected from its +% content. However, if it is not a vertical box or there are are +% other data then nothing is unpacked and you have to do the +% unpacking yourself to get at the marks inside. +% +% It is quite likely that one only needs a single token list for +% returning the \cs{mark_insert:nn} statements. If that is the case +% this command may change to take only two arguments. +% \end{function} +% +% % % ^^A \end{documentation} % @@ -703,12 +733,13 @@ % % % \begin{macro}{\mark_new_class:n,\@@_new_class:nn} +% % A mark class is created by initializing a number of data -% structures. First, we get a register number to refer to the mark class. -% The new mark class is then added to the \cs{g_@@_classes_seq} -% sequence to be able to easily loop over all classes. Finally a -% number of top-level global token lists are declared that hold -% various versions of the mark for access. +% structures. First, we get a register number to refer to the mark +% class. The new mark class is then added to the +% \cs{g_@@_classes_seq} sequence to be able to easily loop over all +% classes. Finally a number of top-level global token lists are +% declared that hold various versions of the mark for access. % \begin{macrocode} \cs_new_protected:Npn \mark_new_class:n #1 { @@ -774,6 +805,32 @@ \tl_new:c { g_@@_last-column_top_ #1 _tl } \tl_new:c { g_@@_last-column_first_ #1 _tl } \tl_new:c { g_@@_last-column_last_ #1 _tl } +% \end{macrocode} +% All marks will have an identication at the beginning of the form +% \cs{@@_id:n}\texttt\{\meta{number}\texttt\} and therefore the +% initial empty values should have that too, so that data extraction +% is going to be uniform. +% \changes{v1.0g}{2024/05/31}{Initialize all marks with an id, use 0 +% when a new class is made (gh/1359)} +% \begin{macrocode} + \tl_set:cn { g_@@_page_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_page_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_page_last_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-page_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-page_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-page_last_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_column_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_column_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_column_last_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-column_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-column_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_previous-column_last_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_first-column_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_first-column_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_first-column_last_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_last-column_top_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_last-column_first_ #1 _tl }{ \@@_id:n{0} } + \tl_set:cn { g_@@_last-column_last_ #1 _tl }{ \@@_id:n{0} } } % \end{macrocode} % \end{macro} @@ -784,57 +841,74 @@ % \subsection{Updating mark structures} % % -% \begin{macro}{\l_@@_box,\g_@@_tmp_tl,\g_@@_new_top_tl} -% For some operations we need a temporary private box and two +% \begin{macro}{\l_@@_box,\l_@@_ii_box,\g_@@_tmp_tl,\g_@@_new_top_tl} +% For some operations we need two temporary private boxes and two % private global token lists. % \begin{macrocode} \box_new:N \l_@@_box +\box_new:N \l_@@_ii_box \tl_new:N \g_@@_tmp_tl \tl_new:N \g_@@_new_top_tl % \end{macrocode} % \end{macro} % % -% \begin{macro}{\@@_update_structure:nn} -% -% This function updates the mark structures. The first argument is -% the region to update and second argument receives the material -% that holds the marks. Out of this material we extract the first -% and last marks for all classes (if there are any) to do the -% assignments. % +% \begin{macro}{\@@_extract_and_handle_marks:nn} +% \changes{v1.0e}{2024/01/29}{Macro added} +% +% This is the main macro to extract and handle marks inside some +% vertical material. It is used by +% \cs{@@_update_structure_from_material:nn} (for updating the mark +% structure for a region based on the marks found) and by +% \cs{@@_get_marks_for_reinsertion:nNN} (for extracting marks from +% some material and prepare for reinserting them later (e.g., out +% of a box that is placed as a box into the main galley). % \begin{macrocode} -\cs_new_protected:Npn \@@_update_structure:nn #1#2 - { +\cs_new_protected:Npn \@@_extract_and_handle_marks:nn #1#2 { % \end{macrocode} -% First thing we do is copying the current structure to -% \texttt{previous-...}; this leaves the current structure -% untouched so we can update it class by class (which is necessary). +% This macro expects code to handle extracted marks in its first argument and +% vertical material (not boxed or just consisting of a single +% vertical box) as its second. It +% extracts top-level mark information from \verb/#2/, stores them +% as split marks and then calls +% \verb/#1/ to make use of this information. +% +% If it finds a forced break in the material it removes it and then +% restarts the attempt without it. +% +% We start with a group to keep most changes local. % \begin{macrocode} - \@@_update_structure_alias:nn { previous-#1 } {#1} + \group_begin: % \end{macrocode} +% % Getting the first and last marks out of the material in \verb=#2= -% is done by putting the material in a box and then doing a -% split operation to the maximum size possible (which hopefully -% means all of the content).\footnote{We could verify this, maybe we -% should.} Because this is an action only for the sake of getting -% at the mark values we don't want any underfull -% box warnings so we turn those (locally) off. +% is done by putting the material in a box and then doing a split +% operation to the maximum size possible (which hopefully gets us +% all of the content).\footnote{With normal column material cut +% from the main galley we should always get all material in one go, +% but in certain situations, for example, in a \pkg{multicols} +% environment that contains some \cs{columnbreak}s a single split +% operation will not be enough. Thus, this is something we need to +% handle.} Because this action is used only to get the mark +% values, we don't want any underfull box warnings so we (locally) +% turn those off. +% % \begin{macrocode} - \group_begin: \dim_set_eq:NN \tex_splitmaxdepth:D \c_max_dim \int_set_eq:NN \tex_vbadness:D \c_max_int \dim_set_eq:NN \tex_vfuzz:D \c_max_dim % \end{macrocode} -% There is a further complication: if the region contains infinite +% +% There is a further complication: if the material contains infinite % shrinking glue then a \tn{vsplit} operation will balk with a -% low-level error. Now pages or columns, which are our main concern here, can't -% have such infinite shrinkage if they are cut straight from the -% galley, however the use of \tn{enlargethispage} actually does add -% some at the very bottom (and also wraps the whole page into a box -% by itself, so if we leave it this way then a) we get this error -% and b) we don't see any marks because they are hidden one level -% down). +% low-level error. Now pages or columns, which are our main concern +% here, can't have such infinite shrinkage if they are cut straight +% from the galley, however the use of \tn{enlargethispage} actually +% does add some at the very bottom (and also wraps the whole page +% into a box by itself, so if we leave it this way then a) we get +% this error and b) we don't see any marks because they are hidden +% one level down). % % Another possible issue are packages or user code that place stray % \tn{vbox}es directly into the main galley (an example is @@ -842,93 +916,236 @@ % boxes end up as the last item on the page we should not unpack % them. % -% We therefore do an \tn{unskip} to get rid of that glue if present and -% also check if we have then a \tn{vbox} as the last item and if so -% unpack that too, but only under certain conditions, see -% below. All this is temporary, just for getting the -% marks out, so it doesn't affect the final page production. -% -% In fact, we go one step further and set the box to a large -% negative height possible and afterwards take a look at the -% reported badness: if it is zero we know that there has still been -% infinite shrinkage in the box so that we can't do a -% \tn{vsplit}. If that is the case we generate an error message and -% bypass extracting the marks. We use only half of \cs{c_max_dim} -% because otherwise \TeX{} will report an overfull vbox despite our -% setting of \cs{tex_vfuzz:D}. This test will not find existing -% infinite shrinkage in all cases, e.g., if there are several glues -% that cancel each other, but it is the best we can do. -% \begin{macrocode} - \vbox_set_to_ht:Nnn \l_@@_box { -.5\c_max_dim } - { - #2 - \tex_unskip:D - \box_set_to_last:N \l_@@_box +% All these issues need to be handled, which is done in +% \cs{@@_prepare_and_extract:nn}. +% +% \begin{macrocode} + \@@_prepare_and_extract:nn {#1} {#2} +% \end{macrocode} +% Once all mark classes have been processed, the data structures are +% updated and we can close the group, which undoes our local +% changes and retains only the global ones. +% \begin{macrocode} + \group_end: + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_prepare_and_extract:nn} +% +% This macro does the dirty work. It is not directly integrated in +% \cs{@@_extract_and_handle_marks:nn} because we may have to call +% it recursively if we find forced breaks. +% \begin{macrocode} +\cs_new_protected:Npn \@@_prepare_and_extract:nn #1#2 { +% \end{macrocode} +% +% To handle the \cs{enlargethispage} case we do an \tn{unskip} to +% get rid of any glue that is present at the very end of the material +% and also check if we have then a \tn{vbox} as the last item and +% if so unpack that too, but only under certain conditions, see +% below. All this is temporary done in a group, just for getting +% the marks out, so it doesn't affect the final page production. +% +% \begin{macrocode} + \vbox_set:Nn \l_@@_box + { + #2 + \tex_unskip:D + \box_set_to_last:N \l_@@_box % \end{macrocode} % After having removed the last box from the current list (if there -% was one) -% we check if the list is now empty. If not, the the last box is -% definitely not the one from \tn{enlargethispage} and so we can -% and should leave it alone. Otherwise we check if this last box is -% a \tn{vbox}. +% was one) we check whether the vertical list is now empty. If not, +% then the last box is definitely not the one from +% \tn{enlargethispage} and so we can, and should, leave it +% alone. Otherwise we check if this last box is a \tn{vbox}. % \changes{v1.0d}{2022/06/01}{Extend the logic for detecting the marks % in the box (gh/836)} % \begin{macrocode} - \int_compare:nNnT \tex_lastnodetype:D < 0 - { - \box_if_vertical:NT \l_@@_box - { -% \end{macrocode} -% If it is we do a further test and reset the \cs{l_@@_box} -% to check if it contains infinitely shrinkable glue. -% \begin{macrocode} - \vbox_set_to_ht:Nnn \l_@@_box { -.5\c_max_dim } - { - \vbox_unpack:N \l_@@_box - \tex_kern:D \c_zero_dim % ensure that box - % is not empty - } + \int_compare:nNnT \tex_lastnodetype:D < 0 + { + \box_if_vertical:NT \l_@@_box % \end{macrocode} -% If not, then we unpack it, if yes we still ignore it for the process of -% mark extraction. We do not generate an error though, because in all -% likelihood this is an ordinary box like a marginal that does -% contain something like \tn{vss}. +% If it is, we unpack the box. % \begin{macrocode} - \int_compare:nNnT \tex_badness:D > 0 - { \vbox_unpack:N \l_@@_box } - } - } + { \vbox_unpack:N \l_@@_box } + } % \end{macrocode} % If it wasn't a vbox, it was either an hbox or there was no box. % Given that we are only interested in the marks we don't need put -% it back in that case. However, we have to make sure that the -% outer box under construction -% is not totally empty (which it might have been from the start, or -% now), because \TeX{} does not report a badness for empty boxes -% and that means our test would incorrectly conclude that we have -% infinite shrinking glue. A simple \tn{kern} is enough to avoid -% this (the same was already done above). -% \begin{macrocode} - \tex_kern:D \c_zero_dim - } - \int_compare:nNnTF \tex_badness:D > 0 +% it back in that case. +% \begin{macrocode} + } % \end{macrocode} -% If the box had no infinite shrinkage (or rather if our test -% didn't show any) we vsplit it. Note that it -% doesn't matter that we set it to this strange size first. If there -% was infinite shrinkage after all, we end up with a low-level -% \TeX{} error, but if there is, it is a coding error and needs -% correcting. +% We are now ready to \cs{vsplit} the box to get at the marks. If +% the box contains some infinite negative glue the \TeX{} will +% produce an error complaining about it but it will correctly find +% the the split marks. Given that we can't prevent that error, we +% hide it from the user and ensure that \TeX{} doesn't stop. The +% error message still shows in the log, but even that is mitigated +% as best as possible---see the definition of +% \cs{@@_vbox_set_split_to_maxdimen:NN} for the tricks employed. % \begin{macrocode} - { - \vbox_set_split_to_ht:NNn \l_@@_box \l_@@_box \c_max_dim + \@@_vbox_set_split_to_maxdimen:NN \l_@@_ii_box \l_@@_box +% \end{macrocode} +% After splitting we check if there is anything left in +% \cs{l_@@_box}. If not then the above split has set some split marks +% that we can then use to finish the extraction: +% \begin{macrocode} + \box_if_empty:NTF \l_@@_box + { #1 } +% \end{macrocode} +% If we have a remainder after the split then this means that there +% was some forced break in the material. We get rid of that by +% combining the content of the two boxes and restart. +% \begin{macrocode} + { +%<*trace> + \@@_debug:n { \iow_term:x + { Marks:~ mark~ extraction~needs~ recursion~ + \msg_line_context: } } +% + \@@_prepare_and_extract:nn {#1} + { \vbox_unpack:N \l_@@_ii_box + \vbox_unpack:N \l_@@_box } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_vbox_set_split_to_maxdimen:NN} +% +% Split a box to get at its marks without pausing even if \TeX{} is +% producing an error message because of infinite negative glue in +% the box. If there is such an error we ensure that it only shows +% up in the log but not on the terminal. +% +% The nice low-level hack by DPC records in the \texttt{.log} that a glue +% shrinkage error is harmless. +% +% We disguise \cs{c_max_dim} in an odd looking csname, which then +% shows up as part of the display of an error message if that error +% happens. This csname forms part of the error diplay so what +% you get is something like +%\begin{verbatim} +% ! Infinite glue shrinkage found in box being split. +% Infinite shrink error above ignored ! +% l. ... } +%\end{verbatim} +% which hopefully makes it clear that the error is harmless and +% and should be ignored by the reader of the \texttt{.log}. +% \begin{macrocode} +\cs_set_eq:cN {Infinite~shrink~error~above~ignored~!}\c_max_dim +% \end{macrocode} +% +% The whole definition of \cs{@@_vbox_set_split_to_maxdimen:NN} +% below is fully expanded, so we have to use a lot of +% \cs{exp_not:N} commands to prevent expansion where necessary. +% \begin{macrocode} +\cs_new_protected:Npx \@@_vbox_set_split_to_maxdimen:NN #1#2 { +% \end{macrocode} +% We start by saving the current interaction and escape char settings. +% \begin{macrocode} + \tl_set:Ne \exp_not:N \l_@@_saved_parameters_tl + { + \tex_interactionmode:D + \exp_not:N \int_use:N \tex_interactionmode:D \scan_stop: + \tex_escapechar:D + \exp_not:N \int_use:N \tex_escapechar:D \scan_stop: + } +% \end{macrocode} +% Then we change them so that no escape char is printed in the +% error message (accounts for the missing backslash in front of +% \verb/Infinite shrink .../) and we set the interaction to +% \cs{nonstopmode} so that the the error (if any) just goes into +% the \texttt{.log} file and \TeX{} doesn't stop at that point. +% \begin{macrocode} + \tex_escapechar:D -1 \scan_stop: + \tex_interactionmode:D 0 \scan_stop: +% \end{macrocode} +% Then we do the splitting of the box to \cs{c_max_dim} to get at +% the marks. This may generate the error we are worried about, +% i.e., if the box contains infinite negative glue. However, \TeX{} +% makes this glue finite and continues, which means we get our split +% marks which is really all we care about. +% \begin{macrocode} + \tex_setbox:D #1 \tex_vsplit:D #2 to +% \end{macrocode} +% The \cs{use:n} may seem pointless, and it is to some extent, but +% we need it to get our disguised \cs{c_max_dim} displayed +% properly as part of the error message if there is one. Without +% it, the display would show only part of what we want it to show +% (try it). +% \begin{macrocode} + \exp_not:N \use:n { + \use:c{Infinite~shrink~error~above~ignored~!} + } +% \end{macrocode} +% Finally, we change the escape char and the interaction mode back +% to what it was before: +% \begin{macrocode} + \exp_not:N \l_@@_saved_parameters_tl +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\l_@@_saved_parameters_tl} +% The temporary variable used for resetting escape char and +% interaction mode. +% \begin{macrocode} +\tl_new:N \l_@@_saved_parameters_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_update_structure_from_material:nn} +% +% \changes{v1.0e}{2024/01/29}{Macro renamed} +% +% This function updates the mark structures of a region. The first +% argument is the region to update and second argument receives the +% material that holds the marks. Out of this material we extract +% the first and last marks for all classes (if there are any) to do +% the assignments. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_update_structure_from_material:nn #1#2 { + \@@_extract_and_handle_marks:nn +% \end{macrocode} +% +% Once the marks can be extracted we update the structure from the +% split marks (code in \cs{@@_update_structure_from_splitmarks:n}). +% \begin{macrocode} + { \@@_update_structure_from_splitmarks:n {#1} } + { #2 } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@@_update_structure_from_splitmarks:n} +% This macro is called after we have done a \cs{tex_vsplit:D} +% operation and the mark data is in the split marks. +% \begin{macrocode} +\cs_new_protected:Npn \@@_update_structure_from_splitmarks:n #1 { +% \end{macrocode} +% +% The first thing we do is to copy the current region structure to +% \texttt{previous-...}; this leaves the current structure +% untouched so we can update it class by class (which is necessary). +% \begin{macrocode} + \@@_update_structure_alias:nn { previous-#1 } {#1} % \end{macrocode} % After this action we can get first and last marks of the various % classes through \cs{tex_splitfirstmarks:D} and % \cs{tex_splitbotmarks:D}. So now we loop over all classes stored in % \cs{g_@@_classes_seq}. % \begin{macrocode} - \seq_map_inline:Nn \g_@@_classes_seq + \seq_map_inline:Nn \g_@@_classes_seq { % \end{macrocode} % First action: get the last mark from the previous region, i.e., @@ -950,14 +1167,14 @@ \tl_gset:No \g_@@_tmp_tl { \tex_splitbotmarks:D \use:c { c_@@_class_##1_mark } } % \end{macrocode} -% If this mark doesn't exist then obviously first mark does -% neither, so both become the last mark from the previous region. We +% If this mark doesn't exist then obviously neither does the first mark, +% so both become the last mark from the previous region. We % have to be a little careful here: something like % \verb=\mark_insert:nn{foo}{}= adds an \enquote{empty} mark that should % not be confused with no mark at all. But no mark in our material % will result in \cs{g_@@_tmp_tl} being fully empty. This is why we % have to make sure that \enquote{empty} from \cs{mark_insert:nn} only -% appears to be empty but fails the next test (see below how this +% appears to be empty when typeset but fails the next test (see below how this % is done). % \begin{macrocode} \tl_if_empty:NTF \g_@@_tmp_tl @@ -987,29 +1204,144 @@ } } } - } +} % \end{macrocode} -% If the badness was zero (we actually tested for${}>0$ but it -% can't get negative) then we had infinite shrinkage, so we report -% that and set all marks to the value the last mark had before. +% \end{macro} +% +% +% +% \begin{macro}{\@@_get_marks_for_reinsertion:nNN} +% +% This function extracts the marks from the material in the first +% argument but it does not update any the mark structures. Instead, +% it collects the marks in the token lists given as the second and +% third argument, in such a way that they can be reinserted by just +% executing the token lists.\footnote{It is probably enough to +% collect everything in a single token list as long as we put the +% first marks first and the last marks last). But for extra +% flexibility, I currently use 2 token lists. This might change when it is +% really clear that this is never needed.} +% % \begin{macrocode} - { - \msg_error:nnn { mark } { infinite-shrinkage } {#1} - \seq_map_inline:Nn \g_@@_classes_seq +\cs_new_protected:Npn \@@_get_marks_for_reinsertion:nNN #1#2#3 { +% \end{macrocode} +% First we clear the temporary token lists as we haven't seen any marks yet. +% \begin{macrocode} + \tl_clear:N \g_@@_first_marks_tl + \tl_clear:N \g_@@_last_marks_tl +% \end{macrocode} +% Then we extract all top-level marks, thereby filling the token lists +% with suitable \cs{mark_insert:nn} calls. +% \begin{macrocode} + \@@_extract_and_handle_marks:nn +% \end{macrocode} +% The first argument holds the code for fill the token lists and +% the second is the material we extract from. +% \begin{macrocode} + \@@_get_from_splitmarks: + { #1 } +% \end{macrocode} +% +% Finally, we copy the updated (or not updated) temporary token +% lists to the two that have been supplied when the function was +% called. By convention \enquote{get} operations return their +% values in local variables and \cs{@@_extract_and_handle_marks:nn} +% runs in a group, which is why we have to use global temporary +% variables for collecting. +% \begin{macrocode} + \tl_set_eq:NN #2 \g_@@_first_marks_tl + \tl_set_eq:NN #3 \g_@@_last_marks_tl +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@_get_from_splitmarks:} +% This function is called after we have done a \cs{vsplit} to +% update the split marks. It loops through all mark classes to find +% out if there are marks for this class and if so updates the +% global tls used for collecting. +% \begin{macrocode} +\cs_new_protected:Npn \@@_get_from_splitmarks: { + \seq_map_inline:Nn \g_@@_classes_seq { - \tl_gset_eq:cc { g_@@_#1_top_ ##1_tl } - { g_@@_#1_last_ ##1_tl } - \tl_gset_eq:cc { g_@@_#1_first_##1_tl } - { g_@@_#1_last_ ##1_tl } +% \end{macrocode} +% First we to get the last mark for the current class from the +% material supplied. +% \begin{macrocode} + \tl_gset:No \g_@@_tmp_tl + { \tex_splitbotmarks:D \use:c { c_@@_class_##1_mark } } +% \end{macrocode} +% +% If this mark doesn't exist then obviously first mark doesn't +% either, so we do nothing (other than issuing some debugging +% info). + +% We have to be a little careful here: something like +% \verb=\mark_insert:nn{foo}{}= adds an \enquote{empty} mark that +% we should not confuse with the case where there is no mark at +% all. +% +% When there is no mark at all we get a truly empty +% \cs{g_@@_tmp_tl} as a result. This is why we have to make sure +% that an \enquote{empty} mark generated with \cs{mark_insert:nn} +% only appears to be empty when it is typeset, but fails the next +% test (see below how this is done). +% \begin{macrocode} + \tl_if_empty:NTF \g_@@_tmp_tl + { +%<*trace> + \@@_debug:n { \iow_term:x { Marks:~no~ marks~ + for~ class~ '##1'~\msg_line_context: } } +% + } +% \end{macrocode} +% +% If it wasn't empty, i.e., if it had a real value then we use this +% value for our new last mark instead. This means we put an +% appropriate \cs{mark_insert:nn} statement into +% \cs{g_@@_last_marks_tl}. +% \begin{macrocode} + { +%<*trace> + \@@_debug:n { \iow_term:x { Marks:~ extract~ last~ + mark~ for~ class~ '##1'~ =~ \g_@@_tmp_tl } } +% + \tl_gput_right:Ne \g_@@_last_marks_tl + { \mark_insert:nn {##1} { \g_@@_tmp_tl } } +% \end{macrocode} +% Because we had a last mark we also have a first mark (which might +% be the same, but might not be), so we pick that up and add it to +% the \cs{g_@@_first_marks_tl} token list. This explains why we +% first checked for the last mark because that makes the processing +% faster in case there is none. +% \begin{macrocode} +%<*trace> + \@@_debug:n { \iow_term:x { Marks:~ extract~ first~ + mark~ for~ class~ '##1'~ =~ + \tex_splitfirstmarks:D + \use:c { c_@@_class_##1_mark } + } } +% + \tl_gput_right:Ne \g_@@_first_marks_tl + { \mark_insert:nn {##1} + { + \tex_splitfirstmarks:D + \use:c { c_@@_class_##1_mark } + } + } + } } - } +} % \end{macrocode} -% Once all mark classes have been processed the data structures are -% updated and we can close the group which undoes our local -% changes and retains only the global ones. +% \end{macro} +% +% +% \begin{macro}{\g_@@_first_marks_tl,\g_@@_last_marks_tl} +% These are two global temporary variables used in the code above. % \begin{macrocode} - \group_end: - } +\tl_new:N \g_@@_first_marks_tl +\tl_new:N \g_@@_last_marks_tl % \end{macrocode} % \end{macro} % @@ -1098,7 +1430,18 @@ % \begin{macrocode} \@kernel@before@insertmark \hook_use:n { insertmark } - \unrestored@protected@xdef \g_@@_tmp_tl {#2} + \unrestored@protected@xdef \g_@@_tmp_tl + { +% \end{macrocode} +% To ensure that marks are unique we insert a hidden sequence +% marker at the beginning of the content of the mark containing the +% sequence number of the mark. +% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks +% unique on nearby regions (gh/1359)} +% \begin{macrocode} + \@@_id:n{ \int_use:N\g_@@_int } + #2 + } %<*trace> \@@_debug:n{ \iow_term:x { Marks:~ set~#1~<-~ '\tl_to_str:V \g_@@_tmp_tl' ~ \msg_line_context: } } @@ -1111,9 +1454,11 @@ % becomes empty, but not immediately; otherwise we just put % \cs{g_@@_tmp_tl} in. % \begin{macrocode} - \tl_if_empty:NTF \g_@@_tmp_tl - { \exp_not:n { \prg_do_nothing: } } - { \exp_not:o { \g_@@_tmp_tl } } +% this is no longer needed with 1.0f +% \tl_if_empty:NTF \g_@@_tmp_tl +% { \exp_not:n { \prg_do_nothing: } } +% { \exp_not:o { \g_@@_tmp_tl } } + \exp_not:o { \g_@@_tmp_tl } } \group_end: % \end{macrocode} @@ -1135,15 +1480,43 @@ % \end{macro} % % +% \begin{macro}{\@@_id:n} +% A hidden marker is placed into every mark added by +% \cs{mark_insert:nn}. It will will not show up in the output but +% its argument (a counter value that is incremented) makes all +% marks unique so the test for \enquote{equal} is not fooled by two +% different marks having the same mark text. +% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks +% unique on nearby regions (gh/1359)} +% \begin{macrocode} +\cs_new_protected:Npn \@@_id:n #1 { } +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}[int]{\@kernel@before@insertmark} % \begin{macro}{insertmark} % By default \cs{label}, \cs{index}, and \cs{glossary} do nothing % when the mark is inserted. % \begin{macrocode} +\int_new:N \g_@@_int \cs_new:Npn \@kernel@before@insertmark { \cs_set_eq:NN \label \scan_stop: \cs_set_eq:NN \index \scan_stop: \cs_set_eq:NN \glossary \scan_stop: +% \end{macrocode} +% We count each mark and use that to place a hidden marker in front +% of the mark text. To ensure that there is no overflow (very +% unlikely but you never know) we restart every 100000 marks. Thus, +% if somebody puts more than that number of marks on a single page +% you could construct a scenario in which that approach fails. +% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks +% unique on nearby regions (gh/1359)} +% \begin{macrocode} + \int_compare:nNnTF \g_@@_int < {99999} + { \int_gincr:N \g_@@_int } + { \int_gzero:N \g_@@_int } + } % \end{macrocode} % The public hook to augment the setup. @@ -1158,15 +1531,25 @@ % To retrieve the first, last or top region mark, we grab the % appropriate value stored in the corresponding token list variable % and pass its contents back. These functions should be used only -% in output routines after \cs{@@_update_structure:nn} has acted, +% in output routines and only after \cs{@@_update_structure_from_material:nn} has acted, % otherwise their value will be wrong. % % If used with an unknown class or region they generate an error % (fairly low-level because we are in an expandable context). +% +% Each mark starts with an id and while the id does not print it is +% nevertheless better to remove it when returning the mark, so that +% downstream manipulation of the data doesn't have to deal with it. +% \changes{v1.0g}{2024/05/31}{Remove the id when returning the mark value (gh/1359)} % \begin{macrocode} -\cs_new:Npn \mark_use_first:nn #1#2 { \exp_not:v { g_@@_#1_first_#2_tl } } -\cs_new:Npn \mark_use_last:nn #1#2 { \exp_not:v { g_@@_#1_last_#2_tl } } -\cs_new:Npn \mark_use_top:nn #1#2 { \exp_not:v { g_@@_#1_top_#2_tl } } +\cs_new:Npn \mark_use_first:nn #1#2 { \@@_use:v { g_@@_#1_first_#2_tl } } +\cs_new:Npn \mark_use_last:nn #1#2 { \@@_use:v { g_@@_#1_last_#2_tl } } +\cs_new:Npn \mark_use_top:nn #1#2 { \@@_use:v { g_@@_#1_top_#2_tl } } +% \end{macrocode} +% This is what the \cs{use_none:nn} accomplishes. +% \begin{macrocode} +\cs_new:Npn \@@_use:n #1 { \exp_not:o { \use_none:nn #1 } } +\cs_generate_variant:Nn \@@_use:n { v } % \end{macrocode} % \end{macro} % @@ -1207,7 +1590,7 @@ % % \subsection{Messages} % -% Mark errors are LaTeX kernel errors: +% Mark errors are \LaTeX{} kernel errors: % \changes{v1.0d}{2022/06/01}{Marks are kernel errors} % \begin{macrocode} \prop_gput:Nnn \g_msg_module_type_prop { mark } { LaTeX } @@ -1247,17 +1630,7 @@ } % \end{macrocode} % -% \begin{macrocode} -\msg_new:nnnn { mark } { infinite-shrinkage } - { Infinite~shrinkage~found~in~'#1'. } - { - \c__msg_coding_error_text_tl - The~mark~region~'#1'~contains~some~infinite~negative~glue~ - allowing~it~to~shrink~to~an~arbitrary~size.~ - This~makes~it~impossible~to~split~the~region~apart~to~ - get~at~its~marks.~They~are~lost. - } -% \end{macrocode} +% % % % @@ -1358,7 +1731,7 @@ % % % \begin{macro}{\@@_status:n} -% Show all mark class values across all regions. +% Show a snapshot of all mark class values across all regions. % \begin{macrocode} \cs_new_protected:Npn \@@_status:n #1 { @@ -1370,6 +1743,22 @@ % \end{macro} % % +% \begin{macro}{\ShowMarksAt} +% \changes{v1.0e}{2024/01/29}{Macro added} +% Debugging helper that displays a snapshot of all known mark +% structures. The argument is a text string that is +% displayed to help identifying when the snapshot was made. +% +% This may not stay like this (or at all), which is why it isn't +% yet documented as an official command. +% \begin{macrocode} +\cs_new_protected:Npn \ShowMarksAt #1 { +%<*trace> + \@@_debug:n { \@@_status:n {#1} } +% +} +% \end{macrocode} +% \end{macro} % % % \subsection{Designer-level interfaces} @@ -1425,9 +1814,9 @@ % % % -% \section{\LaTeXe{} integration} +% \section{\LaTeXe{} integration} % -% \subsection{Core \LaTeXe{} integration} +% \subsection{Core \LaTeXe{} integration} % % \begin{macro}{\@@_update_singlecol_structures:} % This command updates the mark structures if we are producing a @@ -1445,11 +1834,11 @@ % \begin{macrocode} \box_if_vertical:NTF \@outputbox { - \@@_update_structure:nn {page} + \@@_update_structure_from_material:nn {page} { \vbox_unpack:N \@outputbox } } { - \@@_update_structure:nn {page} + \@@_update_structure_from_material:nn {page} { \hbox_unpack:N \@outputbox } } % \end{macrocode} @@ -1489,11 +1878,11 @@ % \begin{macrocode} \box_if_vertical:NTF \@outputbox { - \@@_update_structure:nn {column} + \@@_update_structure_from_material:nn {column} { \vbox_unpack:N \@outputbox } } { - \@@_update_structure:nn {column} + \@@_update_structure_from_material:nn {column} { \hbox_unpack:N \@outputbox } } % \end{macrocode} @@ -1538,6 +1927,12 @@ % \begin{macrocode} \seq_map_inline:Nn \g_@@_classes_seq { +% \end{macrocode} +% The \texttt{previous-page} updates need to come before the +% updates for \texttt{page} region because otherwise the values +% to copy are already overwritten. +% necessary values. +% \begin{macrocode} \tl_gset_eq:cc { g_@@_previous-page_top_ ##1 _tl } { g_@@_page_top_ ##1 _tl } \tl_gset_eq:cc { g_@@_previous-page_first_ ##1 _tl } @@ -1545,16 +1940,48 @@ \tl_gset_eq:cc { g_@@_previous-page_last_ ##1 _tl } { g_@@_page_last_ ##1 _tl } % \end{macrocode} -% The \texttt{page} updates need to come after the corresponding -% updates for \texttt{previous-page} otherwise we loose the -% necessary value. +% To update the \texttt{top} we only have to copy what is in +% \texttt{first-column}: % \begin{macrocode} \tl_gset_eq:cc { g_@@_page_top_ ##1 _tl } { g_@@_first-column_top_ ##1 _tl } - \tl_gset_eq:cc { g_@@_ page_first_ ##1 _tl } - { g_@@_first-column_first_ ##1 _tl } - \tl_gset_eq:cc { g_@@_page_last_ ##1 _tl } - { g_@@_last-column_last_ ##1 _tl } + +% \end{macrocode} +% Updating the \texttt{first} mark for the \texttt{page} region is +% more complicated. We first have to find out of there is any mark +% in the first column (this can be done by comparing the \texttt{top} and +% the \texttt{first} mark of of that region). +% \changes{v1.0f}{2024/05/30}{Correct logic for first mark in page +% region if first column contains no marks (gh/1359)} +% \begin{macrocode} + \tl_if_eq:ccTF { g__@@_first-column_top_ ##1 _tl } + { g__@@_first-column_first_ ##1 _tl } + { +% \end{macrocode} +% If there is no mark in the first column we copy the first mark of +% the last column. If that doesn't contain a mark we still get the +% right result because the first mark is then equal to the top mark. +% \begin{macrocode} + \tl_gset_eq:cc { g_@@_page_first_ ##1 _tl } + { g_@@_last-column_first_ ##1 _tl } + } + { +% \end{macrocode} +% On the other hand, if there is a mark in the first column we copy +% over the \texttt{first} mark from that column. +% \begin{macrocode} + \tl_gset_eq:cc { g_@@_page_first_ ##1 _tl } + { g_@@_first-column_first_ ##1 _tl } + } +% \end{macrocode} +% The logic for the \texttt{last} page mark is again simple, we can +% just copy the value in the \texttt{last} mark of the last column. +% If that column doesn't contain any marks, then the value in +% \texttt{last} will be automatically the same as the \texttt{last} +% from the first column. +% \begin{macrocode} + \tl_gset_eq:cc { g_@@_page_last_ ##1 _tl } + { g_@@_last-column_last_ ##1 _tl } } } %<*trace> @@ -1583,17 +2010,26 @@ %<@@=> % \end{macrocode} % -% \begin{macro}[int]{\@expl@@@mark@update@singlecol@structures@@, -% \@expl@@@mark@update@dblcol@structures@@} +% \begin{macro}[int]{\@expl@@@mark@update@singlecol@structures@@} % \begin{macrocode} \cs_new_eq:NN \@expl@@@mark@update@singlecol@structures@@ \__mark_update_singlecol_structures: +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}[int]{\@expl@@@mark@update@dblcol@structures@@} +% \begin{macrocode} \cs_new_eq:NN \@expl@@@mark@update@dblcol@structures@@ \__mark_update_dblcol_structures: % \end{macrocode} % \end{macro} % -% \subsection{Other \LaTeXe{} output routines} +% +% +% +% \subsection{Other \LaTeXe{} output routines} % % This section will cover \pkg{multicol} and other packages altering % or providing their own output routine. Not done yet. @@ -1601,6 +2037,9 @@ % % % +% \subsection{Rollback information} +% +% % \begin{macrocode} %\IncludeInRelease{0000/00/00}{ltmarks}% % {Undo~Marks~handling} @@ -1609,7 +2048,7 @@ % We keep the interface commands around even if we roll back in % case they are used in packages that don't roll back. Not likely % to do a lot of good, but then there is not much we can do, but -% this at least then doesn't give errors. +% this at least they won't give unknown csname errors. % \begin{macrocode} %\DeclareRobustCommand \NewMarkClass[1]{} %\DeclareRobustCommand \InsertMark[2]{} diff --git a/Master/texmf-dist/source/latex/base/ltmeta.dtx b/Master/texmf-dist/source/latex/base/ltmeta.dtx index 30da4016fb4..cc3e62811df 100644 --- a/Master/texmf-dist/source/latex/base/ltmeta.dtx +++ b/Master/texmf-dist/source/latex/base/ltmeta.dtx @@ -13,20 +13,14 @@ % % %%% From File: ltmeta.dtx -% -% \begin{macrocode} -\def\ltmetaversion{v1.0b} -\def\ltmetadate{2022/05/18} -% \end{macrocode} %<*driver> +% \fi +\ProvidesFile{ltmeta.dtx} + [2024/05/16 v1.0b LaTeX Kernel (Document Metadata)] +% \iffalse +% \documentclass{l3doc} - -% 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}}} +\GetFileInfo{ltmeta.dtx} \EnableCrossrefs \CodelineIndex @@ -43,7 +37,7 @@ % % % \title{The \texttt{ltmeta.dtx} code\thanks{This file has version -% \ltmetaversion\ dated \ltmetadate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % \author{Frank Mittelbach} % diff --git a/Master/texmf-dist/source/latex/base/ltmiscen.dtx b/Master/texmf-dist/source/latex/base/ltmiscen.dtx index 9706f272035..accdac24b2f 100644 --- a/Master/texmf-dist/source/latex/base/ltmiscen.dtx +++ b/Master/texmf-dist/source/latex/base/ltmiscen.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2023/09/13 v1.2c LaTeX Kernel (Misc. Environments)] + [2024/02/08 v1.2c LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -509,8 +509,8 @@ % endings are converted to spaces by \TeX{} during that process. % % However, especially the \texttt{.toc} file might be read in L-R mode -% (in cases the \cs{tableofcontents} attempts to put, say a list of -% sub-sections as a paragraph. In that case the newlines after a line +% (in cases the \cs{tableofcontents} attempts to put, say, a list of +% sub-sections as a paragraph). In that case the newlines after a line % like % \begin{verbatim} % \contentsline {subsubsection}{\numberline {1.1.1}A C-head}{2} @@ -520,9 +520,9 @@ % % That could be fixed by reading in the file using % \cs{endlinechar}\texttt{=-1} but that has the danger that it drops -% some valid endlines that should be converted to spaces (for example +% some valid endlines that should be converted to spaces (for example, % when the user edited the TOC and then used \cs{nofiles} to preserve -% it. +% it). % % So the approach taken instead is this: % \begin{itemize} @@ -1604,7 +1604,7 @@ % ``\verb=!~!foo='' in the output. % To avoid this scenario we check if \verb=#1= has the character % code of a space, if so we recurse otherwise we call \cs{@@sverb} -% (which is the original definition of \cs{@sverb}. +% (which is the original definition of \cs{@sverb}). % \changes{v1.1u}{2020/04/22}{Drop spaces before \cs{verb} delimiter (gh/327)} % \begin{macrocode} \def\@sverb#1{\if\noexpand#1 \expandafter\@sverb\else\@@sverb{#1}\fi} diff --git a/Master/texmf-dist/source/latex/base/ltoutenc.dtx b/Master/texmf-dist/source/latex/base/ltoutenc.dtx index e7d48e4ba20..c18ff014464 100644 --- a/Master/texmf-dist/source/latex/base/ltoutenc.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutenc.dtx @@ -44,7 +44,7 @@ %<*driver> % \fi \ProvidesFile{ltoutenc.dtx} - [2022/05/27 v2.0z LaTeX Kernel (font encodings)] + [2024/02/08 v2.1a LaTeX Kernel (font encodings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutenc.dtx} @@ -383,10 +383,10 @@ % other encodings, so there are some optimizations provided: % \begin{quote} % |\DeclareTextSymbolDefault{|^^A -% \meta{command}|}|^^A +% \meta{command}|}{|^^A % \meta{encoding}|}|\\ % |\DeclareTextAccentDefault{|^^A -% \meta{command}|}|^^A +% \meta{command}|}{|^^A % \meta{encoding}|}| % \end{quote} % are short for: @@ -840,7 +840,7 @@ % interfere between accent and base character. Therefore we need to % 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 +% (as that already happened in the box above, if necessary), we simply % 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. @@ -3659,10 +3659,10 @@ \let\encodingdefault\CurrentOption % \end{macrocode} % From 2020/02/02 release onward we only load the encoding files if -% they haven't be loaded already. To check this we look if -% \verb=\T@=\textit{encoding} is already defined. If not we load +% they haven't be loaded already. To check this we look at whether +% \verb=\T@=\textit{encoding} is already defined. If not, we load it later % (indicated by setting the switch -% \texttt{@tempswa} to true and we always load if we run in an older +% \texttt{@tempswa} to true) and we always load if we are using an older % format (or rather in a rollback situation). % \changes{v2.0m}{2020/01/25}{Load each encoding file only once (gh/255)} % \begin{macrocode} @@ -3677,6 +3677,7 @@ \if@tempswa % \end{macrocode} % +% \changes{v2.1a}{2023/11/07}{Add more explanation to error message (gh/1102)} % \begin{macrocode} \edef\reserved@f{% \lowercase{\def\noexpand\reserved@f{\CurrentOption enc.def}}}% @@ -3685,7 +3686,11 @@ {}{\PackageError{fontenc}% {Encoding file `\reserved@f' not found.% \MessageBreak - You might have misspelt the name of the encoding}% + You might have misspelled the name of the encoding + \MessageBreak + or a required support package (e.g., cyrillic) is + \MessageBreak + missing in your installation}% {Necessary code for this encoding was not loaded.\MessageBreak Thus calling the encoding later on will @@ -3723,8 +3728,8 @@ % \end{macrocode} % % We select the new font encoding default (i.e., the last encoding -% specified in the option list. But this encoding may not work with -% the current |\f@shape|, e.g., \texttt{LY1} is not defined for +% specified in the option list). But this encoding may not work with +% the current |\f@shape|: e.g., \texttt{LY1} is not defined for % \texttt{cmr} and therefore packages switching to \texttt{LY1} % usually also change \cs{rmdefault}. But that only applies at % |\begin{document}| so we get a spurious warning if we use what diff --git a/Master/texmf-dist/source/latex/base/ltoutput.dtx b/Master/texmf-dist/source/latex/base/ltoutput.dtx index b067ef5ecbd..f0c1bf830b3 100644 --- a/Master/texmf-dist/source/latex/base/ltoutput.dtx +++ b/Master/texmf-dist/source/latex/base/ltoutput.dtx @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltoutput.dtx} - [2023/05/26 v1.4j LaTeX Kernel (Output Routine)] + [2024/03/16 v1.4j LaTeX Kernel (Output Routine)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutput.dtx} @@ -847,7 +847,7 @@ % \begin{macro}{\if@firstcolumn} % \begin{macro}{\if@twocolumn} % \begin{macro}{\if@twoside} -% \begin{macro}{\if@reversemarginpar} +% \begin{macro}{\if@reversemargin} % \begin{macro}{\if@mparswitch} % \begin{macro}{\col@number} % \changes{v1.0n}{1994/04/30}{Added \cs{col@number}} diff --git a/Master/texmf-dist/source/latex/base/ltpara.dtx b/Master/texmf-dist/source/latex/base/ltpara.dtx index f76352fb917..f102d68e0d6 100644 --- a/Master/texmf-dist/source/latex/base/ltpara.dtx +++ b/Master/texmf-dist/source/latex/base/ltpara.dtx @@ -14,21 +14,14 @@ % %%% From File: ltpara.dtx % -% \begin{macrocode} -\def\ltparaversion{v1.0l} -\def\ltparadate{2023/01/30} -% \end{macrocode} %<*driver> +% \fi +\ProvidesFile{ltpara.dtx} + [2024/05/16 v1.0m LaTeX Kernel (paragraph hooks)] +% \iffalse +% \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}}} +\GetFileInfo{ltpara.dtx} \EnableCrossrefs \CodelineIndex @@ -45,7 +38,7 @@ % % % \title{The \texttt{ltpara.dtx} code\thanks{This file has version -% \ltparaversion\ dated \ltparadate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % \author{Frank Mittelbach} % @@ -811,9 +804,11 @@ \hook_use:n {para/begin} % \end{macrocode} % If we aren't in horizontal mode any longer the hooks above misbehaved. +% \changes{v1.0m}{2023/11/16}{Correct error message: hook +% left horizontal not vertical mode (gh/1182)} % \begin{macrocode} \if_mode_horizontal: \else: - \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi: + \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi: % \end{macrocode} % Finally we reinsert the indentation box (unless suppressed) and % then call \cs{everypar} the way legacy \LaTeX\ code expects it. @@ -845,7 +840,7 @@ % \@kernel@before@para@begin % \hook_use:n {para/begin} % \if_mode_horizontal: \else: -% \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi: +% \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi: % \@@_handle_indent: %} % \end{macrocode} @@ -1261,7 +1256,7 @@ % 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 +\everypar{\@nodocument} %% To get an error if text appears before the \document % \end{macrocode} % % diff --git a/Master/texmf-dist/source/latex/base/ltplain.dtx b/Master/texmf-dist/source/latex/base/ltplain.dtx index 37733735623..a628b954d97 100644 --- a/Master/texmf-dist/source/latex/base/ltplain.dtx +++ b/Master/texmf-dist/source/latex/base/ltplain.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2023/10/21 v2.3i LaTeX Kernel (Plain TeX)] + [2024/02/08 v2.3j LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -1241,11 +1241,11 @@ %\IncludeInRelease{2022/06/01}{\obeylines}% % {Add a redirection to obeylines and obeyspaces}% % \end{macrocode} -% If the active |^^M| escapes, e.g. into a \cs{write} (which is -% effectively in a different context) we don't want the definition +% If the active |^^M| escapes, e.g., into a \cs{write} (which is +% effectively in a different context) then we don't want the definition % from \cs{obeylines} but rather a simple \cs{par} (in fact even % the primitive one, not the \LaTeX{} version \cs{para\_end:} which -% is only defined later. +% is only defined later). % % \begin{macrocode} \begingroup @@ -1263,7 +1263,7 @@ % line ending characters and in that mode \TeX{} discards % everything from that point onwards to the real end of the line so % it works like a comment --- pretty strange really (and I think -% due to the fact the the original pascal compiler could have some +% due to the fact that the original pascal compiler could have some % garbage showing up after the normal line ending character. Thus % we really have to make sure that any closing braces is not one % the same line as an |^^M|, because otherwise it would get dropped @@ -1293,7 +1293,7 @@ % one that is current when \cs{obeylines} act. % % There is a small subtlety here: in an \cs{edef} the active |^^M| stayed -% put (because it was equal to to the primitive \cs{par}), now +% put (because it was equal to the primitive \cs{par}), now % \cs{obeyedline} expands and you get what it contains, i.e., in that % case \cs{par}, into the \cs{edef} or \cs{mark} unless we use % \cs{protected} on it. @@ -1813,7 +1813,13 @@ \tracinggroups\z@ \tracingparagraphs\z@ \tracingmacros\z@ - \tracinglostchars\@ne +% \end{macrocode} +% None really means go back to the \LaTeX{} ``default'' and for +% \cs{tracinglostchars} this should therefore be 2 these days. +% \changes{v2.3j}{2023/11/07}{Set \cs{tracinglostchars} to 2 in +% \cs{tracingnone} (gh/549)} +% \begin{macrocode} + \tracinglostchars\tw@ \tracingpages\z@ \tracingstats\z@ }% diff --git a/Master/texmf-dist/source/latex/base/ltproperties.dtx b/Master/texmf-dist/source/latex/base/ltproperties.dtx index 40c50cd20a2..0fd8f22e0ef 100644 --- a/Master/texmf-dist/source/latex/base/ltproperties.dtx +++ b/Master/texmf-dist/source/latex/base/ltproperties.dtx @@ -1,8 +1,8 @@ % \iffalse meta-comment % -%% File: ltproperties.dtx +% File: ltproperties.dtx % -% Copyright (C) 2021-2023 The LaTeX Project +% Copyright (C) 2023-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -21,13 +21,21 @@ % https://github.com/latex3/latex2e % % for those people who are interested. -% \begin{macrocode} -\def\ltpropertiesversion{1.0c} -\def\ltpropertiesdate{2023-10-15} -% \end{macrocode} - -%<*driver> +% +% \fi +% +% \iffalse +%%% From File: ltproperties.dtx +% +%<*driver> +% \fi +\ProvidesFile{ltproperties.dtx} + [2024/04/17 v1.0e LaTeX Kernel (Properties)] +% \iffalse +% \documentclass[full]{l3doc} +\GetFileInfo{ltproperties.dtx} + \EnableCrossrefs \CodelineIndex \begin{document} @@ -39,7 +47,7 @@ % \title{^^A % Recording and cross-referencing document properties^^A % \thanks{This module has version -% \ltpropertiesversion\ dated \ltpropertiesdate, \copyright\ The \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ The \LaTeX\ % Project.} % } % @@ -157,8 +165,8 @@ % % \begin{function}{\property_new:nnnn,\property_gset:nnnn} % \begin{syntax} -% \cs{property_new:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} -% \cs{property_gset:nnnn} \Arg{property}\Arg{setpoint} \Arg{default} \Arg{code} +% \cs{property_new:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \cs{property_gset:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} % \end{syntax} % \LaTeXe-interface: see \cs{NewProperty}, \cs{SetProperty}.\\ % Sets the \meta{property} to have the \meta{default} specified, and at the @@ -180,7 +188,7 @@ % \property_record:nn, \property_record:nV, \property_record:ee % } % \begin{syntax} -% \cs{property_record:nN} \Arg{label} \Arg{clist var} +% \cs{property_record:nN} \Arg{label} \meta{clist var} % \cs{property_record:nn} \Arg{label} \Arg{clist} % \end{syntax} % \LaTeXe{}-interface: see \cs{RecordProperties}.\\ @@ -266,7 +274,7 @@ % \cs{property_if_exist_p:n} \Arg{property} % \cs{property_if_exist:nTF} \Arg{property} \Arg{true code} \Arg{false code} % \end{syntax} -% \LaTeXe{}-interface: \cs{IfPropertyExistTF}.\\ +% \LaTeXe{}-interface: \cs{IfPropertyExistsTF}.\\ % Tests if the \meta{property} has been declared. % \end{function} % @@ -275,7 +283,7 @@ % \cs{property_if_recorded_p:n} \Arg{label} % \cs{property_if_recorded:nTF} \Arg{label} \Arg{true code} \Arg{false code} % \end{syntax} -% \LaTeXe{}-interface: \cs{IfLabelExistTF}\\ +% \LaTeXe{}-interface: \cs{IfLabelExistsTF}\\ % Tests if the \meta{label} is known. This is also true if the label has been % set with the standard \cs{label} command. % \end{function} @@ -307,8 +315,8 @@ % % \begin{function}{\NewProperty,\SetProperty} % \begin{syntax} -% \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} -% \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} +% \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code} % \end{syntax} % Sets the \meta{property} to have the \meta{default} specified, and at the % \meta{setpoint} (either |now| or |shipout|) to write the result of the @@ -329,7 +337,7 @@ % of properties. Also similar to the standard \cs{label} command, the command is surrounded % by an \cs{@bsphack}/\cs{@esphack} pair to preserve spacing. % \end{function} - +% % \begin{function}[EXP]{\RefProperty} % \begin{syntax} % \cs{RefProperty} \oarg{local default} \Arg{label} \Arg{property} @@ -340,16 +348,16 @@ % If \Arg{property} has not been declared an error is issued. % \end{function} % -% \begin{function}{\IfPropertyExistTF} +% \begin{function}{\IfPropertyExistsTF,\IfPropertyExistsT,\IfPropertyExistsF} % \begin{syntax} -% \cs{IfPropertyExistTF} \Arg{property} \Arg{true code} \Arg{false code} +% \cs{IfPropertyExistsTF} \Arg{property} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{property} has been declared. % \end{function} % -% \begin{function}{\IfLabelExistTF} +% \begin{function}{\IfLabelExistsTF,\IfLabelExistsT,\IfLabelExistsF} % \begin{syntax} -% \cs{IfLabelExistTF} \Arg{label} \Arg{true code} \Arg{false code} +% \cs{IfLabelExistsTF} \Arg{label} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{label} has been recorded. This is also true if a label % has been set with the standard \cs{label} command. @@ -361,7 +369,7 @@ % \end{syntax} % Tests if the label and a value of the \meta{property} for the \meta{label} are both known. % \end{function} - +% % \begin{function}{\RefUndefinedWarn} % \begin{syntax} % \cs{RefUndefinedWarn} \Arg{label} \Arg{property} @@ -551,6 +559,7 @@ % later too. That is all pretty easy using \pkg{expl3}: we accept a stray % comma at the end of the list as that is easier to deal with than trying % to tidy up, and there is no real downside. +% \changes{v1.0d}{2024-01-17}{Use \cs{protected@write}}% % \begin{macrocode} \cs_new_protected:Npn \property_record:nN #1#2 { \property_record:nV {#1} #2 } @@ -561,7 +570,7 @@ { \legacy_if:nT { @filesw } { - \iow_shipout_x:Nx \@auxout + \protected@write \@auxout {} { \token_to_str:N \new@label@record {#1} @@ -737,9 +746,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{IfPropertyExistTF} +% \begin{macro}{\IfPropertyExistsTF,\IfPropertyExistsT,\IfPropertyExistsF} +% \changes{v1.0e}{2024-04-17}{Renamed \cs{IfPropertyExistTF} to +% \cs{IfPropertyExistsTF} (gh/1262)} % \begin{macrocode} -\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF +\cs_new_eq:NN \IfPropertyExistsTF \property_if_exist:eTF +\cs_new:Npn \IfPropertyExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} } +\cs_new:Npn \IfPropertyExistsF #1 {\property_if_exist:eTF {#1}{} } % \end{macrocode} % \end{macro} % @@ -762,9 +775,13 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\IfLabelExistTF} +% \begin{macro}{\IfLabelExistsTF,\IfLabelExistsT,\IfLabelExistsF} +% \changes{v1.0e}{2024-04-17}{Renamed \cs{IfLabelExistTF} to +% \cs{IfLabelExistsTF} (gh/1262)} % \begin{macrocode} -\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF +\cs_new_eq:NN \IfLabelExistsTF \property_if_recorded:eTF +\cs_new:Npn \IfLabelExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} } +\cs_new:Npn \IfLabelExistsF #1 {\property_if_exist:eTF {#1}{} } % \end{macrocode} % \end{macro} % @@ -938,8 +955,8 @@ %\let \RefProperty \@undefined %\let \RefUndefinedWarn \@undefined % -%\let \IfPropertyExistTF \@undefined -%\let \IfLabelExistTF \@undefined +%\let \IfPropertyExistsTF \@undefined +%\let \IfLabelExistsTF \@undefined %\let \IfPropertyRecordedTF \@undefined % %\let\new@label@record \@undefined diff --git a/Master/texmf-dist/source/latex/base/ltsect.dtx b/Master/texmf-dist/source/latex/base/ltsect.dtx index 4560704463a..21aeda32e02 100644 --- a/Master/texmf-dist/source/latex/base/ltsect.dtx +++ b/Master/texmf-dist/source/latex/base/ltsect.dtx @@ -31,7 +31,7 @@ %%% From File: ltsect.dtx %<*driver> % \fi -\ProvidesFile{ltsect.dtx}[2021/07/28 v1.1f LaTeX Kernel (Sectioning)] +\ProvidesFile{ltsect.dtx}[2024/03/25 v1.1f LaTeX Kernel (Sectioning)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltsect.dtx} @@ -835,13 +835,13 @@ % \begin{macro}{\contentsline} % The |\contentsline{|\meta{type}|}{|\meta{entry}|}{|\meta{page}|}{}| % macro produces a \meta{type} entry in a table of contents, etc. -% It will appear in the |.toc| or other file. For example, -% The entry for subsection 1.4.3 in the table of contents for -% example, might be produced by: +% It will appear in the |.toc| or other file. +% For example, the entry for subsection 1.4.3 in the table of contents, +% might be produced by: % % \begin{verbatim} % \contentsline{subsection} -% {\makebox{30pt}[r]{1.4.3} Gnats and Gnus}{22} +% {\numberline{1.4.3}Gnats and Gnus}{22}{} % \end{verbatim} % % The |\protect| command causes command sequences to be written diff --git a/Master/texmf-dist/source/latex/base/ltshipout.dtx b/Master/texmf-dist/source/latex/base/ltshipout.dtx index aaeba15ea70..0c9113ce938 100644 --- a/Master/texmf-dist/source/latex/base/ltshipout.dtx +++ b/Master/texmf-dist/source/latex/base/ltshipout.dtx @@ -31,30 +31,14 @@ % %%% From File: ltshipout.dtx % -% \begin{macrocode} -\providecommand\ltshipoutversion{v1.0n} -\providecommand\ltshipoutdate{2022/11/08} -% \end{macrocode} -% %<*driver> - +% \fi +\ProvidesFile{ltshipout.dtx} + [2024/02/11 v1.0n LaTeX Kernel (Shipout)] +% \iffalse +% \documentclass{l3doc} - -% bug fix fo l3doc.cls -\ExplSyntaxOn -\cs_set_protected:Npn \__codedoc_macro_typeset_one:nN #1#2 - { - \vbox_set:Nn \l__codedoc_macro_box - { - \vbox_unpack_drop:N \l__codedoc_macro_box - \hbox { \llap { \__codedoc_print_macroname:nN {#1} #2 - \MacroFont % <----- without it the \ is in lmr10 if a link is made - \ - } } - } - \int_incr:N \l__codedoc_macro_int - } -\ExplSyntaxOff +\GetFileInfo{ltshipout.dtx} \providecommand\InternalDetectionOff{} \providecommand\InternalDetectionOn{} @@ -76,7 +60,7 @@ % % % \title{The \texttt{ltshipout} documentation\thanks{This file has version -% \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % % \author{Frank Mittelbach, \LaTeX{} Project Team} @@ -859,7 +843,7 @@ % % \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}} +% flexibility (cf.\ \texttt{https://github.com/pgf-tikz/pgf/issues/960}} % \begin{macrocode} \bool_lazy_and:nnF { \hook_if_empty_p:n {shipout/background} } diff --git a/Master/texmf-dist/source/latex/base/ltsockets.dtx b/Master/texmf-dist/source/latex/base/ltsockets.dtx index 909792a4f54..243963f7bcc 100644 --- a/Master/texmf-dist/source/latex/base/ltsockets.dtx +++ b/Master/texmf-dist/source/latex/base/ltsockets.dtx @@ -30,14 +30,14 @@ % %%% From File: ltsockets.dtx % -% \begin{macrocode} -\def\ltsocketsversion{0.9a} -\def\ltsocketsdate{2023-08-21} -% \end{macrocode} +%<*driver> +% \fi +\ProvidesFile{ltsockets.dtx} + [2024/02/11 v0.9a LaTeX Kernel (Sockets)] +% \iffalse % -%<*driver> \documentclass{l3doc} - +\GetFileInfo{ltsockets.dtx} \providecommand\InternalDetectionOff{} \providecommand\InternalDetectionOn{} @@ -55,7 +55,7 @@ % % % \title{\LaTeX{}'s socket management\thanks{This module has version -% \ltsocketsversion\ dated \ltsocketsdate, \copyright\ \LaTeX\ +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ % Project.}} % % \author{Frank Mittelbach} @@ -530,8 +530,8 @@ % % \begin{function}{\NewSocket,\socket_new:nn} % \begin{syntax} -% \cs{NewSocket} \Arg{socket-name}\Arg{number-of-inputs} -% \cs{socket_new:nn}\Arg{socket-name}\Arg{number-of-inputs} +% \cs{NewSocket} \Arg{socket-name} \Arg{number-of-inputs} +% \cs{socket_new:nn} \Arg{socket-name} \Arg{number-of-inputs} % \end{syntax} % Declares a new socket with name \meta{socket-name} having % \meta{number-of-inputs} inputs. There is automatically a @@ -563,9 +563,9 @@ % % \begin{function}{\NewSocketPlug,\socket_new_plug:nnn,\socket_set_plug:nnn} % \begin{syntax} -% \cs{NewSocketPlug} \Arg{socket-name}\Arg{socket-plug-name}\Arg{code} -% \cs{socket_new_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code} -% \cs{socket_set_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code} +% \cs{NewSocketPlug} \Arg{socket-name} \Arg{socket-plug-name} \Arg{code} +% \cs{socket_new_plug:nnn} \Arg{socket-name} \Arg{socket-plug-name} \Arg{code} +% \cs{socket_set_plug:nnn} \Arg{socket-name} \Arg{socket-plug-name} \Arg{code} % \end{syntax} % Declares a new plug for socket \meta{socket-name} that runs % \meta{code} when executing. It complains if the plug was already @@ -582,8 +582,8 @@ % % \begin{function}{\AssignSocketPlug,\socket_assign_plug:nn} % \begin{syntax} -% \cs{AssignSocketPlug} \Arg{socket-name}\Arg{socket-plug-name} -% \cs{socket_assign_plug:nn}\Arg{socket-name}\Arg{socket-plug-name} +% \cs{AssignSocketPlug} \Arg{socket-name} \Arg{socket-plug-name} +% \cs{socket_assign_plug:nn} \Arg{socket-name} \Arg{socket-plug-name} % \end{syntax} % Assigns the plug \meta{socket-plug-name} to the socket % \meta{socket-name}. It errors if either socket or plug is not @@ -595,8 +595,8 @@ % % \begin{function}{\UseSocket,\socket_use:nw,\socket_use:n,\socket_use:nn,\socket_use:nnn,\socket_use:nnnn} % \begin{syntax} -% \cs{UseSocket} \Arg{socket-name} -% \cs{socket_use:nnn}\Arg{socket-name} \Arg{socket-arg\textsubscript{1}} \Arg{socket-arg\textsubscript{2}} +% \cs{UseSocket} \Arg{socket-name} +% \cs{socket_use:nnn} \Arg{socket-name} \Arg{socket-arg\textsubscript{1}} \Arg{socket-arg\textsubscript{2}} % \end{syntax} % Executes the socket \meta{socket-name} by retrieving the % \meta{code} of the current plug assigned to the socket. This is @@ -619,8 +619,8 @@ % % \begin{function}{\ShowSocket,\LogSocket,\socket_show:n,\socket_log:n} % \begin{syntax} -% \cs{ShowSocket} \Arg{socket-name} -% \cs{socket_show:n}\Arg{socket-name} +% \cs{ShowSocket} \Arg{socket-name} +% \cs{socket_show:n} \Arg{socket-name} % \end{syntax} % Displays information about the socket \meta{socket-name} and its % state then stops and waits for further instructions --- at the diff --git a/Master/texmf-dist/source/latex/base/ltspace.dtx b/Master/texmf-dist/source/latex/base/ltspace.dtx index 73941d48156..206e4f38858 100644 --- a/Master/texmf-dist/source/latex/base/ltspace.dtx +++ b/Master/texmf-dist/source/latex/base/ltspace.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltspace.dtx} - [2023/10/26 v1.3r LaTeX Kernel (spacing)] + [2024/02/08 v1.3r LaTeX Kernel (spacing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltspace.dtx} @@ -568,7 +568,7 @@ % \changes{LaTeX2e}{1993/12/08} % {Command reimplemented; late birthday present for Chris} % \changes{LaTeX2e}{1993/12/08}{Command reimplemented} -% \changes{LaTeX2e}{1993/12/16}{Corrected optimisation :-)} +% \changes{LaTeX2e}{1993/12/16}{Corrected optimisation} % |\@bsphack| and |\@esphack| % used by macros such as |\index| and % |\begin{@float}| \ldots |\end{@float}| @@ -1156,8 +1156,8 @@ % \subsection{Horizontal space (and breaks)} % % \begin{macro}{\nobreakdashes} -% \changes{v1.3}{2004/02/04}{(Macro added} -% \changes{v1.3a}{2004/02/15}{(Added spacefactor setting} +% \changes{v1.3}{2004/02/04}{Macro added} +% \changes{v1.3a}{2004/02/15}{Added spacefactor setting} % This idea is borrowed from the \textsf{amsmath} package but % here we define a robust command. % @@ -1194,7 +1194,7 @@ % \end{macro} % % \begin{macro}{\nobreakspace} -% \changes{v1.2k}{1995/12/04}{(Macro added} +% \changes{v1.2k}{1995/12/04}{Macro added} % \changes{v1.3r}{2023/10/26}{Protected definition for tilde} % \begin{macro}{\@xobeysp} % \changes{v1.2t}{1996/09/28}{Moved from ltmiscen.dtx and redefined to @@ -1209,7 +1209,7 @@ % % The braces in the definition of |~| are needed to ensure that a % following space is preserved when reading to/from internal files. -% \changes{v1.2l}{1995/12/04}{(braces added to definition of tilde} +% \changes{v1.2l}{1995/12/04}{braces added to definition of tilde} % % We need to keep \cs{@xobeysp} as it is widely used; so here it is % let to the non-robust command \cs{nobreakspace }. diff --git a/Master/texmf-dist/source/latex/base/lttagging.dtx b/Master/texmf-dist/source/latex/base/lttagging.dtx new file mode 100644 index 00000000000..585479df214 --- /dev/null +++ b/Master/texmf-dist/source/latex/base/lttagging.dtx @@ -0,0 +1,775 @@ +% \iffalse meta-comment +% +% Copyright (C) 2023-2024 +% 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: lttagging.dtx +% +%<*driver> +% \fi +\ProvidesFile{lttagging.dtx} + [2023/12/19 v1.0a LaTeX Kernel (tagging support)] +% \iffalse +\documentclass{l3doc} +\GetFileInfo{lttagging.dtx} +\title{\filename} +\date{\filedate} +\author{\LaTeX{} project} + +\begin{document} +% \MaintainedByLaTeXTeam{latex} % should be added again the moment + % it is supported by l3doc + \maketitle + \DocInput{\filename} +\end{document} +% +% \fi +% +% \providecommand\env[1]{\texttt{#1}} +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \let\ProvideDocElement\NewDocElement +% +% \ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \ProvideDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% +% \section{} +% +% +% +% \MaybeStop{} +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% +% \section{General support for tagged output} +% +% \DescribeMacro\SuspendTagging +% \DescribeMacro\ResumeTagging +% +% The are places in code where it is import top stop any tagging +% activities, e.g., when we are doing trial typesetting that it is +% done several times. In such a case one must tag only the final +% version that is actually used, otherwise tagging structures are +% allowed which then do not end up in the PDF and confuse the +% mechanism. For this we have two commands that can be used in +% packages: \cs{SuspendTagging} and \cs{ResumeTagging}. They are +% available as part of the \LaTeX{} kernel, so that they can be +% safely used in packages whether or not tagging is requested .They +% both take string argument that is used for debugging to easily +% identify why tagging was suspended or restarted, for example, in +% \pkg{tabularx} you find \verb=\SuspendTagging{tabularx}=. By default +% they two commands do nothing. +% +% TODO: the corresponding L3 layer commands should also have a dummy +% definition in the kernel! +% +% \DescribeMacro\UseTaggingSocket +% \DescribeMacro\tag_socket_use:n +% \DescribeMacro\tag_socket_use:nn +% To support tagging in packages we use sockets with names starting +% with \texttt{tagsupport/}. Usually, these sockets have exactly two +% plugs defined: +% \plug{noop} (when no tagging is requested or tagging is not wanted +% for some reason) and a second plug that enables the tagging. There +% may be more, e.g., tagging with special debugging, etc., but right +% now it is usually just on or off. +% +% Given that we sometimes have to suspend tagging, it would be fairly +% inefficient to put different plugs into these sockets whenever that +% happens. We therefore offer \cs{UseTaggingSocket} which is like +% \cs{UseSocket} except that the socket name is specified without +% \texttt{tagsupport/}, i.e., +% \begin{quote} +% \verb=\UseTaggingSocket{foo}= $\to$ +% \verb=\UseSocket{tagsupport/foo}= +% \end{quote} +% Beside being slightly shorter, the big advantage is that this way +% we can change \cs{UseTaggingSocket} to do nothing when tagging is +% suspended with \cs{SuspendTagging} instead of changing the plugs of +% the tagging support sockets back and forth. +% +% It is possible to use the tagging support sockets with +% \cs{UseSocket} directly, but in this case the socket remains active +% if \cs{SuspendTagging} is in force. There my be reasons for doing +% that but in general we expect to always use \cs{UseTaggingSocket}. +% +% The L3 programming layer versions \cs{tag_socket_use:n} and +% \cs{tag_socket_use:nn} are slightly more efficient than +% \cs{UseTaggingSocket} because they do not have to determine how +% many arguments the socket takes when disabling it, so in code that +% is using the L3 programming layer we recommend to use them instead +% of the CamelCase command. +% +% +% +% \begin{macro}{\SuspendTagging,\ResumeTagging} +% +% In the kernel, these two commands get dummy definitions so that +% they can be used without harm in packages. The real definition is +% used when tagging gets enabled. +% \begin{macrocode} +\cs_new_eq:NN \SuspendTagging \use_none:n +\cs_new_eq:NN \ResumeTagging \use_none:n +% \end{macrocode} +% +% A simplified version of this defnition should move to +% \pkg{tagpdf} and dropped here, eventually. +% \begin{macrocode} +\AddToHook{begindocument/before}{ + \cs_if_exist:NT \tag_stop:n + { + \cs_set:Npn \SuspendTagging #1 { +% \end{macrocode}% +% This stops tagging and also disables all tagging sockets so we are done. +% \begin{macrocode} + \tag_stop:n {#1} + } +% \end{macrocode} +% +% \begin{macrocode} + \cs_set:Npn \ResumeTagging #1 { \tag_start:n {#1} } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tag_socket_use:n, +% \tag_socket_use:nn, +% \UseTaggingSocket, +% } +% Again this is not the final definition for the kernel; it is just +% a version to get going while some parts of the kernel support are +% still missing. +% \begin{macrocode} +\AddToHook{begindocument}[kernel]{ + \cs_if_exist:NF \tag_if_active:T + { + \prg_new_conditional:Npnn \tag_if_active: { p , T , TF, F } + { \prg_return_false: } + } +} +% \end{macrocode} +% +% Dummy definitions in the kernel. +% These definitions will get updated in \pkg{tagpdf}. +% \begin{macrocode} +\cs_new_protected:Npn \tag_socket_use:n #1 { } +\cs_new_protected:Npn \tag_socket_use:nn #1#2 { } +% \end{macrocode} +% The default in the kernel is just to get rid of the argument: +% \begin{macrocode} +\cs_new_protected:Npn \UseTaggingSocket #1 { + \int_case:nnF + { \int_use:c { c__socket_tagsupport/#1_args_int } } + { + 0 \prg_do_nothing: + 1 \use_none:n + 2 \use_none:nn +% \end{macrocode} +% We do not expect tagging sockets with more than one or two +% arguments, so for now we only provide those. +% \begin{macrocode} + } + \ERRORusetaggingsocket % that should get a proper error message +} +\ExplSyntaxOff +% \end{macrocode} +% +% \end{macro} +% +% +% +% +% +% +% \subsection{Tagging support for table/tabular packages} +% +% The code uses a number of sockets to inject the tagging +% commands. These can be easily set to a noop-plug in case the +% automated tagging is not wanted. +% +% \begin{socketdecl}{tagsupport/tbl/cell/begin, +% tagsupport/tbl/cell/end, +% tagsupport/tbl/pcell/end, +% tagsupport/tbl/pcell/end, +% tagsupport/tbl/row/begin, +% tagsupport/tbl/row/end, +% } +% At first sockets for the begin and end of cells and table rows: +% \begin{macrocode} +\NewSocket{tagsupport/tbl/cell/begin}{0} +\NewSocket{tagsupport/tbl/cell/end}{0} +% \end{macrocode} +% +% \begin{macrocode} +\NewSocket{tagsupport/tbl/row/begin}{0} +\NewSocket{tagsupport/tbl/row/end}{0} +% \end{macrocode} +% Multi-line cells have their own sockets (as they start out in +% vertical mode and need different treatment). +% \begin{macrocode} +\NewSocket{tagsupport/tbl/pcell/begin}{0} +\NewSocket{tagsupport/tbl/pcell/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/tbl/init} +% This socket should be at the begin of the table, inside a group. +% It is used for settings such as disabling para-tagging inside the +% table. This socket +% can perhaps be merged later into the begin-sockets. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/init}{0} +% \end{macrocode} +% \end{socketdecl} +% +% +% \begin{socketdecl}{tagsupport/tbl/finalize} +% To fine tune the structure (change cells to header cells, remove +% unwanted structures, move a foot to the end, etc.). We also need a +% socket that is executed at the end of the table but \emph{before} +% all the variables are restored to the outer or default values. +% The code in the socket can make assignments, but probably +% shouldn't do typesetting and not write whatsits. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/finalize}{0} +% \end{macrocode} +% \end{socketdecl} +% + + +% \begin{socketdecl}{tagsupport/tbl/colspan} +% This socket is used to manage spanning cells, e.g., a +% \cs{multicolumn}. It expects one argument (the number of cells +% spanned) and if tagging is enabled set appropriate tag attributes +% in the background. We probably need a similar socket for row +% spans eventually. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/colspan}{1} +% \end{macrocode} +% \end{socketdecl} +% + + +% \begin{socketdecl}{tagsupport/tbl/hmode/begin, +% tagsupport/tbl/hmode/end, +% tagsupport/tbl/vmode/begin, +% tagsupport/tbl/vmode/end +% } +% +% These sockets are used in the begin and end code of environments, +% to allow a fast enabling and disabling of the tagging. We +% distinguish between tables that can be used inside paragraphs and +% standalone tables such as \env{longtable} that are always in +% vertical mode. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/hmode/begin}{0} +\NewSocket{tagsupport/tbl/hmode/end}{0} +\NewSocket{tagsupport/tbl/vmode/begin}{0} +\NewSocket{tagsupport/tbl/vmode/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% +% +% \begin{socketdecl}{tagsupport/tbl/longtable/init, +% tagsupport/tbl/longtable/finalize} +% \env{longtable} needs its own sockets to fine tune the structure. +% Simply switching the plug in the previous socket interferes with +% enabling/disabling the tagging. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/longtable/init}{0} +\NewSocket{tagsupport/tbl/longtable/finalize}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{socketdecl}{tagsupport/tbl/longtable/head, +% tagsupport/tbl/longtable/foot} +% Header and footer boxes need special handling because they are repeatedly +% used. +% \begin{macrocode} +\NewSocket{tagsupport/tbl/longtable/head}{0} +\NewSocket{tagsupport/tbl/longtable/foot}{0} +% \end{macrocode} +% \end{socketdecl} +% +% +% +% +% +% \section{For lttab.dtx parked here for now} +% +% +% \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn +% \end{macrocode} +% +% +% \subsection{Variables for row, column and span counting} +% +% This part needs a decision on names for various integer registers +% as well as a decision if those should be also made available for +% \LaTeXe{}-style packages in form of 2e names and or as +% non-internals for the L3 programming layer. +% +% At the moment they are all internal but this probably has to change. +% +% \begin{macro}{ +% \g_@@_col_int, +% \g_@@_row_int, +% \g_@@_span_tl, +% \g_@@_table_cols_tl} +% +% \cs{g_@@_row_int} holds the current row number in the table. The +% value \texttt{0} means we haven't yet processed the table +% preamble (or in case of longtable are just in front of the next +% chunk to be processed). It is incremented by every \cs{cr} +% including the one ending the table preamble. +% +% TODO: due to the gymnastics needed inside the longtable code the +% row counter is directly exposed there rather than hidden by +% interfaces. This needs changing when it is decided how to manage +% these counters. +% +% \cs{g_@@_col_int} holds the current column number. The value +% \texttt{0} means we have not yet started the table or just finished a table row +% (with \verb=\\= typically); any other positive value means we +% are currently typesetting a cell in that column in some row +% (denoted by the \cs{g_@@_row_int}). +% +% In a \cs{multicolumn} it holds the column number of the first +% spanned column and \cs{g_@@_span_tl} the info how many cells are +% spanned. +% +% \cs{g_@@_span_tl} is normally \texttt{1} except in a +% \cs{multicolumn} cell. +% \begin{macrocode} +\int_new:N \g_@@_col_int +\int_new:N \g_@@_row_int +\tl_new:N \g_@@_span_tl +\tl_new:N \g_@@_table_cols_tl + +\tl_gset:Nn \g_@@_span_tl {1} +\tl_gset:Nn \g_@@_table_cols_tl {0} % indicates outer level +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\l_@@_saved_col_tl,\l_@@_saved_row_tl, +% \l_@@_saved_span_tl,\l_@@_saved_table_cols_tl} +% +% Saving the outer values if we are nesting tables is necessary (as +% the above variables are globally altered). For this we always use +% token lists because they don't change and we do not need to blow +% additional integer registers. +% \begin{macrocode} +\tl_new:N \l_@@_saved_col_tl +\tl_new:N \l_@@_saved_row_tl +\tl_new:N \l_@@_saved_span_tl +\tl_new:N \l_@@_saved_table_cols_tl + +\tl_set:Nn \l_@@_saved_col_tl{0} +\tl_set:Nn \l_@@_saved_row_tl{0} +\tl_set:Nn \l_@@_saved_span_tl{1} +\tl_set:Nn \l_@@_saved_table_cols_tl{0} % indicates outer level +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\g_@@_missingcells_int} +% This will contain the number of missing cells in a row: +% \begin{macrocode} +\int_new:N \g_@@_missing_cells_int +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Tracing/debugging} +% +% \begin{macro}{\DebugTablesOn,\DebugTablesOff} +% +% \begin{macrocode} +\def\DebugTablesOn{ + \cs_set_eq:NN \@@_trace:n \typeout +} +\def\DebugTablesOff{ + \cs_set_eq:NN \@@_trace:n \use_none:n +} +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_eq:NN \@@_trace:n \use_none:n +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Interface commands} +% +% All interface commands for the cell number determination have to be +% public on some level because they are needed in other packages as +% well, e.g., longtable. We may or may not also want to provide 2e +% style names for them. +% +% \begin{macro}{\tbl_update_cell_data:} +% Updating cell data in columns after the first means we have to +% increment the \cs{g_@@_col_int} by the span count of the previous +% cell (in case it was a \cs{multicolumn}) and then reset the +% \cs{g_@@_span_tl} to one (as the default). +% \begin{macrocode} +\cs_new_protected:Npn \tbl_update_cell_data: { + \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } + \tl_gset:Nn \g_@@_span_tl {1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\tbl_count_table_cols:} +% Current implementation of \cs{@mkpream} uses the scratch counter +% \cs{count@} to keep track of the number of toks registers it needs +% (2 per column), but this can't be used as it counts also +% insertions made with \verb+!{}+ and \verb+@{}+. +% So similar as does longtable for \cs{LT@cols} we count the +% numbers of ampersands instead. +% \begin{macrocode} +\cs_new:Npn \tbl_count_table_cols: { + \seq_set_split:NnV\l_@@_tmpa_seq {&}\@preamble + \tl_gset:Ne \g_@@_table_cols_tl { \seq_count:N \l_@@_tmpa_seq } + \@@_trace:n { ==>~ Table~ has~ \g_@@_table_cols_tl \space columns } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\l_@@_tmpa_seq} +% +% \begin{macrocode} +\seq_new:N \l_@@_tmpa_seq +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\tbl_count_missing_cells:n} +% +% We might have the situation that some table package has not +% implemented the \cs{tbl_count_table_cols:} in which case +% \cs{g_@@_table_cols_tl} would always be zero and we would get an +% error below when we try to determine the missing cells, so bypass +% that calculation if we aren't doing tagging (there the packages +% should have the proper code added). Recall that this is code, +% that is called by \verb=\\= and an old table packagee might rely +% on whatever the \LaTeX{} kernel offers here. +% \begin{macrocode} +\cs_new:Npn \tbl_count_missing_cells:n #1 { + \tag_if_active:T { + \int_compare:nNnT \g_@@_col_int > 0 + { + \int_gset:Nn \g_@@_missing_cells_int + { + \g_@@_table_cols_tl + - \g_@@_col_int + - \g_@@_span_tl + + 1 + } + \int_compare:nNnT \g_@@_missing_cells_int < 0 \ERRORmissingcells % should not happen + \@@_trace:n{==>~ + (#1)~ + This~ row~ needs~ + \int_use:N \g_@@_missing_cells_int \space + additional~ cell(s) + } + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tbl_save_outer_table_cols:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tbl_save_outer_table_cols: { + \tl_set_eq:NN \l_@@_saved_table_cols_tl \g_@@_table_cols_tl +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tbl_init_cell_data_for_table:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tbl_init_cell_data_for_table: { + \tl_set:No \l_@@_saved_col_tl {\int_use:N \g_@@_col_int } + \tl_set:No \l_@@_saved_row_tl {\int_use:N \g_@@_row_int } + \tl_set_eq:NN \l_@@_saved_span_tl \g_@@_span_tl +% + \@@_trace:n { ==>~ saved~cell~data:~ + \l_@@_saved_row_tl, + \l_@@_saved_col_tl, + \l_@@_saved_span_tl \space + ( + \int_compare:nNnTF \l_@@_saved_table_cols_tl = 0 + { outer~ level } + { max:~ \l_@@_saved_table_cols_tl } + ) + } +% \end{macrocode} +% These are the initial values when starting a table: +% \begin{macrocode} + \int_gzero:N \g_@@_row_int + \int_gzero:N \g_@@_col_int + \tl_gset:Nn \g_@@_span_tl {1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\tbl_update_cell_data_for_next_row:} +% \begin{macrocode} +\cs_new_protected:Npn \tbl_update_cell_data_for_next_row: { + \int_gincr:N \g_@@_row_int % this row about to start + \int_gzero:N \g_@@_col_int % we are before first col +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tbl_init_cell_data_for_row:} +% If we start processing a cell in the first column we set +% \cs{g_@@_col_int} to \texttt{1} as we are no longer "at" but "in" +% the first column. We also set \cs{g_@@_span_tl} to its default +% value (not spanning cells). +% \begin{macrocode} +\cs_new_protected:Npn \tbl_init_cell_data_for_row: { + \int_gset:Nn \g_@@_col_int {1} + \tl_gset:Nn \g_@@_span_tl {1} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tbl_if_row_was_started:T, +% \tbl_if_row_was_started:TF} +% We use \cs{g_@@_col_int} equal zero to indicate that we are just +% after a TR (i.e.n between rows or at the very beginning of the +% table). Using the row +% count is not so good as longtable may split the table in chunks. +% +% These conditionals have to be expandable (i.e., unprotected) as +% they are sometimes executed when \TeX{} is scanning inside a table. +% \begin{macrocode} +\cs_new:Npn \tbl_if_row_was_started:T { + \int_compare:nNnT \g_@@_col_int > 0 +} +\cs_new:Npn \tbl_if_row_was_started:TF { + \int_compare:nNnTF \g_@@_col_int > 0 +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\tbl_gzero_row_count:,\tbl_gincr_row_count:,\tbl_gdecr_row_count:} +% This here is basically a temporary interface. What it will be in +% the end depends on what we decide concerning exposing row and +% column counters, if they stay internal we need something like +% this here (perhaps using \texttt{gincr} etc, or perhaps some +% other names in the first place). +% \begin{macrocode} +\cs_new_protected:Npn \tbl_gzero_row_count: { + \int_gzero:N \g_@@_row_int +} +\cs_new_protected:Npn \tbl_gincr_row_count: { + \int_gincr:N \g_@@_row_int +} +\cs_new_protected:Npn \tbl_gdecr_row_count: { + \int_gdecr:N \g_@@_row_int +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\tbl_inbetween_rows:} +% Again name is not really brilliant so far. +% \begin{macrocode} +\cs_new_protected:Npn \tbl_inbetween_rows: { + \int_gzero:N \g_@@_col_int +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\tbl_restore_outer_cell_data:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tbl_restore_outer_cell_data: { + \int_gset:Nn \g_@@_col_int { \l_@@_saved_col_tl } + \int_gset:Nn \g_@@_row_int { \l_@@_saved_row_tl } + \tl_gset_eq:NN \g_@@_span_tl \l_@@_saved_span_tl + \tl_gset_eq:NN \g_@@_table_cols_tl \l_@@_saved_table_cols_tl + \@@_trace:n { ==>~ restored~cell~data:~ + \int_use:N \g_@@_row_int, + \int_use:N \g_@@_col_int, + \l_@@_saved_span_tl \space + ( + \int_compare:nNnTF \g_@@_table_cols_tl = 0 + { outer~ level } + { max:~ \g_@@_table_cols_tl } + ) + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\tbl_update_multicolumn_cell_data:n} +% This macro updates \cs{g_@@_col_int} and \cs{g_@@_span_tl} inside +% a \cs{multicolumn} and possibly calls the tagging socket +% \texttt{tbl/row/begin}. +% \begin{macrocode} +\cs_new_protected:Npn \tbl_update_multicolumn_cell_data:n #1 { +% \end{macrocode} +% We execute socket for tagging only if this \cs{multicolumn} +% replaces the preamble of the first column. In that case we also have +% to set \cs{g_@@_col_int} to 1 because this is no longer done in the +% preamble for the cell either. +% \begin{macrocode} + \int_compare:nNnTF \g_@@_col_int = 0 + { + \UseTaggingSocket{tbl/row/begin} + \int_gset:Nn \g_@@_col_int {1} + } +% \end{macrocode} +% If we are in a later column we use \cs{g_@@_span_tl} from the +% previous column to update. +% \begin{macrocode} + { + \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } + } +% \end{macrocode} +% Then we set the span value so that it can be use in the next column. +% \begin{macrocode} + \tl_gset:Nn \g_@@_span_tl {#1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\tbl_crcr:n} +% This macro is used instead of the usual \cs{crcr} at the end of a +% table. It is deliberately defined without protection because it +% may get expanded by the scanning mechanism of low-level \TeX{} +% after a final \cs{cr} (aka \verb=\\=) in the table. In that case +% it shouldn't stop the expansion and the conditional inside will +% be false, thus it just vanishes without doing anything. If there +% are missing cells (in which case we also haven't see \cs{cr} yet) +% the macro \cs{tbl_count_missing_cells:n} is executed and +% then the row is finished with a final \cs{cr}. +% \begin{macrocode} +\cs_new:Npn \tbl_crcr:n #1 { + \int_compare:nNnT \g_@@_col_int > 0 + { + \tbl_count_missing_cells:n {#1} + \cr + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +\ExplSyntaxOff +%<@@=> +% \end{macrocode} +% +% This is needed for \pkg{longtable} because \cs{refstepcounter} is +% setting up a target when \pkg{hyperref} is loaded and we don't +% want that in \pkg{longtable}. +% +% TODO: move to right .dtx file +% \begin{macrocode} +\let\@kernel@refstepcounter\refstepcounter +% \end{macrocode} +% Prevent longtable patching by hyperref until hyperref does so automatically: +% \begin{macrocode} +\def\hyper@nopatch@longtable{} +% \end{macrocode} +% +% +% Should there be a module? +% +% \begin{macrocode} +%\NewModuleRelease{2024/06/01}{lttagging} +% {Tagging support} +% \end{macrocode} +% +% +% +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}{lttagging}% +% {Undo tagging support} +% +% +% +%\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex/base/lttemplates.dtx b/Master/texmf-dist/source/latex/base/lttemplates.dtx new file mode 100644 index 00000000000..7192359e726 --- /dev/null +++ b/Master/texmf-dist/source/latex/base/lttemplates.dtx @@ -0,0 +1,2634 @@ +% \iffalse meta-comment +% +% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle +% Copyright (C) 2004-2010 Frank Mittelbach, The LaTeX Project +% Copyright (C) 2011-2024 +% 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: lttemplates.dtx +% +%<*driver> +% \fi +\ProvidesFile{lttemplates.dtx} + [2024-04-17 v1.0c LaTeX Kernel (Prototype document functions)] +% \iffalse +\documentclass{l3doc} +\GetFileInfo{lttemplates.dtx} +\begin{document} + \DocInput{lttemplates.dtx} +\end{document} +% +% \fi +% +% \title{The \texttt{lttemplates.dtx} code\thanks{This file has version +% \fileversion\ dated \filedate, \copyright\ \LaTeX\ +% Project.}} +% \author{^^A +% Frank Mittelbach, Chris Rowley, David Carlisle, \LaTeX{} Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \maketitle +% +% \section{Introduction} +% +% There are three broad \enquote{layers} between putting down ideas into +% a source file and ending up with a typeset document. These layers of +% document writing are +% \begin{enumerate} +% \item authoring of the text with mark-up; +% \item document layout design; +% \item implementation (with \TeX{} programming) of the design. +% \end{enumerate} +% We write the text as an author, and we see the visual output of the design +% after the document is generated; the \TeX{} implementation in the middle is +% the glue between the two. +% +% \LaTeX{}'s greatest success has been to standardise a system of mark-up that +% balances the trade-off between ease of reading and ease of writing to suit +% almost all forms of technical writing. It's +% other original strength was a good background in typographical design; while +% the standard \LaTeXe{} classes look somewhat dated now in terms of their +% visual design, their typography is generally sound (barring the occasional +% minor faults). +% +% However, \LaTeXe{} has always lacked a standard approach to customising +% the visual design of a document. Changing the looks of the standard classes +% involved either: +% \begin{itemize} +% \item Creating a new version of the implementation code of the class and +% editing it. +% \item Loading one of the many packages to customise certain elements of +% the standard classes. +% \item Loading a completely different document class, such as +% \textsf{KOMA-Script} or \textsf{memoir}, that allows easy customisation. +% \end{itemize} +% All three of these approaches have their drawbacks and learning curves. +% +% The idea behind \pkg{lttemplates} is to cleanly separate the three layers +% introduced at the beginning of this section, so that document authors who +% are not programmers can easily change the design of their documents. +% \pkg{lttemplates} also makes it easier for \LaTeX{} programmers to provide +% their own customisations on top of a pre-existing class. +% +% \section{What is a document?} +% +% Besides the textual content of the words themselves, the source file +% of a document contains mark-up elements that add structure to the +% document. These elements include sectional divisions, figure/table +% captions, lists of various sorts, theorems/proofs, and so on. +% The list will be different for every document that can be written. +% +% Each element can be represented logically without worrying about the +% formatting, with mark-up such as \cs{section}, \cs{caption}, +% |\begin{enumerate}| and so on. The output of each one of these +% document elements will be a typeset representation of the information +% marked up, and the visual arrangement and design of these elements +% can vary widely in producing a variety of desired outcomes. +% +% For each type of document element, there may be design variations that +% contain the same sort of information but present it in slightly +% different ways. For example, the difference between a numbered and an +% unnumbered section, \cs{section} and |\section*|, or the difference +% between an itemised list or an enumerated list. +% +% There are three distinct layers in the definition of +% \enquote{a document} at this level +% \begin{enumerate} +% \item semantic elements such as the ideas of sections and lists; +% \item a set of design solutions for representing these elements +% visually; +% \item specific variations for these designs that represent the +% elements in the document. +% \end{enumerate} +% In the parlance of the template system, these are called types, +% templates, and instances, and they are discussed below in sections +% \ref{sec:types}, \ref{sec:templates}, and~\ref{sec:instances}, +% respectively. +% +% \section {Types, templates, and instances} +% +% By formally declaring documents to be composed of mark-up elements +% grouped into types, which are interpreted and typeset with a set of +% templates, each of which has one or more instances with which to +% compose each and every semantic unit of the text, we can cleanly +% separate the components of document construction. +% +% All of the structures provided by the template system are global, +% and do not respect \TeX{} grouping. +% +% \section{Template types} +% \label{sec:types} +% +% An \emph{template type} (sometimes just \enquote{type}) is an +% abstract idea of a document element that takes a fixed number of +% arguments corresponding to the information from the document author +% that it is representing. A sectioning type, for example, might take +% three inputs: \enquote{title}, \enquote{short title}, and +% \enquote{label}. +% +% Any given document class will define which types are to be +% used in the document, and any template of a given type can be +% used to generate an instance for the type. (Of course, different +% templates will produce different typeset representations, but the +% underlying content will be the same.) +% +% \begin{function}{\NewTemplateType} +% \begin{syntax} +% \cs{NewTemplateType} \Arg{template type} \Arg{no. of args} +% \end{syntax} +% This function defines an \meta{template type} taking +% \meta{number of arguments}, where the \meta{type} is an +% abstraction as discussed above. For example, +% \begin{verbatim} +% \NewTemplateType{sectioning}{3} +% \end{verbatim} +% creates a type \enquote{sectioning}, where each use of that +% type will need three arguments. +% \end{function} +% +% \section{Templates} +% \label{sec:templates} +% +% A \emph{template} is a generalised design solution for representing +% the information of a specified type. Templates that do the same +% thing, but in different ways, are grouped together by their type +% and given separate names. There are two important parts to a template: +% \begin{itemize} +% \item the parameters it takes to vary the design it is producing; +% \item the implementation of the design. +% \end{itemize} +% As a document author or designer does not care about the +% implementation but rather only the interface to the template, these two +% aspects of the template definition are split into two independent +% declarations, \cs{DeclareTemplateInterface} and +% \cs{DeclareTemplateCode}. +% +% \begin{function}{\DeclareTemplateInterface} +% \begin{syntax} +% \cs{DeclareTemplateInterface} +% ~~\Arg{type} \Arg{template} \Arg{no.~of args} +% ~~\Arg{key list} +% \end{syntax} +% A \meta{template} interface is declared for a particular +% \meta{type}, where the \meta{number of arguments} must +% agree with the type declaration. The interface itself is +% defined by the \meta{key list}, which is itself a key--value list +% taking a specialized format: +% \begin{quotation} +% \obeylines +% \noindent +% \meta{key1}~":"~\meta{key type1}~"," +% \meta{key2}~":"~\meta{key type2}~"," +% \meta{key3}~":"~\meta{key type3}~"="~\meta{default3}~"," +% \meta{key4}~":"~\meta{key type4}~"="~\meta{default4}~"," +% \ldots +% \end{quotation} +% Each \meta{key} name should consist of \textsc{ascii} characters, +% with the exception of |,|, |=| and \verb*| |. The recommended form +% for key names is to use lower case letters, with dashes to separate +% out different parts. Spaces are ignored in key names, so they can be +% included or missed out at will. Each \meta{key} must have a +% \meta{key type}, which defined the type of input that the \meta{key} +% requires. A full list of key types is given in +% Table~\ref{tab:key-types}. Each key may have a \meta{default} +% value, which will be used in by the template if the \meta{key} is +% not set explicitly. The \meta{default} should be of the correct +% form to be accepted by the \meta{key type} of the \meta{key}: this +% is not checked by the code. Expressions for numerical values are +% evaluated when the template is used, thus for example values given +% in terms of |em| or |ex| will be set respecting the prevailing font. +% \end{function} +% +% \begin{table} +% \centering +% \begin{tabular}{>{\ttfamily}ll} +% \toprule +% \multicolumn{1}{l}{Key-type} & Description of input \\ +% \midrule +% boolean & \texttt{true} or \texttt{false} \\ +% choice\Arg{choices} +% & A list of pre-defined \meta{choices} \\ +% commalist & A comma-separated list \\ +% function\Arg{$N$} +% & A function definition with $N$ arguments +% ($N$ from $0$ to $9$) \\ +% instance\Arg{name} +% & An instance of type \meta{name} \\ +% integer & An integer or integer expression \\ +% length & A fixed length \\ +% muskip & A math length with shrink and stretch components \\ +% real & A real (floating point) value \\ +% skip & A length with shrink and stretch components \\ +% tokenlist & A token list: any text or commands \\ +% \bottomrule +% \end{tabular} +% \caption{Key-types for defining template interfaces with +% \cs{DeclareTemplateInterface}.} +% \label{tab:key-types} +% \end{table} +% +% \begin{function}{\KeyValue} +% \begin{syntax} +% \cs{KeyValue} \Arg{key name} +% \end{syntax} +% There are occasions where the default (or value) for one key +% should be taken from another. The \cs{KeyValue} function can be +% used to transfer this information without needing to know the +% internal implementation of the key: +% \begin{verbatim} +% \DeclareTemplateInterface { type } { template } { no. of args } +% { +% key-name-1 : key-type = value , +% key-name-2 : key-type = \KeyValue { key-name-1 }, +% ... +% } +% \end{verbatim} +% \end{function} +% +% \begin{function}{\DeclareTemplateCode} +% \begin{syntax} +% \cs{DeclareTemplateCode} +% ~~\Arg{type} \Arg{template} \Arg{no.~of args} +% ~~\Arg{key bindings} \Arg{code} +% \end{syntax} +% The relationship between a templates keys and the internal +% implementation is created using the \cs{DeclareTemplateCode} +% function. As with \cs{DeclareTemplateInterface}, the +% \meta{template} name is given along with the \meta{type} +% and \meta{number of arguments} required. The \meta{key bindings} +% argument is a key--value list which specifies the relationship +% between each \meta{key} of the template interface with an +% underlying\meta{variable}. +% +% \begin{quotation} +% \obeylines +% \noindent +% \meta{key1}~"="~\meta{variable1}, +% \meta{key2}~"="~\meta{variable2}, +% \meta{key3}~"="~global~\meta{variable3}, +% \meta{key4}~"="~global~\meta{variable4}, +% \ldots +% \end{quotation} +% With the exception of the choice, code and function key types, +% the \meta{variable} here should be the name of an existing +% \LaTeX3 register. As illustrated, the key word \enquote{global} +% may be included in the listing to indicate that the \meta{variable} +% should be assigned globally. A full list of variable bindings is +% given in Table~\ref{tab:key-vars}. +% +% The \meta{code} argument of \cs{DeclareTemplateCode} is used +% as the replacement text for the template when it is used, either +% directly or as an instance. This may therefore accept arguments +% |#1|, |#2|, \emph{etc}.~as detailed by the \meta{number of arguments} +% taken by the type. +% \end{function} +% +% \begin{table} +% \centering +% \begin{tabular}{>{\ttfamily}ll} +% \toprule +% \multicolumn{1}{l}{Key-type} & Description of binding \\ +% \midrule +% \ & Boolean variable, \emph{e.g}.~\cs{l_tmpa_bool} \\ +% choice +% & List of choice implementations +% (see Section~\ref{sec:choices-key}) \\ +% commalist & Comma list, \emph{e.g}.~\cs{l_tmpa_clist} \\ +% function +% & Function taking $N$ arguments, \emph{e.g}.~\cs{use_i:nn} \\ +% instance \\ +% integer & Integer variable, \emph{e.g}.~\cs{l_tmpa_int} \\ +% length & Dimension variable, \emph{e.g}.~\cs{l_tmpa_dim} \\ +% muskip & Muskip variable, \emph{e.g}.~\cs{l_tmpa_muskip} \\ +% real & Floating-point variable, \emph{e.g}.~\cs{l_tmpa_fp} \\ +% skip & Skip variable, \emph{e.g}.~\cs{l_tmpa_skip} \\ +% tokenlist & Token list variable, \emph{e.g}.~\cs{l_tmpa_tl} \\ +% \bottomrule +% \end{tabular} +% \caption{Bindings required for different key types when defining +% template implementations with \cs{DeclareTemplateCode}. Apart +% from \texttt{code}, \texttt{choice} and \texttt{function} +% all of these accept the key word \texttt{global} to carry +% out a global assignment.} +% \label{tab:key-vars} +% \end{table} +% +% \begin{function}{\AssignTemplateKeys} +% \begin{syntax} +% \cs{AssignTemplateKeys} +% \end{syntax} +% In the final argument of \cs{DeclareTemplateCode} the assignment of +% keys defined by the template may be delayed by including the command +% \cs{AssignTemplateKeys}. If this is \emph{not} present, keys are assigned +% immediately before the template code. If \cs{AssignTemplateKeys} is +% present, assignment is delayed until this point. Note that the +% command must be \emph{directly} present in the code, not placed +% within a nested command/macro. +% \end{function} +% +% \begin{function}{\DeclareTemplateCopy} +% \begin{syntax} +% \cs{DeclareTemplateCopy} +% ~~\Arg{type} \Arg{template2} \Arg{template1} +% \end{syntax} +% Copies \meta{template1} of \meta{type} to a new name \meta{template2}: +% the copy can then be edited independent of teh original. +% \end{function} +% +% \section{Multiple choices} +% \label{sec:choices-key} +% +% The \texttt{choice} key type implements multiple choice input. At the +% interface level, only the list of valid choices is needed: +% \begin{verbatim} +% \DeclareTemplateInterface { foo } { bar } { 0 } +% { key-name : choice { A, B, C } } +% \end{verbatim} +% where the choices are given as a comma-list (which must therefore +% be wrapped in braces). A default value can also be given: +% \begin{verbatim} +% \DeclareTemplateInterface { foo } { bar } { 0 } +% { key-name : choice { A, B, C } = A } +% \end{verbatim} +% +% At the implementation level, each choice is associated with code, +% using a nested key--value list. +% \begin{verbatim} +% \DeclareTemplateCode { foo } { bar } { 0 } +% { +% key-name = +% { +% A = Code-A , +% B = Code-B , +% C = Code-C +% } +% } +% { ... } +% \end{verbatim} +% The two choice lists should match, but in the implementation a +% special \texttt{unknown} choice is also available. This can be used +% to ignore values and implement an \enquote{else} branch: +% \begin{verbatim} +% \DeclareTemplateCode { foo } { bar } { 0 } +% { +% key-name = +% { +% A = Code-A , +% B = Code-B , +% C = Code-C , +% unknown = Else-code +% } +% } +% { ... } +% \end{verbatim} +% The \texttt{unknown} entry must be the last one given, and should +% \emph{not} be listed in the interface part of the template. +% +% For keys which accept the values \texttt{true} and \texttt{false} +% both the boolean and choice key types can be used. As template +% interfaces are intended to prompt clarity at the design level, the +% boolean key type should be favoured, with the choice type reserved +% for keys which take arbitrary values. +% +% \section{Instances} +% \label{sec:instances} +% +% After a template is defined it still needs to be put to use. The +% parameters that it expects need to be defined before it can be used in +% a document. Every time a template has parameters given to it, an +% \emph{instance} is created, and this is the code that ends up in the +% document to perform the typesetting of whatever pieces of information +% are input into it. +% +% For example, a template might say \enquote{here is a section with or +% without a number that might be centred or left aligned and print its +% contents in a certain font of a certain size, with a bit of a gap +% before and after it} whereas an instance declares \enquote{this is a +% section with a number, which is centred and set in $12\,\text{pt}$ +% italic with a $10\,\text{pt}$ skip before and a +% $12\,\text{pt}$ skip after it}. Therefore, an instance is just a +% frozen version of a template with specific settings as chosen by the +% designer. +% +% \begin{function}{\DeclareInstance} +% \begin{syntax} +% \cs{DeclareInstance} +% ~~\Arg{type} \Arg{instance} \Arg{template} \Arg{parameters} +% \end{syntax} +% This function uses a \meta{template} for an \meta{type} +% to create an \meta{instance}. The \meta{instance} will be set +% up using the \meta{parameters}, which will set some of the +% \meta{keys} in the \meta{template}. +% +% As a practical example, consider a type for document sections +% (which might include chapters, parts, sections, \emph{etc}.), which +% is called \texttt{sectioning}. One possible template for this +% type might be called \texttt{basic}, and one instance of this +% template would be a numbered section. The instance declaration might +% read: +% \begin{verbatim} +% \DeclareInstance { sectioning } { section-num } { basic } +% { +% numbered = true , +% justification = center , +% font =\normalsize\itshape , +% before-skip = 10pt , +% after-skip = 12pt , +% } +% \end{verbatim} +% Of course, the key names here are entirely imaginary, but illustrate +% the general idea of fixing some settings. +% \end{function} +% +% \begin{function}{\IfInstanceExistsT, \IfInstanceExisstF, \IfInstanceExistsTF} +% \begin{syntax} +% \cs{IfInstanceExistsTF} \Arg{type} \Arg{instance} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the named \meta{instance} of a \meta{type} exists, and +% then inserts the appropriate code into the input stream. +% \end{function} +% +% \begin{function}{\DeclareInstanceCopy} +% \begin{syntax} +% \cs{DeclareInstanceCopy} +% ~~\Arg{type} \Arg{instance2} \Arg{instance1} +% \end{syntax} +% Copies the \meta{values} for \meta{instance1} for an +% \meta{type} to \meta{instance2}. +% \end{function} +% +% \section{Document interface} +% +% After the instances have been chosen, document commands must be +% declared to use those instances in the document. \cs{UseInstance} +% calls instances directly, and this command should be used internally +% in document-level mark-up. +% +% \begin{function}{\UseInstance} +% \begin{syntax} +% \cs{UseInstance} +% ~~\Arg{type} \Arg{instance} \meta{arguments} +% \end{syntax} +% Uses an \meta{instance} of the \meta{type}, which will require +% \meta{arguments} as determined by the number specified for the +% \meta{type}. The \meta{instance} must have been declared +% before it can be used, otherwise an error is raised. +% \end{function} +% +% \begin{function}{\UseTemplate} +% \begin{syntax} +% \cs{UseTemplate} \Arg{type} \Arg{template} +% ~~\Arg{settings} \meta{arguments} +% \end{syntax} +% Uses the \meta{template} of the specified \meta{type}, +% applying the \meta{settings} and absorbing \meta{arguments} as +% detailed by the \meta{type} declaration. This in effect +% is the same as creating an instance using \cs{DeclareInstance} +% and immediately using it with \cs{UseInstance}, but without the +% instance having any further existence. It is therefore useful where +% a template needs to be used once. +% +% This function can also be used as the argument to \texttt{instance} +% key types: +% \begin{verbatim} +% \DeclareInstance { type } { template } { instance } +% { +% instance-key = +% \UseTemplate { type2 } { template2 } { } +% } +% \end{verbatim} +% \end{function} +% +% \section{Changing existing definitions} +% +% Template parameters may be assigned specific defaults for instances +% to use if the instance declaration doesn't explicit set those +% parameters. In some cases, the document designer will wish to edit +% these defaults to allow them to \enquote{cascade} to the instances. +% The alternative would be to set each parameter identically for each +% instance declaration, a tedious and error-prone process. +% +% \begin{function}{\EditTemplateDefaults} +% \begin{syntax} +% \cs{EditTemplateDefaults} +% ~~\Arg{type} \Arg{template} \Arg{new defaults} +% \end{syntax} +% Edits the \meta{defaults} for a \meta{template} for an +% \meta{type}. The \meta{new defaults}, given as a key--value +% list, replace the existing defaults for the \meta{template}. This +% means that the change will apply to instances declared after the +% editing, but that instances which have already been created are +% unaffected. +% \end{function} +% +% \begin{function}{\EditInstance} +% \begin{syntax} +% \cs{EditInstance} +% ~~\Arg{type} \Arg{instance} \Arg{new values} +% \end{syntax} +% Edits the \meta{values} for an \meta{instance} for an +% \meta{type}. The \meta{new values}, given as a key--value +% list, replace the existing values for the \meta{instance}. This +% function is complementary to \cs{EditTemplateDefaults}: +% \cs{EditInstance} changes a single instance while leaving the +% template untouched. +% \end{function} +% +% \section{\emph{Ad hoc} adjustment of templates} +% +% \begin{function}{\SetTemplateKeys} +% \begin{syntax} +% \cs{SetTemplateKeys} \Arg{type} \Arg{template} \Arg{keyvals} +% \end{syntax} +% At point of use it may be useful to apply changed to individual instances. +% This is supported as each template key is made available for adjustment +% using \cs{SetTemplateKeys}. +% \end{function} +% +% For example, after +% \begin{verbatim} +% \NewTypeType{MyObj}{0} +% \DeclareTemplateInterface{MyObj}{TemplateA}{0} +% { +% akey: tokenlist , +% bkey: function{2} +% } +% \DeclareTemplateCode{MyObj}{TemplateA}{0} +% { +% akey = SomeTokens , +% bkey = \func:nn , +% } +% \end{verbatim} +% the template keys could be adjusted in an \emph{ad hoc} fashion using +% \begin{verbatim} +% \SetTemplateKeys{MyObj}{TemplateA} +% { +% akey = OtherTokens , +% bkey = \AltFunc:nn +% } +% \end{verbatim} +% +% \section{Getting information about templates and instances} +% +% \begin{function}{\ShowInstanceValues} +% \begin{syntax} +% \cs{ShowInstanceValues} \Arg{type} \Arg{instance} +% \end{syntax} +% Shows the \meta{values} for an \meta{instance} of the given +% \meta{type} at the terminal. +% \end{function} +% +% \begin{function}{\ShowTemplateCode} +% \begin{syntax} +% \cs{ShowTemplateCode} \Arg{type} \Arg{template} +% \end{syntax} +% Shows the \meta{code} of a \meta{template} for an \meta{type} +% in the terminal. +% \end{function} +% +% \begin{function}{\ShowTemplateDefaults} +% \begin{syntax} +% \cs{ShowTemplateDefaults} \Arg{type} \Arg{template} +% \end{syntax} +% Shows the \meta{default} values of a \meta{template} for an +% \meta{type} in the terminal. +% \end{function} +% +% \begin{function}{\ShowTemplateInterface} +% \begin{syntax} +% \cs{ShowTemplateInterface} \Arg{type} \Arg{template} +% \end{syntax} +% Shows the \meta{keys} and associated \meta{key types} of a +% \meta{template} for an \meta{type} in the terminal. +% \end{function} +% +% \begin{function}{\ShowTemplateVariables} +% \begin{syntax} +% \cs{ShowTemplateVariables} \Arg{type} \Arg{template} +% \end{syntax} +% Shows the \meta{variables} and associated \meta{keys} of a +% \meta{template} for an \meta{type} in the terminal. Note that +% \texttt{code} and \texttt{choice} keys do not map directly to variables +% but to arbitrary code. For \texttt{choice} keys, each valid choice +% is shown as a separate entry in the list, with the key name and choice +% separated by a space, for example +% \begin{verbatim} +% Template 'example' of type 'example' has variable mapping: +% > demo unknown => \def \demo {?} +% > demo c => \def \demo {c} +% > demo b => \def \demo {b} +% > demo a => \def \demo {a}. +% \end{verbatim} +% would be shown for a choice key \texttt{demo} with valid choices +% \texttt{a}, \texttt{b} and \texttt{c}, plus code for an \texttt{unknown} +% branch. +% \end{function} +% +% \MaybeStop{\setlength\IndexMin{200pt}\PrintIndex} +% +% \section{The implementation} +% +% \begin{macrocode} +%<@@=template> +% \end{macrocode} +% +% \begin{macrocode} +%<*2ekernel> +\message{templates,} +% +% \end{macrocode} +% +% \begin{macrocode} +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} +%\NewModuleRelease{2024/06/01}{lttemplates} +% {Prototype~document~commands}% +% \end{macrocode} +% +% \subsection{Variables and constants} +% +% \begin{variable} +% { +% \c_@@_code_root_tl , +% \c_@@_defaults_root_tl , +% \c_@@_instances_root_tl , +% \c_@@_keytypes_root_tl , +% \c_@@_key_order_root_tl , +% \c_@@_restrict_root_tl , +% \c_@@_values_root_tl , +% \c_@@_vars_root_tl +% } +% So that literal values are kept to a minimum. +% \begin{macrocode} +\tl_const:Nn \c_@@_code_root_tl { template~code~>~ } +\tl_const:Nn \c_@@_defaults_root_tl { template~defaults~>~ } +\tl_const:Nn \c_@@_instances_root_tl { template~instance~>~ } +\tl_const:Nn \c_@@_keytypes_root_tl { template~key~types~>~ } +\tl_const:Nn \c_@@_key_order_root_tl { template~key~order~>~ } +\tl_const:Nn \c_@@_values_root_tl { template~values~>~ } +\tl_const:Nn \c_@@_vars_root_tl { template~vars~>~ } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_@@_keytypes_arg_seq} +% A list of keytypes which also need additional data (an argument), +% used to parse the keytype correctly. +% \begin{macrocode} +\seq_const_from_clist:Nn \c_@@_keytypes_arg_seq + { choice , function , instance } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_@@_type_prop} +% For storing types and the associated number of arguments. +% \begin{macrocode} +\prop_new:N \g_@@_type_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_assignments_tl} +% When creating an instance, the assigned values are collected here. +% \begin{macrocode} +\tl_new:N \l_@@_assignments_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\l_@@_default_tl} +% The default value for a key is recovered here from the property list +% in which it is stored. +% \begin{macrocode} +\tl_new:N \l_@@_default_tl +% \end{macrocode} +%\ end{macro} +% +% \begin{variable}{\l_@@_error_bool} +% A flag for errors to be carried forward. +% \begin{macrocode} +\bool_new:N \l_@@_error_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_global_bool} +% Used to indicate that assignments should be global. +% \begin{macrocode} +\bool_new:N \l_@@_global_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_key_name_tl , +% \l_@@_keytype_tl , +% \l_@@_keytype_arg_tl , +% \l_@@_value_tl , +% \l_@@_var_tl +% } +% When defining each key in a template, the name and type of the key +% need to be separated and stored. Any argument needed by the +% keytype is also stored separately. +% \begin{macrocode} +\tl_new:N \l_@@_key_name_tl +\tl_new:N \l_@@_keytype_tl +\tl_new:N \l_@@_keytype_arg_tl +\tl_new:N \l_@@_value_tl +\tl_new:N \l_@@_var_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_keytypes_prop , +% \l_@@_key_order_seq , +% \l_@@_values_prop , +% \l_@@_vars_prop +% } +% To avoid needing too many difficult-to-follow csname assignments, +% various scratch token registers are used to build up data, which is +% then transferred +% \begin{macrocode} +\prop_new:N \l_@@_keytypes_prop +\seq_new:N \l_@@_key_order_seq +\prop_new:N \l_@@_values_prop +\prop_new:N \l_@@_vars_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable} +% { +% \l_@@_tmp_clist , +% \l_@@_tmp_dim , +% \l_@@_tmp_int , +% \l_@@_tmp_muskip , +% \l_@@_tmp_skip , +% \l_@@_tmp_tl +% } +% Scratch space. +% \begin{macrocode} +\clist_new:N \l_@@_tmp_clist +\dim_new:N \l_@@_tmp_dim +\int_new:N \l_@@_tmp_int +\muskip_new:N \l_@@_tmp_muskip +\skip_new:N \l_@@_tmp_skip +\tl_new:N \l_@@_tmp_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\s_@@_mark, \s_@@_stop} +% Internal scan marks. +% \begin{macrocode} +\scan_new:N \s_@@_mark +\scan_new:N \s_@@_stop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\q_@@_nil} +% Internal quarks. +% \begin{macrocode} +\quark_new:N \q_@@_nil +% \end{macrocode} +% \end{variable} +% +% \begin{macro}[pTF]{\@@_quark_if_nil:n} +% Branching quark conditional. +% \begin{macrocode} +\__kernel_quark_new_conditional:Nn \@@_quark_if_nil:N { F } +% \end{macrocode} +% \end{macro} +% +% \subsection{Testing existence and validity} +% +% There are a number of checks needed for either the existence of +% a type, template or instance. There are also some for the +% validity of a particular call. All of these are collected up here. +% +% \begin{macro}{\@@_execute_if_arg_agree:nnT} +% A test agreement between the number of arguments for the template +% type and that specified when creating a template. This is not done as a +% separate conditional for efficiency and better error message +% \begin{macrocode} +\cs_new_protected:Npn \@@_execute_if_arg_agree:nnT #1#2#3 + { + \prop_get:NnN \g_@@_type_prop {#1} \l_@@_tmp_tl + \int_compare:nNnTF {#2} = \l_@@_tmp_tl + {#3} + { + \msg_error:nneee { template } { argument-number-mismatch } + {#1} { \l_@@_tmp_tl } {#2} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_execute_if_code_exist:nnT} +% A template is only fully declared if the code has been set up, +% which can be checked by looking for the template function itself. +% \begin{macrocode} +\cs_new_protected:Npn \@@_execute_if_code_exist:nnT #1#2#3 + { + \cs_if_exist:cTF { \c_@@_code_root_tl #1 / #2 } + {#3} + { \msg_error:nnnn { template } { no-template-code } {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% {\@@_execute_if_keytype_exist:nT, \@@_execute_if_keytype_exist:VT} +% The test for valid keytypes looks for a function to set up the key, +% which is part of the \enquote{code} side of the template definition. +% This avoids having different lists for the two parts of the process. +% \begin{macrocode} +\cs_new_protected:Npn \@@_execute_if_keytype_exist:nT #1#2 + { + \cs_if_exist:cTF { @@_store_value_ #1 :n } + {#2} + { \msg_error:nnn { template } { unknown-keytype } {#1} } + } +\cs_generate_variant:Nn \@@_execute_if_keytype_exist:nT { V } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_execute_if_type_exist:nT} +% To check that a particular type is valid. +% \begin{macrocode} +\cs_new_protected:Npn \@@_execute_if_type_exist:nT #1#2 + { + \prop_if_in:NnTF \g_@@_type_prop {#1} + {#2} + { \msg_error:nnn { template } { unknown-type } {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_execute_if_keys_exist:nnT} +% To check that the keys for a template have been set up before trying +% to create any code, a simple check for the correctly-named keytype +% property list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_if_keys_exist:nnT #1#2#3 + { + \cs_if_exist:cTF { \c_@@_keytypes_root_tl #1 / #2 } + {#3} + { \msg_error:nnnn { template } { unknown-template } {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\@@_if_key_value:n, \@@_if_key_value:V} +% Tests for the first token in a string being \cs{KeyValue}. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_key_value:n #1 { T , F , TF } + { + \str_if_eq:noTF { \KeyValue } { \tl_head:w #1 \q_nil \q_stop } + \prg_return_true: + \prg_return_false: + } +\prg_generate_conditional_variant:Nnn \@@_if_key_value:n { V } { T , F , TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\@@_if_instance_exist:nn} +% Testing for an instance +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_instance_exist:nn #1#2 { T, F, TF } + { + \cs_if_exist:cTF { \c_@@_instances_root_tl #1 / #2 } + \prg_return_true: + \prg_return_false: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_if_use_template:nTF} +% Tests for the first token in a string being \cs{UseTemplate}. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_if_use_template:n #1 { TF } + { + \str_if_eq:noTF { \UseTemplate } { \tl_head:w #1 \q_nil \q_stop } + \prg_return_true: + \prg_return_false: +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Saving and recovering property lists} +% +% The various property lists for templates have to be shuffled in +% and out of storage. +% +% \begin{macro} +% { +% \@@_store_defaults:nn , +% \@@_store_keytypes:nn , +% \@@_store_values:nn , +% \@@_store_vars:nn +% } +% The defaults and keytypes are transferred from the scratch property +% lists to the \enquote{proper} lists for the template being created. +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_defaults:nn #1#2 + { + \debug_suspend: + \prop_gclear_new:c { \c_@@_defaults_root_tl #1 / #2 } + \prop_gset_eq:cN { \c_@@_defaults_root_tl #1 / #2 } + \l_@@_values_prop + \debug_resume: + } +\cs_new_protected:Npn \@@_store_keytypes:nn #1#2 + { + \debug_suspend: + \prop_if_exist:cTF { \c_@@_keytypes_root_tl #1 / #2 } + { + \msg_info:nnnn { template } { declare-template-interface } {#1} {#2} + \prop_gclear:c { \c_@@_keytypes_root_tl #1 / #2 } + } + { \prop_new:c { \c_@@_keytypes_root_tl #1 / #2 } } + \prop_gset_eq:cN { \c_@@_keytypes_root_tl #1 / #2 } + \l_@@_keytypes_prop + \seq_gclear_new:c { \c_@@_key_order_root_tl #1 / #2 } + \seq_gset_eq:cN { \c_@@_key_order_root_tl #1 / #2 } + \l_@@_key_order_seq + \debug_resume: + } +\cs_new_protected:Npn \@@_store_values:nn #1#2 + { + \debug_suspend: + \prop_clear_new:c { \c_@@_values_root_tl #1 / #2 } + \prop_set_eq:cN { \c_@@_values_root_tl #1 / #2 } + \l_@@_values_prop + \debug_resume: + } +\cs_new_protected:Npn \@@_store_vars:nn #1#2 + { + \debug_suspend: + \prop_gclear_new:c { \c_@@_vars_root_tl #1 / #2 } + \prop_gset_eq:cN { \c_@@_vars_root_tl #1 / #2 } + \l_@@_vars_prop + \debug_resume: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_recover_defaults:nn , +% \@@_recover_keytypes:nn , +% \@@_recover_values:nn , +% \@@_recover_vars:nn +% } +% Recovering the stored data for a template is rather less complex +% than storing it. All that happens is the data is transferred from +% the permanent to the scratch storage. However, we need to check the +% scratch storage does exist. +% \begin{macrocode} +\cs_new_protected:Npn \@@_recover_defaults:nn #1#2 + { + \prop_if_exist:cTF + { \c_@@_defaults_root_tl #1 / #2 } + { + \prop_set_eq:Nc \l_@@_values_prop + { \c_@@_defaults_root_tl #1 / #2 } + } + { \prop_clear:N \l_@@_values_prop } + } +\cs_new_protected:Npn \@@_recover_keytypes:nn #1#2 + { + \prop_if_exist:cTF + { \c_@@_keytypes_root_tl #1 / #2 } + { + \prop_set_eq:Nc \l_@@_keytypes_prop + { \c_@@_keytypes_root_tl #1 / #2 } + } + { \prop_clear:N \l_@@_keytypes_prop } + \seq_if_exist:cTF { \c_@@_key_order_root_tl #1 / #2 } + { + \seq_set_eq:Nc \l_@@_key_order_seq + { \c_@@_key_order_root_tl #1 / #2 } + } + { \seq_clear:N \l_@@_key_order_seq } + } +\cs_new_protected:Npn \@@_recover_values:nn #1#2 + { + \prop_if_exist:cTF + { \c_@@_values_root_tl #1 / #2 } + { + \prop_set_eq:Nc \l_@@_values_prop + { \c_@@_values_root_tl #1 / #2 } + } + { \prop_clear:N \l_@@_values_prop } + } +\cs_new_protected:Npn \@@_recover_vars:nn #1#2 + { + \prop_if_exist:cTF + { \c_@@_vars_root_tl #1 / #2 } + { + \prop_set_eq:Nc \l_@@_vars_prop + { \c_@@_vars_root_tl #1 / #2 } + } + { \prop_clear:N \l_@@_vars_prop } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Creating new template types} +% +% \begin{macro}{\@@_define_type:nn, \@@_declare_type:nn} +% Although the type is the \enquote{top level} of the template +% system, it is actually very easy to implement. All that happens is that +% the number of arguments required is recorded, indexed by the name of the +% type. +% \begin{macrocode} +\cs_new_protected:Npn \@@_define_type:nn #1#2 + { + \prop_if_in:NnTF \g_@@_type_prop {#1} + { \msg_error:nnn { template } { type-already-defined } {#1} } + { \@@_declare_type:nn {#1} {#2} } + } +\cs_new_protected:Npn \@@_declare_type:nn #1#2 + { + \int_set:Nn \l_@@_tmp_int {#2} + \int_compare:nTF { 0 <= \l_@@_tmp_int <= 9 } + { + \msg_info:nnnV { template } { declare-type } + {#1} \l_@@_tmp_int + \prop_gput:NnV \g_@@_type_prop {#1} + \l_@@_tmp_int + } + { + \msg_error:nnnV { template } { bad-number-of-arguments } + {#1} \l_@@_tmp_int + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Design part of template declaration} +% +% The \enquote{design} part of a template declaration defines the general +% behaviour of each key, and possibly a default value. However, it does +% not include the implementation. This means that what happens here is +% the two properties are saved to appropriate lists, which can then +% be used later to recover the information when implementing the keys. +% +% \begin{macro}{\@@_declare_template_keys:nnnn} +% The main function for the \enquote{design} part of creating a template +% starts by checking that the type exists and that the number of +% arguments required agree. If that is all fine, then the two storage +% areas for defaults and keytypes are initialised. The mechanism is then +% set up for the \pkg{l3keys} module to actually parse the keys. +% Finally, the code hands of to the storage routine to save the parsed +% information properly. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_template_keys:nnnn #1#2#3#4 + { + \@@_execute_if_type_exist:nT {#1} + { + \@@_execute_if_arg_agree:nnT {#1} {#3} + { + \prop_clear:N \l_@@_values_prop + \prop_clear:N \l_@@_keytypes_prop + \seq_clear:N \l_@@_key_order_seq + \keyval_parse:NNn + \@@_parse_keys_elt:n \@@_parse_keys_elt:nn {#4} + \@@_store_defaults:nn {#1} {#2} + \@@_store_keytypes:nn {#1} {#2} + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_keys_elt:n} +% \begin{macro}{\@@_parse_keys_elt_aux:n} +% \begin{macro}{\@@_parse_keys_elt_aux:} +% Processing the key part of the key--value pair is always carried out +% using this function, even if a value was found. First, the key name +% is separated from the keytype, and if necessary the keytype is +% separated into two parts. This information is then used to check that +% the keytype is valid, before storing the keytype (plus argument if +% necessary) as a property of the key name. The key name is also stored +% (in braces) in the token list to record the order the keys are defined +% in. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_keys_elt:n #1 + { + \@@_split_keytype:n {#1} + \bool_if:NF \l_@@_error_bool + { + \@@_execute_if_keytype_exist:VT \l_@@_keytype_tl + { + \seq_map_function:NN \c_@@_keytypes_arg_seq + \@@_parse_keys_elt_aux:n + \bool_if:NF \l_@@_error_bool + { + \seq_if_in:NoTF \l_@@_key_order_seq + \l_@@_key_name_tl + { + \msg_error:nnV { template } { duplicate-key-interface } + \l_@@_key_name_tl + } + { \@@_parse_keys_elt_aux: } + } + } + } + } +\cs_new_protected:Npn \@@_parse_keys_elt_aux:n #1 + { + \str_if_eq:VnT \l_@@_keytype_tl {#1} + { + \tl_if_empty:NT \l_@@_keytype_arg_tl + { + \msg_error:nnn { template } { keytype-requires-argument } {#1} + \bool_set_true:N \l_@@_error_bool + \seq_map_break: + } + } + } +\cs_new_protected:Npn \@@_parse_keys_elt_aux: + { + \tl_set:Ne \l_@@_tmp_tl + { + \l_@@_keytype_tl + \tl_if_empty:NF \l_@@_keytype_arg_tl + { { \l_@@_keytype_arg_tl } } + } + \prop_put:NVV \l_@@_keytypes_prop \l_@@_key_name_tl + \l_@@_tmp_tl + \seq_put_right:NV \l_@@_key_order_seq \l_@@_key_name_tl + \str_if_eq:VnT \l_@@_keytype_tl { choice } + { + \clist_if_in:NnT \l_@@_keytype_arg_tl { unknown } + { \msg_error:nn { template } { choice-unknown-reserved } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parse_keys_elt:nn} +% For keys which have a default, the keytype and key name are first +% separated out by the \cs{@@_parse_keys_elt:n} +% routine, before storing the default value in the scratch property list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_keys_elt:nn #1#2 + { + \@@_parse_keys_elt:n {#1} + \use:c { @@_store_value_ \l_@@_keytype_tl :n } {#2} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_split_keytype:n} +% \begin{macro}{\@@_split_keytype_aux:w} +% The keytype and key name should be separated by |:|. As the +% definition might be given inside or outside of a code block, +% the category code of colons is standardised. After +% that, the standard delimited argument method is used to separate the +% two parts. +% \begin{macrocode} +\cs_new_protected:Npe \@@_split_keytype:n #1 + { + \exp_not:N \bool_set_false:N \exp_not:N \l_@@_error_bool + \tl_set:Nn \exp_not:N \l_@@_tmp_tl {#1} + \tl_replace_all:Nnn \exp_not:N \l_@@_tmp_tl { : } { \token_to_str:N : } + \tl_if_in:VnTF \exp_not:N \l_@@_tmp_tl { \token_to_str:N : } + { + \exp_not:n + { + \tl_clear:N \l_@@_key_name_tl + \exp_after:wN \@@_split_keytype_aux:w + \l_@@_tmp_tl \s_@@_stop + } + } + { + \exp_not:N \bool_set_true:N \exp_not:N \l_@@_error_bool + \msg_error:nnn { template } { missing-keytype } {#1} + } + } +\use:e + { + \cs_new_protected:Npn \exp_not:N \@@_split_keytype_aux:w + #1 \token_to_str:N : #2 \s_@@_stop + { + \tl_put_right:Ne \exp_not:N \l_@@_key_name_tl + { + \exp_not:N \tl_trim_spaces:e + { \exp_not:N \tl_to_str:n {#1} } + } + \tl_if_in:nnTF {#2} { \token_to_str:N : } + { + \tl_put_right:Nn \exp_not:N \l_@@_key_name_tl + { \token_to_str:N : } + \exp_not:N \@@_split_keytype_aux:w #2 \s_@@_stop + } + { + \exp_not:N \tl_if_empty:NTF \exp_not:N \l_@@_key_name_tl + { + \msg_error:nnn { template } { empty-key-name } + { \token_to_str:N : #2 } + } + { \exp_not:N \@@_split_keytype_arg:n {#2} } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_split_keytype_arg:n, \@@_split_keytype_arg:V} +% \begin{macro}{\@@_split_keytype_arg_aux:n} +% \begin{macro}{\@@_split_keytype_arg_aux:w} +% The second stage of sorting out the keytype is to check for an +% argument. As there is no convenient delimiting token to look for, +% a check is made instead for each possible text value for the keytype. +% To keep things faster, this only involves the keytypes that need an +% argument. If a match is made, then a check is also needed to see that +% it is at the start of the keytype information. All being well, the +% split can then be applied. Any non-matching keytypes are assumed to +% be \enquote{correct} as given, and are left alone (this is checked by +% other code). +% \begin{macrocode} +\cs_new_protected:Npn \@@_split_keytype_arg:n #1 + { + \tl_set:Ne \l_@@_keytype_tl { \tl_trim_spaces:n {#1} } + \tl_clear:N \l_@@_keytype_arg_tl + \cs_set_protected:Npn \@@_split_keytype_arg_aux:n ##1 + { + \tl_if_in:nnT {#1} {##1} + { + \cs_set:Npn \@@_split_keytype_arg_aux:w + ####1 ##1 ####2 \s_@@_stop + { + \tl_if_blank:nT {####1} + { + \tl_set:Ne \l_@@_keytype_tl + { \tl_trim_spaces:n {##1} } + \tl_if_blank:nF {####2} + { + \tl_set:Ne \l_@@_keytype_arg_tl + { \use:n ####2 } + } + \seq_map_break: + } + } + \@@_split_keytype_arg_aux:w #1 \s_@@_stop + } + } + \seq_map_function:NN \c_@@_keytypes_arg_seq + \@@_split_keytype_arg_aux:n + } +\cs_generate_variant:Nn \@@_split_keytype_arg:n { V } +\cs_new:Npn \@@_split_keytype_arg_aux:n #1 { } +\cs_new:Npn \@@_split_keytype_arg_aux:w #1 \s_@@_stop { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Storing values} +% +% As \pkg{lttemplates} pre-processes key values for efficiency reasons, +% there is a need to convert the values given as defaults into +% \enquote{ready to use} data. The same general idea is true when an instance +% is declared. However, assignments are not made until an instance is +% used, and so there has to be some intermediate storage. Furthermore, +% the ability to delay evaluation of results is needed. To achieve these +% aims, a series of \enquote{process and store} functions are defined here. +% +% All of the information about the key (the key name and the keytype) +% is already stored as variables. The same property list is always used +% to store the data, meaning that the only argument required is the +% value to be processed and potentially stored. +% +% \begin{macro}{\@@_store_value_boolean:n} +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_value_boolean:n #1 + { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_store_value:n, \@@_store_value_choice:n, +% \@@_store_value_function:n, \@@_store_value_instance:n} +% With no need to worry about delayed evaluation, these keytypes all +% just store the input directly. +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_value:n #1 + { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#1} } +\cs_new_eq:NN \@@_store_value_choice:n \@@_store_value:n +\cs_new_eq:NN \@@_store_value_function:n \@@_store_value:n +\cs_new_eq:NN \@@_store_value_instance:n \@@_store_value:n +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_store_value_aux:Nn, \@@_store_value_integer:n, +% \@@_store_value_length:n, \@@_store_value_muskip:n, +% \@@_store_value_real:n, \@@_store_value_skip:n, +% \@@_store_value_tokenlist:n, \@@_store_value_commalist:n} +% Storing values in \cs{l_@@_values_prop} is in most cases the same. +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_value_aux:Nn #1#2 + { \prop_put:Non \l_@@_values_prop \l_@@_key_name_tl {#2} } +\cs_new_protected:Npn \@@_store_value_integer:n + { \@@_store_value_aux:Nn \int_eval:n } +\cs_new_protected:Npn \@@_store_value_length:n + { \@@_store_value_aux:Nn \dim_eval:n } +\cs_new_protected:Npn \@@_store_value_muskip:n + { \@@_store_value_aux:Nn \muskip_eval:n } +\cs_new_protected:Npn \@@_store_value_real:n + { \@@_store_value_aux:Nn \fp_eval:n } +\cs_new_protected:Npn \@@_store_value_skip:n + { \@@_store_value_aux:Nn \skip_eval:n } +\cs_new_protected:Npn \@@_store_value_tokenlist:n + { \@@_store_value_aux:Nn \use:n } +\cs_new_eq:NN \@@_store_value_commalist:n \@@_store_value_tokenlist:n +% \end{macrocode} +% \end{macro} +% +% \subsection{Implementation part of template declaration} +% +% \begin{macro}{\@@_declare_template_code:nnnnn} +% \begin{macro}{\@@_declare_template_code:nnnn} +% The main function for implementing a template starts with a couple of +% simple checks to make sure that there are no obvious mistakes: the +% number of arguments must agree and the template keys must have been +% declared. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_template_code:nnnnn #1#2#3#4#5 + { + \@@_execute_if_type_exist:nT {#1} + { + \@@_execute_if_arg_agree:nnT {#1} {#3} + { + \@@_if_keys_exist:nnT {#1} {#2} + { + \@@_store_key_implementation:nnn {#1} {#2} {#4} + \regex_match:nnTF { \c { AssignTemplateKeys } } {#5} + { \@@_declare_template_code:nnnn {#1} {#2} {#3} {#5} } + { + \@@_declare_template_code:nnnn + {#1} {#2} {#3} { \AssignTemplateKeys #5 } + } + } + } + } + } +\cs_new_protected:Npn \@@_declare_template_code:nnnn #1#2#3#4 + { + \cs_if_exist:cT { \c_@@_code_root_tl #1 / #2 } + { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} } + \cs_generate_from_arg_count:cNnn + { \c_@@_code_root_tl #1 / #2 } + \cs_gset_protected:Npn {#3} {#4} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_store_key_implementation:nnn} +% Actually storing the implementation part of a template is quite easy +% as it only requires the list of keys given to be turned into a +% property list. There is also some error-checking to do, hence the need +% to have the list of defined keytypes available. In certain cases +% (when choices are involved) parsing the key results in changes to the +% default values. That is why they are loaded and then saved again. +% \begin{macrocode} +\cs_new_protected:Npn \@@_store_key_implementation:nnn #1#2#3 + { + \@@_recover_defaults:nn {#1} {#2} + \@@_recover_keytypes:nn {#1} {#2} + \prop_clear:N \l_@@_vars_prop + \keyval_parse:nnn + { \@@_parse_vars_elt:n } { \@@_parse_vars_elt:nnn { #1 / #2 } } {#3} + \@@_store_vars:nn {#1} {#2} + \prop_map_inline:Nn \l_@@_keytypes_prop + { \msg_error:nnnnn { template } { key-not-implemented } {##1} {#2} {#1} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_vars_elt:n} +% At the implementation stage, every key must have a value given. So +% this is an error function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_vars_elt:n #1 + { \msg_error:nnn { template } { key-no-variable } {#1} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_vars_elt:nnn} +% \begin{macro}{\@@_parse_vars_elt_aux:nn} +% \begin{macro}{\@@_parse_vars_elt_aux:nw} +% \begin{macro}{\@@_parse_vars_elt_aux:nnn, \@@_parse_vars_elt_aux:nne} +% \begin{macro}{\@@_parse_vars_elt_key:nn} +% The actual storage part here is very simple: the storage bin name +% is placed into the property list. At the same time, a comparison is +% made with the keytypes defined earlier: if there is a mismatch then +% an error is raised. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_vars_elt:nnn #1#2#3 + { + \tl_set:Ne \l_@@_key_name_tl + { \tl_trim_spaces:e { \tl_to_str:n {#2} } } + \prop_get:NVNTF \l_@@_keytypes_prop + \l_@@_key_name_tl + \l_@@_keytype_tl + { + \@@_split_keytype_arg:V \l_@@_keytype_tl + \@@_parse_vars_elt_aux:nn {#1} {#3} + \prop_remove:NV \l_@@_keytypes_prop \l_@@_key_name_tl + } + { \msg_error:nnn { template } { unknown-key } {#2} } + } +% \end{macrocode} +% Split off any leading \texttt{global} and they look for the way to +% implement. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_vars_elt_aux:nn #1#2 + { + \@@_parse_vars_elt_aux:nw {#1} #2 global global \s_@@_stop + } +\cs_new_protected:Npn \@@_parse_vars_elt_aux:nw + #1#2 global #3 global #4 \s_@@_stop + { + \tl_if_blank:nTF {#4} + { \@@_parse_vars_elt_aux:nnn {#1} { } {#2} } + { + \tl_if_blank:nTF {#2} + { + \@@_parse_vars_elt_aux:nne + {#1} { global } { \tl_trim_spaces:n {#3} } + } + { \msg_error:nnn { template } { bad-variable } { #2 global #3 } } + } + } +\cs_new_protected:Npn \@@_parse_vars_elt_aux:nnn #1#2#3 + { + \str_case:VnF \l_@@_keytype_tl + { + { choice } { \@@_implement_choices:nn {#1} {#3} } + { function } + { + \cs_if_exist:NF #3 + { \cs_new:Npn #3 { } } + \@@_parse_vars_elt_key:nn {#1} + { + .code:n = + { + \cs_generate_from_arg_count:NNnn + \exp_not:N #3 + \exp_not:c + { cs_ \str_if_eq:nnT {#1} { global } { g } set:Npn } + { \exp_not:V \l_@@_keytype_arg_tl } + {##1} + } + } + \prop_put:NVn \l_@@_vars_prop + \l_@@_key_name_tl {#2#3} + } + { instance } + { + \@@_parse_vars_elt_key:nn {#1} + { + .code:n = + { + \exp_not:c + { cs_ \str_if_eq:nnT {#1} { global } { g } set:Npn } + \exp_not:N #3 { \UseInstance {##1} } + } + } + \prop_put:NVn \l_@@_vars_prop + \l_@@_key_name_tl {#2#3} + } + } + { + \tl_if_single:nTF {#3} + { + \cs_if_exist:NF #3 + { \use:c { \@@_map_var_type: _new:N } #3 } + \@@_parse_vars_elt_key:nn {#1} + { + . \@@_map_var_type: + _ \str_if_eq:nnT {#1} { global } { g } set:N + = \exp_not:N #3 + } + \prop_put:NVn \l_@@_vars_prop + \l_@@_key_name_tl {#2#3} + } + { \msg_error:nnn { template } { bad-variable } {#2#3} } + } + } +\cs_generate_variant:Nn \@@_parse_vars_elt_aux:nnn { nne } +\cs_new_protected:Npn \@@_parse_vars_elt_key:nn #1#2 + { + \keys_define:ne { template / #1 } + { \l_@@_key_name_tl #2 } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\@@_map_var_type:} +% Turn a \enquote{friendly} variable type into an \texttt{expl3} one. +% \begin{macrocode} +\cs_new:Npn \@@_map_var_type: + { + \str_case:Vn \l_@@_keytype_tl + { + { boolean } { bool } + { commalist } { clist } + { integer } { int } + { length } { dim } + { muskip } { muskip } + { real } { fp } + { skip } { skip } + { tokenlist } { tl } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_implement_choices:nn} +% \begin{macro}{\@@_implement_choices_default:} +% Implementing choices requires a second key--value loop. So after a +% little set-up, the standard parser is called. +% \begin{macrocode} +\cs_new_protected:Npn \@@_implement_choices:nn #1#2 + { + \clist_set:NV \l_@@_tmp_clist \l_@@_keytype_arg_tl + \prop_put:NVn \l_@@_vars_prop \l_@@_key_name_tl { } + \keys_define:ne { template / #1 } { \l_@@_key_name_tl .choice: } + \keyval_parse:nnn + { \@@_implement_choice_elt:n } + { \@@_implement_choice_elt:nnn {#1} } + {#2} + \prop_get:NVNT \l_@@_values_prop \l_@@_key_name_tl + \l_@@_tmp_tl + { \@@_implement_choices_default: } + \clist_if_empty:NF \l_@@_tmp_clist + { + \clist_map_inline:Nn \l_@@_tmp_clist + { \msg_error:nnn { template } { choice-not-implemented } {##1} } + } + } +% \end{macrocode} +% A sanity check for the default value, so that an error is raised +% now and not when converting to assignments. +% \begin{macrocode} +\cs_new_protected:Npn \@@_implement_choices_default: + { + \tl_set:Ne \l_@@_tmp_tl + { \l_@@_key_name_tl \c_space_tl \l_@@_tmp_tl } + \prop_if_in:NVF \l_@@_vars_prop \l_@@_tmp_tl + { + \tl_set:Ne \l_@@_tmp_tl + { \l_@@_key_name_tl \c_space_tl \l_@@_tmp_tl } + \prop_if_in:NVF \l_@@_vars_prop \l_@@_tmp_tl + { + \prop_get:NVN \l_@@_keytypes_prop \l_@@_key_name_tl + \l_@@_tmp_tl + \@@_split_keytype_arg:V \l_@@_tmp_tl + \prop_get:NVN \l_@@_values_prop \l_@@_key_name_tl + \l_@@_tmp_tl + \msg_error:nnVV { template } { unknown-default-choice } + \l_@@_key_name_tl + \l_@@_key_name_tl + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_implement_choice_elt:nnn, \@@_implement_choice_elt_aux:nnn} +% \begin{macro}{\@@_implement_choice_elt_aux:n} +% \begin{macro}{\@@_implement_choice_elt:n} +% The actual storage of the implementation of a choice is mainly about +% error checking. The code here ensures that all choices have to have +% been declared, apart from the special \texttt{unknown} choice, which +% must come last. The code for each choice is stored along with the +% key name in the variables property list. +% \begin{macrocode} +\cs_new_protected:Npn \@@_implement_choice_elt:nnn #1#2#3 + { + \clist_if_empty:NTF \l_@@_tmp_clist + { + \str_if_eq:nnTF {#2} { unknown } + { \@@_implement_choice_elt_aux:nnn {#1} {#2} {#3} } + { \@@_implement_choice_elt_aux:n {#2} } + } + { + \clist_if_in:NnTF \l_@@_tmp_clist {#2} + { + \clist_remove_all:Nn \l_@@_tmp_clist {#2} + \@@_implement_choice_elt_aux:nnn {#1} {#2} {#3} + } + { \@@_implement_choice_elt_aux:n {#2} } + } + } +\cs_new_protected:Npn \@@_implement_choice_elt_aux:n #1 + { + \prop_get:NVN \l_@@_keytypes_prop \l_@@_key_name_tl + \l_@@_tmp_tl + \@@_split_keytype_arg:V \l_@@_tmp_tl + \msg_error:nnVn { template } { unknown-choice } \l_@@_key_name_tl {#1} + } +\cs_new_protected:Npn \@@_implement_choice_elt_aux:nnn #1#2#3 + { + \keys_define:ne { template / #1 } + { \l_@@_key_name_tl / #2 .code:n = { \exp_not:n {#3} } } + \tl_set:Ne \l_@@_tmp_tl + { \l_@@_key_name_tl \c_space_tl #2 } + \prop_put:NVn \l_@@_vars_prop \l_@@_tmp_tl {#3} + } +\cs_new_protected:Npn \@@_implement_choice_elt:n #1 + { + \msg_error:nnVn { template } { choice-requires-code } + \l_@@_key_name_tl {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Editing template defaults} +% +% \begin{macro}{\@@_edit_defaults:nnn} +% Editing the template defaults means getting the values back out +% of the store, then parsing the list of new values before putting +% the updated list back into storage. +% \begin{macrocode} +\cs_new_protected:Npn \@@_edit_defaults:nnn #1#2#3 + { + \@@_if_keys_exist:nnT {#1} {#2} + { + \@@_recover_defaults:nn {#1} {#2} + \@@_parse_values:nnn {#1} {#2} {#3} + \@@_store_defaults:nn {#1} {#2} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_values:nnn} +% The routine to parse values is the same for both editing a +% template and setting up an instance. So the code here does only the +% minimum necessary for reading the values. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_values:nnn #1#2#3 + { + \@@_recover_keytypes:nn {#1} {#2} + \keyval_parse:NNn + \@@_parse_values_elt:n \@@_parse_values_elt:nn {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_values_elt:n} +% Every key needs a value, so this is just an error routine. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_values_elt:n #1 + { + \bool_set_true:N \l_@@_error_bool + \msg_error:nnn { template } { key-no-value } {#1} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_parse_values_elt:nn} +% \begin{macro}{\@@_parse_values_elt_aux:n} +% To store the value, find the keytype then call the saving function. +% These need the current key name saved as \cs{l_@@_key_name_tl}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_parse_values_elt:nn #1#2 + { + \tl_set:Ne \l_@@_key_name_tl + { \tl_trim_spaces:e { \tl_to_str:n {#1} } } + \prop_get:NVNTF \l_@@_keytypes_prop \l_@@_key_name_tl + \l_@@_tmp_tl + { \@@_parse_values_elt_aux:n {#2} } + { \msg_error:nnV { template } { unknown-key } \l_@@_key_name_tl } + } +\cs_new_protected:Npn \@@_parse_values_elt_aux:n #1 + { + \@@_split_keytype_arg:V \l_@@_tmp_tl + \use:c { @@_store_value_ \l_@@_keytype_tl :n } {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_template_set_eq:nnn} +% To copy a template, each of the lists plus the code has to be copied +% across. To keep this independent of the list storage system, it is +% all done with two-part shuffles. +% \begin{macrocode} +\cs_new_protected:Npn \@@_template_set_eq:nnn #1#2#3 + { + \@@_recover_defaults:nn {#1} {#3} + \@@_store_defaults:nn {#1} {#2} + \@@_recover_keytypes:nn {#1} {#3} + \@@_store_keytypes:nn {#1} {#2} + \@@_recover_vars:nn {#1} {#3} + \@@_store_vars:nn {#1} {#2} + \cs_if_exist:cT { \c_@@_code_root_tl #1 / #2 } + { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} } + \cs_gset_eq:cc { \c_@@_code_root_tl #1 / #2 } + { \c_@@_code_root_tl #1 / #3 } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Creating instances of templates} +% +% \begin{macro} +% { +% \@@_declare_instance:nnnn, +% \@@_declare_instance_aux:nnnn +% } +% Making an instance has two distinct parts. First, the keys given are +% parsed to transfer the values into the structured data format used +% internally. This allows the default and given values to be combined +% with no repetition. In the second step, the structured data is +% converted to pre-defined variable assignments, and these are stored +% in the function for the instance. +% \begin{macrocode} +\cs_new_protected:Npn \@@_declare_instance:nnnn #1#2#3#4 + { + \@@_execute_if_code_exist:nnT {#1} {#2} + { + \@@_recover_defaults:nn {#1} {#2} + \@@_recover_vars:nn {#1} {#2} + \@@_declare_instance_aux:nnnn {#1} {#2} {#3} {#4} + } + } +\cs_new_protected:Npn \@@_declare_instance_aux:nnnn #1#2#3#4 + { + \bool_set_false:N \l_@@_error_bool + \@@_parse_values:nnn {#1} {#2} {#4} + \bool_if:NF \l_@@_error_bool + { + \prop_put:Nnn \l_@@_values_prop { from~template } {#2} + \@@_store_values:nn {#1} {#3} + \@@_convert_to_assignments: + \cs_if_exist:cT { \c_@@_instances_root_tl #1 / #3 } + { \msg_info:nnnn { template } { declare-instance } {#3} {#1} } + \cs_set_protected:cpe { \c_@@_instances_root_tl #1 / #3 } + { + \exp_not:N \@@_assignments_push:n + { \exp_not:V \l_@@_assignments_tl } + \exp_not:c { \c_@@_code_root_tl #1 / #2 } + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_instance_set_eq:nnn} +% Copy--paste an instance. +% \begin{macrocode} +\cs_new_protected:Npn \@@_instance_set_eq:nnn #1#2#3 + { + \@@_if_instance_exist:nnTF {#1} {#3} + { + \@@_recover_values:nn {#1} {#3} + \@@_store_values:nn {#1} {#2} + \cs_if_exist:cT { \c_@@_instances_root_tl #1 / #2 } + { \msg_info:nnnn { template } { declare-instance } {#2} {#1} } + \cs_set_eq:cc { \c_@@_instances_root_tl #1 / #2 } + { \c_@@_instances_root_tl #1 / #3 } + } + { \msg_error:nnnn { template } { unknown-instance } {#1} {#3} } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_edit_instance:nnn} +% \begin{macro} +% {\@@_edit_instance_aux:nnnnn, \@@_edit_instance_aux:nVnnn} +% Editing an instance is almost identical to declaring one. The only +% variation is the source of the values to use. When editing, they are +% recovered from the previous instance run. +% \begin{macrocode} +\cs_new_protected:Npn \@@_edit_instance:nnn #1#2#3 + { + \@@_if_instance_exist:nnTF {#1} {#2} + { + \@@_recover_values:nn {#1} {#2} + \prop_get:NnN \l_@@_values_prop { from~template } + \l_@@_tmp_tl + \@@_edit_instance_aux:nVnn + {#1} \l_@@_tmp_tl {#2} {#3} + } + { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} } + } +\cs_new_protected:Npn \@@_edit_instance_aux:nnnn #1#2#3#4 + { + \@@_recover_vars:nn {#1} {#2} + \@@_declare_instance_aux:nnnn {#1} {#2} {#3} {#4} + } +\cs_generate_variant:Nn \@@_edit_instance_aux:nnnn { nV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_convert_to_assignments:} +% \begin{macro}{\@@_convert_to_assignments_aux:n} +% \begin{macro} +% {\@@_convert_to_assignments_aux:nn, \@@_convert_to_assignments_aux:nV} +% The idea on converting to a set of assignments is to loop over each +% key, so that the loop order follows the declaration order of the keys. +% This is done using a sequence as property lists are not +% \enquote{ordered}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_convert_to_assignments: + { + \tl_clear:N \l_@@_assignments_tl + \seq_map_function:NN \l_@@_key_order_seq + \@@_convert_to_assignments_aux:n + } +\cs_new_protected:Npn \@@_convert_to_assignments_aux:n #1 + { + \prop_get:NnN \l_@@_keytypes_prop {#1} \l_@@_tmp_tl + \@@_convert_to_assignments_aux:nV {#1} \l_@@_tmp_tl + } +% \end{macrocode} +% The second auxiliary function actually does the work. The +% arguments here are the key name (|#1|) and the keytype (|#2|). +% From those, the value to assign and the name of the appropriate +% variable are recovered. A bit of work is then needed to sort out +% keytypes with arguments (for example instances), and to look for +% global assignments. Once that is done, a hand-off can be made to the +% handler for the relevant keytype. +% \begin{macrocode} +\cs_new_protected:Npn \@@_convert_to_assignments_aux:nn #1#2 + { + \prop_get:NnNT \l_@@_values_prop {#1} \l_@@_value_tl + { + \prop_get:NnNTF \l_@@_vars_prop {#1} \l_@@_var_tl + { + \@@_split_keytype_arg:n {#2} + \str_if_eq:VnF \l_@@_keytype_tl { choice } + { + \str_if_eq:VnF \l_@@_keytype_tl { code } + { \@@_find_global: } + } + \tl_set:Nn \l_@@_key_name_tl {#1} + \cs_if_exist_use:cF { @@_assign_ \l_@@_keytype_tl : } + { \@@_assign_variable: } + } + { \msg_error:nnn { template } { unknown-attribute } {#1} } + } + } +\cs_generate_variant:Nn \@@_convert_to_assignments_aux:nn { nV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_find_global:} +% \begin{macro}{\@@_find_global_aux:w} +% Global assignments should have the phrase |global| at the front. +% This is pretty easy to find: no other error checking, though. +% \begin{macrocode} +\cs_new_protected:Npn \@@_find_global: + { + \bool_set_false:N \l_@@_global_bool + \tl_if_in:onT \l_@@_var_tl { global } + { + \exp_after:wN \@@_find_global_aux:w \l_@@_var_tl \s_@@_stop + } + } +\cs_new_protected:Npn \@@_find_global_aux:w #1 global #2 \s_@@_stop + { + \tl_set:Nn \l_@@_var_tl {#2} + \bool_set_true:N \l_@@_global_bool + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Using templates directly} +% +% \begin{macro}{\@@_use_template:nnn} +% Directly use a template with a particular parameter setting. +% This is also picked up if used in a nested fashion inside a parameter +% list. The idea is essentially the same as creating an instance, +% just with no saving of the result. +% \begin{macrocode} +\cs_new_protected:Npn \@@_use_template:nnn #1#2#3 + { + \@@_execute_if_code_exist:nnT {#1} {#2} + { + \@@_recover_defaults:nn {#1} {#2} + \@@_recover_vars:nn {#1} {#2} + \@@_parse_values:nnn {#1} {#2} {#3} + \@@_convert_to_assignments: + \use:c { \c_@@_code_root_tl #1 / #2 } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Assigning values to variables} +% +% \begin{macro}{\@@_assign_boolean:} +% \begin{macro}{\@@_assign_boolean_aux:n} +% Setting a Boolean value is slightly different to everything else +% as the value can be used to work out which \texttt{set} function to +% call. As long as there is no need to recover things from another +% variable, everything is pretty easy. If there is, then we need to allow +% for the fact that the recovered value here will \emph{not} be expandable, +% so needs to be converted to something that is. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assign_boolean: + { + \bool_if:NTF \l_@@_global_bool + { \@@_assign_boolean_aux:n { bool_gset } } + { \@@_assign_boolean_aux:n { bool_set } } + } +\cs_new_protected:Npn \@@_assign_boolean_aux:n #1 + { + \@@_if_key_value:VTF \l_@@_value_tl + { + \@@_key_to_value: + \tl_put_right:Ne \l_@@_assignments_tl + { + \exp_not:c { #1 _eq:NN } + \exp_not:V \l_@@_var_tl + \exp_not:V \l_@@_value_tl + } + } + { + \tl_put_right:Ne \l_@@_assignments_tl + { + \exp_not:c { #1 _ \l_@@_value_tl :N } + \exp_not:V \l_@@_var_tl + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_assign_choice:} +% \begin{macro} +% {\@@_assign_choice_aux:nF, \@@_assign_choice_aux:eF} +% The idea here is to find either the choice as-given or else the +% special |unknown| choice, and to copy the appropriate code across. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assign_choice: + { + \@@_assign_choice_aux:eF + { \l_@@_key_name_tl \c_space_tl \l_@@_value_tl } + { + \@@_assign_choice_aux:eF + { \l_@@_key_name_tl \c_space_tl unknown } + { + \prop_get:NVN \l_@@_keytypes_prop \l_@@_key_name_tl + \l_@@_tmp_tl + \@@_split_keytype_arg:V \l_@@_tmp_tl + \msg_error:nnVV { template } { unknown-choice } + \l_@@_key_name_tl + \l_@@_value_tl + } + } + } +\cs_new_protected:Npn \@@_assign_choice_aux:nF #1 + { + \prop_get:NnNTF \l_@@_vars_prop {#1} \l_@@_tmp_tl + { \tl_put_right:NV \l_@@_assignments_tl \l_@@_tmp_tl } + } +\cs_generate_variant:Nn \@@_assign_choice_aux:nF { e } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_assign_function:} +% \begin{macro}{\@@_assign_function_aux:N} +% This looks a bit messy but is only actually one function. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assign_function: + { + \bool_if:NTF \l_@@_global_bool + { \@@_assign_function_aux:N \cs_gset:Npn } + { \@@_assign_function_aux:N \cs_set:Npn } + } +\cs_new_protected:Npn \@@_assign_function_aux:N #1 + { + \tl_put_right:Ne \l_@@_assignments_tl + { + \cs_generate_from_arg_count:NNnn + \exp_not:V \l_@@_var_tl + \exp_not:N #1 + { \exp_not:V \l_@@_keytype_arg_tl } + { \exp_not:V \l_@@_value_tl } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_assign_instance:} +% \begin{macro}{\@@_assign_instance_aux:N} +% Using an instance means adding the appropriate function creation to +% the tl. No checks are made at this stage, so if the instance is +% not valid then errors will arise later. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assign_instance: + { + \bool_if:NTF \l_@@_global_bool + { \@@_assign_instance_aux:N \cs_gset_protected:Npn } + { \@@_assign_instance_aux:N \cs_set_protected:Npn } + } +\cs_new_protected:Npn \@@_assign_instance_aux:N #1 + { + \tl_put_right:Ne \l_@@_assignments_tl + { + \exp_not:N #1 \exp_not:V \l_@@_var_tl + { + \@@_use_instance:nn + { \exp_not:V \l_@@_keytype_arg_tl } + { \exp_not:V \l_@@_value_tl } + } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_assign_variable:} +% \begin{macro}{\@@_assign_variable:N, \@@_assign_variable:c} +% A general-purpose function for all of the other assignments. +% As long as the value is not coming from another variable, the stored +% value is simply transferred for output. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assign_variable: + { + \@@_assign_variable:c + { + \@@_map_var_type: _ + \bool_if:NT \l_@@_global_bool { g } set:Nn + } + } +\cs_new_protected:Npn \@@_assign_variable:N #1 + { + \@@_if_key_value:VT \l_@@_value_tl + { \@@_key_to_value: } + \tl_put_right:Ne \l_@@_assignments_tl + { + #1 \exp_not:V \l_@@_var_tl + { \exp_not:V \l_@@_value_tl } + } + } +\cs_generate_variant:Nn \@@_assign_variable:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_key_to_value:} +% \begin{macro}{\@@_key_to_value_auxi:w} +% \begin{macro}{\@@_key_to_value_auxii:w} +% The idea here is to recover the attribute value of another key. To +% do that, the marker is removed and a look up takes place. If this +% is successful, then the name of the variable of the attribute is +% returned. This assumes that the value will be used in context where +% it will be converted to a value, for example when setting a number. +% There is also a need to check in case the copied value happens to be +% \texttt{global}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_key_to_value: + { \exp_after:wN \@@_key_to_value_auxi:w \l_@@_value_tl } +\cs_new_protected:Npn \@@_key_to_value_auxi:w \KeyValue #1 + { + \tl_set:Ne \l_@@_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } } + \prop_get:NVNTF \l_@@_vars_prop \l_@@_tmp_tl + \l_@@_value_tl + { + \exp_after:wN \@@_key_to_value_auxii:w \l_@@_value_tl + \s_@@_mark global \q_@@_nil \s_@@_stop + } + { \msg_error:nnV { template } { unknown-attribute } \l_@@_tmp_tl } + } +\cs_new_protected:Npn \@@_key_to_value_auxii:w #1 global #2#3 \s_@@_stop + { + \@@_quark_if_nil:NF #2 + { \tl_set:Nn \l_@@_value_tl {#2} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Using instances} +% +% \begin{macro}{\@@_use_instance:nn} +% \begin{macro}{\@@_use_instance_aux:nNnnn} +% \begin{macro}{\@@_use_instance_aux:nn} +% Using an instance is just a question of finding the appropriate function. +% If nothing is found, an error is raised. One complication is that +% if the first token of argument |#2| is \cs{UseTemplate} then that +% is also valid. There is an error-test to make sure that the +% types agree, and if so the template is used directly. +% \begin{macrocode} +\cs_new_protected:Npn \@@_use_instance:nn #1#2 + { + \@@_if_use_template:nTF {#2} + { \@@_use_instance_aux:nNnnn {#1} #2 } + { \@@_use_instance_aux:nn {#1} {#2} } + } +\cs_new_protected:Npn \@@_use_instance_aux:nNnnn #1#2#3#4#5 + { + \str_if_eq:nnTF {#1} {#3} + { \@@_use_template:nnn {#3} {#4} {#5} } + { \msg_error:nnnn { template } { type-mismatch } {#1} {#3} } +} +\cs_new_protected:Npn \@@_use_instance_aux:nn #1#2 + { + \@@_if_instance_exist:nnTF {#1} {#2} + { \use:c { \c_@@_instances_root_tl #1 / #2 } } + { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +%\subsection{Assignment manipulation} +% +% A few functions to transfer assignments about, as this is needed by +% \cs{AssignTemplateKeys}. +% +% \begin{macro}{\@@_assignments_pop:} +% To actually use the assignments. +% \begin{macrocode} +\cs_new:Npn \@@_assignments_pop: { \l_@@_assignments_tl } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_assignments_push:n} +% Here, the assignments are stored for later use. +% \begin{macrocode} +\cs_new_protected:Npn \@@_assignments_push:n #1 + { \tl_set:Nn \l_@@_assignments_tl {#1} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Showing templates and instances} +% +% \begin{macro}{\@@_show_code:nn} +% Showing the code for a template is just a translation of +% \cs{cs_show:c}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_code:nn #1#2 + { \cs_show:c { \c_@@_code_root_tl #1 / #2 } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \@@_show_defaults:nn, +% \@@_show_keytypes:nn, +% \@@_show_vars:nn +% } +% \begin{macro}{\@@_show:Nnnn} +% A modified version of the property-list printing code, such that +% the output refers to templates and instances rather than to the +% underlying structures. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_defaults:nn #1#2 + { + \@@_if_keys_exist:nnT {#1} {#2} + { + \@@_recover_defaults:nn {#1} {#2} + \@@_show:Nnnn \l_@@_values_prop + {#1} {#2} { default~values } + } + } +\cs_new_protected:Npn \@@_show_keytypes:nn #1#2 + { + \@@_if_keys_exist:nnT {#1} {#2} + { + \@@_recover_keytypes:nn {#1} {#2} + \@@_show:Nnnn \l_@@_keytypes_prop + {#1} {#2} { interface } + } + } +\cs_new_protected:Npn \@@_show_vars:nn #1#2 + { + \@@_execute_if_code_exist:nnT {#1} {#2} + { + \@@_recover_vars:nn {#1} {#2} + \@@_show:Nnnn \l_@@_vars_prop + {#1} {#2} { variable~mapping } + } + } +\cs_new_protected:Npn \@@_show:Nnnn #1#2#3#4 + { + \msg_show:nneeee { template } { show-attribute } + { \tl_to_str:n {#2} } + { \tl_to_str:n {#3} } + { \tl_to_str:n {#4} } + { \prop_map_function:NN #1 \msg_show_item_unbraced:nn } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_show_values:nn} +% Instance values are a little more complex, as is the template to consider. +% \begin{macrocode} +\cs_new_protected:Npn \@@_show_values:nn #1#2 + { + \@@_if_instance_exist:nnT {#1} {#2} + { + \@@_recover_values:nn {#1} {#2} + \msg_show:nneee { template } { show-values } + { \tl_to_str:n {#1} } + { \tl_to_str:n {#2} } + { + \prop_map_function:NN \l_@@_values_prop + \msg_show_item_unbraced:nn + } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% The text for error messages: short and long text for all of them. +% \begin{macrocode} +\msg_new:nnnn { template } { argument-number-mismatch } + { Template~type~'#1'~takes~#2~argument(s). } + { + Templates~of~type~'#1'~require~#2~argument(s).\\ + You~have~tried~to~make~a~template~for~'#1'~ + with~#3~argument(s),~which~is~not~possible:~ + the~number~of~arguments~must~agree. + } +\msg_new:nnnn { template } { bad-number-of-arguments } + { Bad~number~of~arguments~for~template~type~'#1'. } + { + A~template~may~accept~between~0~and~9~arguments.\\ + You~asked~to~use~#2~arguments:~this~is~not~supported. + } +\msg_new:nnnn { template } { bad-variable } + { Incorrect~variable~description~'#1'. } + { + The~argument~'#1'~is~not~of~the~form \\ + ~~''\\ + ~or~\\ + ~~'global~'.\\ + It~must~be~given~in~one~of~these~formats~to~be~used~in~a~template. + } +\msg_new:nnnn { template } { choice-not-implemented } + { The~choice~'#1'~has~no~implementation. } + { + Each~choice~listed~in~the~interface~for~a~template~must~ + have~an~implementation. + } +\msg_new:nnnn { template } { choice-no-code } + { The~choice~'#1'~requires~implementation~details. } + { + When~creating~template~code~using~\DeclareTemplateCode,~ + each~choice~name~must~have~an~associated~implementation.\\ + This~should~be~given~after~a~'='~sign:~LaTeX~did~not~find~one. + } +\msg_new:nnnn { template } { choice-requires-code } + { The~choice~'#2'~for~key~'#1'~requires~an~implementation. } + { + You~should~have~put:\\ + \ \ #1~:~choice~{~#2 = ~} \\ + but~LaTeX~did~not~find~any~. + } +\msg_new:nnnn { template } { duplicate-key-interface } + { Key~'#1'~appears~twice~in~interface~definition~\msg_line_context:. } + { + Each~key~can~only~have~one~interface~declared~in~a~template.\\ + LaTeX~found~two~interfaces~for~'#1'. + } +\msg_new:nnnn { template } { keytype-requires-argument } + { The~key~type~'#1'~requires~an~argument~\msg_line_context:. } + { + You~should~have~put:\\ + \ \ ~:~#1~{~~} \\ + but~LaTeX~did~not~find~an~. + } +\msg_new:nnnn { template } { invalid-keytype } + { The~key~'#1'~is~missing~a~key-type~\msg_line_context:. } + { + Each~key~in~a~template~requires~a~key-type,~given~in~the~form:\\ + \ \ ~:~\\ + LaTeX~could~not~find~a~~in~your~input. + } +\msg_new:nnnn { template } { key-no-value } + { The~key~'#1'~has~no~value~\msg_line_context:. } + { + When~creating~an~instance~of~a~template~ + every~key~listed~must~include~a~value:\\ + \ \ ~=~ + } +\msg_new:nnnn { template } { key-no-variable } + { The~key~'#1'~requires~implementation~details~\msg_line_context:. } + { + When~creating~template~code~using~\DeclareTemplateCode,~ + each~key~name~must~have~an~associated~implementation.\\ + This~should~be~given~after~a~'='~sign:~LaTeX~did~not~find~one. + } +\msg_new:nnnn { template } { key-not-implemented } + { Key~'#1'~has~no~implementation~\msg_line_context:. } + { + The~definition~of~key~implementations~for~template~'#2'~ + of~template~type~'#3'~does~not~include~any~details~for~key~'#1'.\\ + The~key~was~declared~in~the~interface~definition,~ + and~so~an~implementation~is~required. + } +\msg_new:nnnn { template } { missing-keytype } + { The~key~'#1'~is~missing~a~key-type~\msg_line_context:. } + { + Key~interface~definitions~should~be~of~the~form\\ + \ \ #1~:~\\ + but~LaTeX~could~not~find~a~. + } +\msg_new:nnnn { template } { no-template-code } + { + The~template~'#2'~of~type~'#1'~is~unknown~ + or~has~no~implementation. + } + { + There~is~no~code~available~for~the~template~name~given.\\ + This~should~be~given~using~\DeclareTemplateCode. + } +\msg_new:nnnn { template } { type-already-defined } + { Template~type~'#1'~already~defined. } + { + You~have~used~\NewTemplateType~ + with~a~template~type~that~has~already~been~defined. + } +\msg_new:nnnn { template } { type-mismatch } + { Template~types~'#1'~and~'#2'~do~not~agree. } + { + You~are~trying~to~use~a~template~directly~with~\UseInstance + (or~a~similar~function),~but~the~template~types~do~not~match. + } +\msg_new:nnnn { template } { unknown-attribute } + { The~template~attribute~'#1'~is~unknown. } + { + There~is~a~definition~in~the~current~template~reading\\ + \ \ \token_to_str:N \KeyValue {~#1~} \\ + but~there~is~no~key~called~'#1'. + } +\msg_new:nnnn { template } { unknown-choice } + { The~choice~'#2'~was~not~declared~for~key~'#1'. } + { + The~key~'#1'~takes~a~fixed~list~of~choices~ + and~this~list~does~not~include~'#2'. + } +\msg_new:nnnn { template } { unknown-default-choice } + { The~default~choice~'#2'~was~not~declared~for~key~'#1'. } + { + The~key~'#1'~takes~a~fixed~list~of~choices~ + and~this~list~does~not~include~'#2'. + } +\msg_new:nnnn { template } { unknown-instance } + { The~instance~'#2'~of~type~'#1'~is~unknown. } + { + You~have~asked~to~use~an~instance~'#2',~ + but~this~has~not~been~created. + } +\msg_new:nnnn { template } { unknown-key } + { Unknown~template~key~'#1'. } + { + The~key~'#1'~was~not~declared~in~the~interface~ + for~the~current~template. + } +\msg_new:nnnn { template } { unknown-keytype } + { The~key-type~'#1'~is~unknown. } + { + Valid~key-types~are:\\ + -~boolean;\\ + -~choice;\\ + -~commalist;\\ + -~function;\\ + -~instance;\\ + -~integer;\\ + -~length;\\ + -~muskip;\\ + -~real;\\ + -~skip;\\ + -~tokenlist. + } +\msg_new:nnnn { template } { unknown-type } + { The~template~type~'#1'~is~unknown. } + { + A~template~type~needs~to~be~defined~with~\NewTemplateType + prior~to~using~it. + } +\msg_new:nnnn { template } { unknown-template } + { The~template~'#2'~of~type~'#1'~is~unknown. } + { + No~interface~has~been~declared~for~a~template~ + '#2'~of~template~type~'#1'. + } +% \end{macrocode} +% +% Information messages only have text: more text should not be needed. +% \begin{macrocode} +\msg_new:nnn { template } { declare-instance } + { Declaring~instance~~'#1'~of~type~#2~\msg_line_context:. } +\msg_new:nnn { template } { declare-template-code } + { Declaring~code~for~template~'#2'~of~template~type~'#1'~\msg_line_context:. } +\msg_new:nnn { template } { declare-template-interface } + { + Declaring~interface~for~template~'#2'~of~template~type~'#1'~ + \msg_line_context:. + } +\msg_new:nnn { template } { declare-type } + { Declaring~template~type~'#1'~taking~#2~argument(s)~\msg_line_context:. } +\msg_new:nnn { template } { show-attribute } + { + The~template~'#2'~of~type~'#1'~has~ + \tl_if_empty:nTF {#4} { no~#3. } { #3 : #4 } + } +\msg_new:nnn { template } { show-values } + { + The~instance~'#2'~of~type~'#1'~has~ + \tl_if_empty:nTF {#3} { no~values. } { values: #3 } + } +% \end{macrocode} +% +% Also add \pkg{template} to the \pkg{LaTeX} messages. +% \begin{macrocode} +\prop_gput:Nnn \g_msg_module_type_prop { template } { LaTeX } +% \end{macrocode} +% +% \subsection{User functions} +% +% \begin{macro}{\NewTemplateType} +% \begin{macro}{\DeclareTemplateInterface} +% \begin{macro}{\DeclareTemplateCode} +% \begin{macro}{\DeclareTemplateCopy} +% \begin{macro}{\EditTemplateDefaults} +% \begin{macro}{\UseTemplate} +% \begin{macro}{\DeclareInstance} +% \begin{macro}{\DeclareInstanceCopy} +% \begin{macro}{\EditInstance} +% \begin{macro}{\UseInstance} +% All simple translations. +% \begin{macrocode} +\cs_new_protected:Npn \NewTemplateType #1#2 + { \@@_define_type:nn {#1} {#2} } +\cs_new_protected:Npn \DeclareTemplateInterface #1#2#3#4 + { \@@_declare_template_keys:nnnn {#1} {#2} {#3} {#4} } +\cs_new_protected:Npn \DeclareTemplateCode #1#2#3#4#5 + { \@@_declare_template_code:nnnnn {#1} {#2} {#3} {#4} {#5} } +\cs_new_protected:Npn \DeclareTemplateCopy #1#2#3 + { \@@_template_set_eq:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \EditTemplateDefaults #1#2#3 + { \@@_edit_defaults:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \UseTemplate #1#2#3 + { \@@_use_template:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \DeclareInstance #1#2#3#4 + { \@@_declare_instance:nnnn {#1} {#3} {#2} {#4} } +\cs_new_protected:Npn \DeclareInstanceCopy #1#2#3 + { \@@_instance_set_eq:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \EditInstance #1#2#3 + { \@@_edit_instance:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \UseInstance #1#2 + { \@@_use_instance:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ShowTemplateCode} +% \begin{macro}{\ShowTemplateDefaults} +% \begin{macro}{\ShowTemplateInterface} +% \begin{macro}{\ShowTemplateVariables} +% \begin{macro}{\ShowInstanceValues} +% The show functions are again just translation. +% \begin{macrocode} +\cs_new_protected:Npn \ShowTemplateCode #1#2 + { \@@_show_code:nn {#1} {#2} } +\cs_new_protected:Npn \ShowTemplateDefaults #1#2 + { \@@_show_defaults:nn {#1} {#2} } +\cs_new_protected:Npn \ShowTemplateInterface #1#2 + { \@@_show_keytypes:nn {#1} {#2} } +\cs_new_protected:Npn \ShowTemplateVariables #1#2 + { \@@_show_vars:nn {#1} {#2} } +\cs_new_protected:Npn \ShowInstanceValues #1#2 + { \@@_show_values:nn {#1} {#2} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\IfInstanceExistsT, \IfInstanceExistsF, \IfInstanceExistsTF} +% \changes{2024-02-15}{v1.0b}{New macros} +% \changes{2024-04-17}{v1.0c}{Use plural names} +% More direct translation. +% \begin{macrocode} +\cs_new:Npn \IfInstanceExistsTF #1#2 + { \@@_if_instance_exist:nnTF {#1} {#2} } +\cs_new:Npn \IfInstanceExistsT #1#2 + { \@@_if_instance_exist:nnT {#1} {#2} } +\cs_new:Npn \IfInstanceExistsF #1#2 + { \@@_if_instance_exist:nnF {#1} {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KeyValue} +% Simply dump the argument when executed: this should not happen. +% \begin{macrocode} +\cs_new_protected:Npn \KeyValue #1 {#1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\AssignTemplateKeys} +% A short call to use a token register by proxy. +% \begin{macrocode} +\cs_new_protected:Npn \AssignTemplateKeys { \@@_assignments_pop: } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\SetTemplateKeys} +% A friendly wrapper +% \begin{macrocode} +\cs_new_protected:Npn \SetTemplateKeys #1#2#3 + { \keys_set_known:nnN { template / #1 / #2 } {#3} \l_@@_tmp_clist } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%\IncludeInRelease{0000/00/00}{lttemplates}% +% {Prototype~document~commands}% +% +%\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% We need to stop DocStrip treating |@@| in a special way at this point. +% \begin{macrocode} +%<@@=> +% \end{macrocode} +% +% \Finale \ No newline at end of file diff --git a/Master/texmf-dist/source/latex/base/lttextcomp.dtx b/Master/texmf-dist/source/latex/base/lttextcomp.dtx index 5de3797f79b..7f247747d6a 100644 --- a/Master/texmf-dist/source/latex/base/lttextcomp.dtx +++ b/Master/texmf-dist/source/latex/base/lttextcomp.dtx @@ -37,7 +37,7 @@ % % \ProvidesFile{lttextcomp.dtx} - [2022/08/07 v1.0g LaTeX Kernel (text companion symbols)] + [2024/04/24 v1.1c LaTeX Kernel (text companion symbols)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -163,11 +163,12 @@ % % \begin{macro}{\DeclareEncodingSubset} % -% The declaration takes 3 mandatory arguments: an \emph{encoding} +% The declaration takes 3 mandatory arguments: an \emph{encoding} % for which a subsetting is wanted (currently always \texttt{TS1}, % and most likely forever), the \emph{font family} for which we -% 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. +% declare the subset and finally the \emph{subset} number, with a value between +% \texttt{0} (all of the encoding is supported) and \texttt{9} (many +% glyphs are missing). % % For \texttt{TS1} the numbers have been chosen in a way that most % fonts can be fairly correctly categorized, but the default @@ -439,7 +440,7 @@ % \end{macrocode} % % And here are the other \texttt{TS1} glyphs that are implemented -% by every font (or nearly every---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 some fonts. % \begin{macrocode} @@ -950,6 +951,8 @@ % This first block contains the fonts that have been already % supported by the \texttt{textcomp} package way back, i.e., the % font families that have \TeX{} support since the mid-nineties. +% \changes{v1.1a}{2024/01/27}{Adjusted/corrected TS1 sub-encoding +% declarations for various families (gh/1257)} % \begin{macrocode} \DeclareEncodingSubset{TS1}{ccr} {0} \DeclareEncodingSubset{TS1}{cmbr} {0} @@ -981,16 +984,28 @@ \DeclareEncodingSubset{TS1}{lmss} {1} \DeclareEncodingSubset{TS1}{lmssq} {1} \DeclareEncodingSubset{TS1}{lmvtt} {1} -\DeclareEncodingSubset{TS1}{lmtt} {1} % missing TM, SM and - % pertenthousand for some reason +% \end{macrocode} +% The lmtt family is missing TM, SM, and perthousand for some +% reason, so the first safe sub-encoding would be 2, but that is +% then missing out a huge number of glyphs that are available, so +% we claim it is sub-encoding 1 even if this can lead to missing glyphs. +% \begin{macrocode} +\DeclareEncodingSubset{TS1}{lmtt} {1} % missing TM, SM and pertenthousand % \end{macrocode} % +% The next three families have been removed from TeX Live, but we +% keep the definitions % \begin{macrocode} \DeclareEncodingSubset{TS1}{ptmx} {2} \DeclareEncodingSubset{TS1}{ptmj} {2} \DeclareEncodingSubset{TS1}{ul8} {2} % \end{macrocode} % +% The next set are the early PostScript font implementations, these +% days there are better alternatives, but \ldots. Note that, their +% virtual fonts contain a lot of ``tofu'' in form of black squares, +% thus they don't even give a missing character warning if you +% select such a glyph. This is why they are set as sub-encoding 5. % \begin{macrocode} \DeclareEncodingSubset{TS1}{bch} {5} % tofu for blank, ohm \DeclareEncodingSubset{TS1}{futj}{5} % tofu for blank, interrobang/down, ohm @@ -1009,12 +1024,11 @@ \DeclareEncodingSubset{TS1}{ul9} {5} % tofu for blank, interrobang/down, ohm % \end{macrocode} % +% The next set suffers from the same problem and they contain even +% fewer real glyphs. % \begin{macrocode} \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) @@ -1024,6 +1038,7 @@ % \begin{macrocode} \DeclareEncodingSubset{TS1}{zi4} {9} % \end{macrocode} +% % LucidaBright (sold through TUG) probably not quite correct, I % guess as I have the older fonts \ldots % \begin{macrocode} @@ -1041,44 +1056,72 @@ % Below are the newer fonts that have support files for % \LaTeX{}. With very few exceptions the classifications are done % so that all characters are correctly produced (either being -% available in the font or substituted. +% available in the font or substituted). % % There are a few fonts that contain ``tofu'' squares in places % (instead of a real glyph) and in a few cases some really seldom % needed chars are unavailable, i.e., produce missing glyphs (to % avoid that a large number of available chars are unnecessarily -% substituted. +% substituted). % +% Encoding declarations for these font families shouldn't really be +% in the kernel, but part of the \texttt{.fd} files for the +% family. When we introduced the concept in 2021 we had some hope +% that this would happen over time and that we could take the +% declarations out---after all it is nearly impossible to maintain +% it correctly in the kernel, given that fonts may get new glyphs +% added (happened for several of them in the recent year) which is +% something we wouldn't notice. However, so far this hasn't +% happened, so in 2024, I went through the current set and adjusted +% the declarations in several places. +% +% Next four are wrong and still need adjustment: % \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}{tli} {1} % with lots of tofu inside % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{tli} {1} % with lots of tofu inside +\DeclareEncodingSubset{TS1}{fbb-*} {2} % missing centoldstyle % \end{macrocode} % +% % \begin{macrocode} \DeclareEncodingSubset{TS1}{Alegreya-*} {2} \DeclareEncodingSubset{TS1}{AlegreyaSans-*} {2} +\DeclareEncodingSubset{TS1}{BaskervilleF-*} {2} \DeclareEncodingSubset{TS1}{DejaVuSans-TLF} {2} \DeclareEncodingSubset{TS1}{DejaVuSansCondensed-TLF} {2} +% \end{macrocode} +% Next one is missing \cs{textfractionsolidus} but is otherwise +% completely sub-encoding 2 so we use that sub-encoding. +% \begin{macrocode} \DeclareEncodingSubset{TS1}{DejaVuSansMono-TLF} {2} +% \end{macrocode} +% +% \begin{macrocode} \DeclareEncodingSubset{TS1}{EBGaramond-*} {2} +\DeclareEncodingSubset{TS1}{Merriwthr-OsF} {2} +\DeclareEncodingSubset{TS1}{MerriwthrSans-OsF} {2} +\DeclareEncodingSubset{TS1}{Montserrat-*} {2} +\DeclareEncodingSubset{TS1}{MontserratAlternates-*} {2} +\DeclareEncodingSubset{TS1}{NotoSansMono-TLF} {2} +\DeclareEncodingSubset{TS1}{NotoSansMono-TOsF} {2} \DeclareEncodingSubset{TS1}{Tempora-TLF} {2} \DeclareEncodingSubset{TS1}{Tempora-TOsF} {2} +\DeclareEncodingSubset{TS1}{XCharter-TLF} {2} +\DeclareEncodingSubset{TS1}{XCharter-TOsF} {2} +\DeclareEncodingSubset{TS1}{erewhon-*} {2} % \end{macrocode} % % \begin{macrocode} \DeclareEncodingSubset{TS1}{Arimo-TLF} {3} -\DeclareEncodingSubset{TS1}{Carlito-*} {3} -\DeclareEncodingSubset{TS1}{FiraSans-*} {3} +\DeclareEncodingSubset{TS1}{Crlt-*} {3} +\DeclareEncodingSubset{TS1}{IBMPlexMono-TLF} {3} \DeclareEncodingSubset{TS1}{IBMPlexSans-TLF} {3} -\DeclareEncodingSubset{TS1}{Merriweather-OsF} {3} -\DeclareEncodingSubset{TS1}{Montserrat-*} {3} -\DeclareEncodingSubset{TS1}{MontserratAlternates-*} {3} +\DeclareEncodingSubset{TS1}{IBMPlexSerif-TLF} {3} \DeclareEncodingSubset{TS1}{SourceCodePro-TLF} {3} \DeclareEncodingSubset{TS1}{SourceCodePro-TOsF} {3} \DeclareEncodingSubset{TS1}{SourceSansPro-*} {3} @@ -1096,6 +1139,7 @@ \DeclareEncodingSubset{TS1}{CrimsonPro-*} {4} \DeclareEncodingSubset{TS1}{FiraMono-TLF} {4} \DeclareEncodingSubset{TS1}{FiraMono-TOsF} {4} +\DeclareEncodingSubset{TS1}{FiraSans-*} {4} \DeclareEncodingSubset{TS1}{Go-TLF} {4} \DeclareEncodingSubset{TS1}{GoMono-TLF} {4} \DeclareEncodingSubset{TS1}{InriaSans-*} {4} @@ -1108,7 +1152,6 @@ \DeclareEncodingSubset{TS1}{LinguisticsPro-OsF} {4} \DeclareEncodingSubset{TS1}{LinuxBiolinumT-*} {4} \DeclareEncodingSubset{TS1}{LinuxLibertineT-*} {4} -\DeclareEncodingSubset{TS1}{MerriweatherSans-OsF} {4} \DeclareEncodingSubset{TS1}{MintSpirit-*} {4} \DeclareEncodingSubset{TS1}{MintSpiritNoTwo-*} {4} \DeclareEncodingSubset{TS1}{PTMono-TLF} {4} @@ -1128,66 +1171,64 @@ % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{Almendra-OsF} {5} +\DeclareEncodingSubset{TS1}{Almndr-OsF} {5} \DeclareEncodingSubset{TS1}{Baskervaldx-*} {5} -\DeclareEncodingSubset{TS1}{BaskervilleF-*} {5} -\DeclareEncodingSubset{TS1}{Bitter-TLF} {5} +\DeclareEncodingSubset{TS1}{Bttr-TLF} {5} \DeclareEncodingSubset{TS1}{Cinzel-LF} {5} \DeclareEncodingSubset{TS1}{CinzelDecorative-LF} {5} +\DeclareEncodingSubset{TS1}{Cochineal-*} {5} \DeclareEncodingSubset{TS1}{DejaVuSerif-TLF} {5} \DeclareEncodingSubset{TS1}{DejaVuSerifCondensed-TLF} {5} \DeclareEncodingSubset{TS1}{GilliusADF-LF} {5} \DeclareEncodingSubset{TS1}{GilliusADFCond-LF} {5} \DeclareEncodingSubset{TS1}{GilliusADFNoTwo-LF} {5} \DeclareEncodingSubset{TS1}{GilliusADFNoTwoCond-LF} {5} -\DeclareEncodingSubset{TS1}{LobsterTwo-LF} {5} \DeclareEncodingSubset{TS1}{OldStandard-TLF} {5} -\DeclareEncodingSubset{TS1}{PlayfairDisplay-TLF} {5} -\DeclareEncodingSubset{TS1}{PlayfairDisplay-TOsF} {5} +\DeclareEncodingSubset{TS1}{PlyfrDisplay-TLF} {5} +\DeclareEncodingSubset{TS1}{PlyfrDisplay-TOsF} {5} \DeclareEncodingSubset{TS1}{TheanoDidot-TLF} {5} \DeclareEncodingSubset{TS1}{TheanoDidot-TOsF} {5} \DeclareEncodingSubset{TS1}{TheanoModern-TLF} {5} \DeclareEncodingSubset{TS1}{TheanoModern-TOsF} {5} \DeclareEncodingSubset{TS1}{TheanoOldStyle-TLF} {5} \DeclareEncodingSubset{TS1}{TheanoOldStyle-TOsF} {5} +\DeclareEncodingSubset{TS1}{charssil-TLF} {5} % \end{macrocode} % % \begin{macrocode} \DeclareEncodingSubset{TS1}{Crimson-TLF} {6} -\DeclareEncodingSubset{TS1}{IBMPlexMono-TLF} {6} -\DeclareEncodingSubset{TS1}{IBMPlexSerif-TLF} {6} -\DeclareEncodingSubset{TS1}{LibertinusMono-TLF} {6} \DeclareEncodingSubset{TS1}{LibertinusSerifDisplay-LF}{6} \DeclareEncodingSubset{TS1}{LinuxLibertineDisplayT-*} {6} \DeclareEncodingSubset{TS1}{LinuxLibertineMonoT-LF} {6} \DeclareEncodingSubset{TS1}{LinuxLibertineMonoT-TLF} {6} -\DeclareEncodingSubset{TS1}{Overlock-LF} {6} +\DeclareEncodingSubset{TS1}{Ovrlck-LF} {6} % \end{macrocode} % % \begin{macrocode} +\DeclareEncodingSubset{TS1}{ComicNeue-TLF} {7} +\DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF} {7} \DeclareEncodingSubset{TS1}{CormorantGaramond-*} {7} \DeclareEncodingSubset{TS1}{Heuristica-TLF} {7} \DeclareEncodingSubset{TS1}{Heuristica-TOsF} {7} \DeclareEncodingSubset{TS1}{IMFELLEnglish-TLF} {7} -\DeclareEncodingSubset{TS1}{LibreBaskerville-TLF} {7} -\DeclareEncodingSubset{TS1}{LibreCaslon-*} {7} -\DeclareEncodingSubset{TS1}{Marcellus-LF} {7} +\DeclareEncodingSubset{TS1}{LibreBskrvl-TLF} {7} +\DeclareEncodingSubset{TS1}{LibreCsln-*} {7} +\DeclareEncodingSubset{TS1}{Lbstr-LF} {7} +\DeclareEncodingSubset{TS1}{Mrcls-LF} {7} +% \end{macrocode} +% Strangely enough NotoSerif and NotoSans are sub-encoding 7 as +% they are missing \cs{textminus} and several other glyphs. In +% contrast the NotoSansMono is far more complete. +% \begin{macrocode} \DeclareEncodingSubset{TS1}{NotoSans-*} {7} -\DeclareEncodingSubset{TS1}{NotoSansMono-TLF} {7} -\DeclareEncodingSubset{TS1}{NotoSansMono-TOsF} {7} \DeclareEncodingSubset{TS1}{NotoSerif-*} {7} -\DeclareEncodingSubset{TS1}{Quattrocento-TLF} {7} -\DeclareEncodingSubset{TS1}{QuattrocentoSans-TLF} {7} -\DeclareEncodingSubset{TS1}{XCharter-TLF} {7} -\DeclareEncodingSubset{TS1}{XCharter-TOsF} {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}{Quattro-LF} {7} +\DeclareEncodingSubset{TS1}{QuattroSans-LF} {7} +\DeclareEncodingSubset{TS1}{Frm-LF} {7} % the superiors are missing % \end{macrocode} % % \begin{macrocode} -\DeclareEncodingSubset{TS1}{Cochineal-*} {8} +\DeclareEncodingSubset{TS1}{LibertinusMono-TLF} {8} % \end{macrocode} % % \begin{macrocode} @@ -1231,7 +1272,7 @@ % % Here are new names for the legacy symbols that \LaTeX{} used to % pick up from the \texttt{OMS} encoded fonts (and used for itemize -% lists or footnote symbols. +% lists or footnote symbols). % % We go the roundabout way via separate OMS declarations so that %\begin{verbatim} @@ -1481,20 +1522,22 @@ % % % -% % \section{The \texttt{textcomp} package} % % +% For any rollback request before 2018-08-11 we make an attempt by +% loading the 2018 version. +% \changes{v2.1b}{2024/04/24} +% {Load the 2018 version when rolling back prior to 2018-08-11 +% (gh/1333)} % \begin{macrocode} %<*TS1sty> -\providecommand\DeclareRelease[3]{} -\providecommand\DeclareCurrentRelease[2]{} - +\DeclareRelease{}{1997-12-01}{textcomp-2018-08-11.sty} \DeclareRelease{}{2018-08-11}{textcomp-2018-08-11.sty} \DeclareCurrentRelease{}{2020-02-02} \ProvidesPackage{textcomp} - [2020/02/02 v2.0n Standard LaTeX package] + [2024/04/24 v2.1b Standard LaTeX package] % \end{macrocode} % % A precaution in case this is used without rebuilding the format. @@ -1550,8 +1593,8 @@ } % \end{macrocode} % +% \changes{v2.1a}{2024/04/22}{Drop default option \texttt{info} (gh/1333)} % \begin{macrocode} -\ExecuteOptions{info} \ProcessOptions\relax % \end{macrocode} % @@ -1706,7 +1749,7 @@ % The default is ``almostfull'' which means that old documents will % work except that |\textcircled| and |\t| will use the kernel % defaults (with the advantage that this also works if the current -% font (as often the case) doesn't implement these glyphs. +% font, as often the case, doesn't implement these glyphs). % % The ``force'' option simply sets the switch to true. % \begin{macrocode} @@ -2301,8 +2344,547 @@ % \begin{macrocode} % % \end{macrocode} +% +% +% +% +% \section{The \texttt{checkencodingsubset.tex} file} +% +% This is a simple file that asks for a name of a font family and +% then displays information about the TS1 encoding for this family +% and recommends the right encoding subset (to be used with +% \cs{DeclareEncodingsubset}) for this family. +% \changes{v1.1a}{2024/01/27}{Added check file for encoding subset} +% \begin{macrocode} +%<*TS1check> +\Providesfile{checkencodingsubset.tex} + [2024/01/27 v0.5a Figure out safe TS1 encoding subsets] +% \end{macrocode} +% +% \begin{macrocode} +\let\typeoutdetails\typeout +%\def\typeoutdetails#1{} % alternative definition used below +% \end{macrocode} +% +% For the purpose of this check a glyph exists if the font slot is +% occupied---too bad if that contains the wrong glyph or some tofu. +% If it ``exists'' we return 0 otherwise 1. This way we can call +% this macro several times in a row and obtain a number that is 0 +% if all glyphs are existing or greater than 0 if any of them is +% missing. +% +% The second argument (holding the command name for a symbol) is +% not used during these tests. +% \begin{macrocode} +\def\doesglyphexist#1#2{\iffontchar\testFont #1 0\else 1\relax \fi} +% \end{macrocode} +% +% This macro also tests and outputs some information about the +% symbol if it is missing. This time we make use of the second +% argument. +% \begin{macrocode} +\def\glyphmissingdetails#1#2{\iffontchar\testFont #1 \else + \typeoutdetails{\space\space\space ==> \string#2 (#1) is missing}\fi} +% \end{macrocode} +% +% \begin{macrocode} +\newif\ifsafesubencodingfound +\newif\ifcoremisses +% \end{macrocode} +% +% Testing a group of symbols that belong to one sub-encoding. More +% precisely, the symbols that become unavailable if you change from +% sub-encoding $x$ (\texttt{\#2}) to $x+1$ (\texttt{\#3}). As far +% as the code is concerned, the +% symbols that are supposed to be always available (the core) +% become available if we test the group \texttt{-1} and \texttt{0}. +% +% The first argument contains the testing code and is supposed to +% return a single number greater or equal to zero. +% \begin{macrocode} +\def\testgroup#1#2#3{% + \ifnum 0 = #1% + \ifnum #2<0 + \typeoutdetails{All glyphs in core exist}% + \else + \typeoutdetails{All glyphs between sub-encoding #2 and #3 exist}% + \fi + \else + \ifnum #2<0 + \typeoutdetails{**********************************}% + \typeoutdetails{Some glyphs are missing from core:}% + \coremissestrue + \ifsafesubencodingfound \else + \def\subencodingresult{#2}% + \fi + \else + \typeoutdetails{Some glyphs are missing from sub-encoding #2:}% + \ifsafesubencodingfound \else + \def\subencodingresult{#3}% + \fi + \fi +% \end{macrocode} +% If some glyphs are missing, we rerun the test code but this time +% using \cs{glyphmissingdetails}. +% \begin{macrocode} + {\let\doesglyphexist \glyphmissingdetails #1}% +% \end{macrocode} +% And because we had misses we have definitely found the subset. +% \begin{macrocode} + \safesubencodingfoundtrue + \fi +} +% \end{macrocode} +% +% The currently defined subset for the family is either stored in +% \cs{TS1:\meta{family}} if it was declared, or it is the default +% subset which is stored in \cs{TS1:?}. +% \begin{macrocode} +\def\currsubencoding#1{\csname TS1:\ifcsname TS1:#1\endcsname #1\else ?\fi\endcsname} +% \end{macrocode} +% +% If a font family is not found when declaring it with +% \cs{DeclareFixedFont} we end up with the following font. This can +% then be used as a simple test if we failed loading the TS1 font. +% \begin{macrocode} +\DeclareFixedFont\cmrFont{TS1}{cmr}{m}{n}{10pt} +% \end{macrocode} +% +% Check for all glyphs in all encoding subsets \ldots +% \begin{macrocode} +\def\testallgroups#1{% + \DeclareFixedFont\testFont{TS1}{#1}{m}{n}{10pt}% + \ifx\testFont\cmrFont + \typeout{***** Font family #1 not found ****}% + \else +% \end{macrocode} +% We haven't checked anything yet. +% \begin{macrocode} + \safesubencodingfoundfalse + \coremissesfalse + \typeoutdetails{^^J-----------------------------------------}% + \typeoutdetails{Testing font family #1^^J(currently TS1-sub-encoding + \currsubencoding{#1})}% + \typeout{-----------------------------------------}% +% \end{macrocode} +% Then we start testing the groups beginning with the glyphs +% between sub-encoding 8 and 9. If any of them is missing (checked +% with \cs{doesglyphexist}) then we already know that 9 is the +% correct answer. +% \begin{macrocode} + \testgroup{% + \doesglyphexist{21}{\texttwelveudash}% + \doesglyphexist{22}{\textthreequartersemdash}% + \doesglyphexist{134}{\textbardbl}% + \doesglyphexist{137}{\textcelsius}% + \doesglyphexist{178}{\texttwosuperior}% + \doesglyphexist{179}{\textthreesuperior}% + \doesglyphexist{185}{\textonesuperior}% + }{8}{9}% +% \end{macrocode} +% Nevertheless we go on with further groups so that the output +% lists all missing glyphs. +% \begin{macrocode} + \testgroup{% + \doesglyphexist{32}{\textblank}% + \doesglyphexist{148}{\textinterrobang}% + \doesglyphexist{149}{\textinterrobangdown}% + \doesglyphexist{191}{\texteuro}% + }{7}{8}% + \testgroup{% + \doesglyphexist{47}{\textfractionsolidus}% + \doesglyphexist{61}{\textminus}% + \doesglyphexist{87}{\textohm}% + \doesglyphexist{181}{\textmu}% + }{6}{7}% + \testgroup{% + \doesglyphexist{140}{\textflorin}% + \doesglyphexist{164}{\textcurrency}% + }{5}{6}% + \testgroup{% + \doesglyphexist{155}{\textnumero}% + \doesglyphexist{157}{\textestimated}% + }{4}{5}% + \testgroup{% + \doesglyphexist{24}{\textleftarrow}% + \doesglyphexist{25}{\textrightarrow}% + \doesglyphexist{94}{\textuparrow}% + \doesglyphexist{95}{\textdownarrow}% + \doesglyphexist{141}{\textcolonmonetary}% + \doesglyphexist{142}{\textwon}% + \doesglyphexist{146}{\textlira}% + \doesglyphexist{150}{\textdong}% + }{3}{4}% + \testgroup{% + \doesglyphexist{60}{\textlangle}% + \doesglyphexist{62}{\textrangle}% + }{2}{3}% + \testgroup{% + \doesglyphexist{0}{\capitalgrave}% + \doesglyphexist{1}{\capitalacute}% + \doesglyphexist{2}{\capitalcircumflex}% + \doesglyphexist{3}{\capitaltilde}% + \doesglyphexist{4}{\capitaldieresis}% + \doesglyphexist{5}{\capitalhungarumlaut}% + \doesglyphexist{6}{\capitalring}% + \doesglyphexist{7}{\capitalcaron}% + \doesglyphexist{8}{\capitalbreve}% + \doesglyphexist{9}{\capitalmacron}% + \doesglyphexist{10}{\capitaldotaccent}% + \doesglyphexist{11}{\capitalcedilla}% + \doesglyphexist{12}{\capitalogonek}% + \doesglyphexist{26}{\t}% + \doesglyphexist{27}{\capitaltie}% + \doesglyphexist{28}{\newtie}% + \doesglyphexist{29}{\capitalnewtie}% + \doesglyphexist{45}{\textdblhyphen}% + \doesglyphexist{48}{\textzerooldstyle}% + \doesglyphexist{49}{\textoneoldstyle}% + \doesglyphexist{50}{\texttwooldstyle}% + \doesglyphexist{51}{\textthreeoldstyle}% + \doesglyphexist{52}{\textfouroldstyle}% + \doesglyphexist{53}{\textfiveoldstyle}% + \doesglyphexist{54}{\textsixoldstyle}% + \doesglyphexist{55}{\textsevenoldstyle}% + \doesglyphexist{56}{\texteightoldstyle}% + \doesglyphexist{57}{\textnineoldstyle}% + \doesglyphexist{77}{\textmho}% + \doesglyphexist{79}{\textbigcircle}% + \doesglyphexist{91}{\textlbrackdbl}% + \doesglyphexist{93}{\textrbrackdbl}% + \doesglyphexist{96}{\textasciigrave}% + \doesglyphexist{98}{\textborn}% + \doesglyphexist{99}{\textdivorced}% + \doesglyphexist{100}{\textdied}% + \doesglyphexist{108}{\textleaf}% + \doesglyphexist{109}{\textmarried}% + \doesglyphexist{110}{\textmusicalnote}% + \doesglyphexist{126}{\texttildelow}% + \doesglyphexist{127}{\textdblhyphenchar}% + \doesglyphexist{128}{\textasciibreve}% + \doesglyphexist{129}{\textasciicaron}% + \doesglyphexist{175}{\textasciimacron}% + \doesglyphexist{130}{\textacutedbl}% + \doesglyphexist{131}{\textgravedbl}% + \doesglyphexist{138}{\textdollaroldstyle}% + \doesglyphexist{139}{\textcentoldstyle}% + \doesglyphexist{143}{\textnaira}% + \doesglyphexist{144}{\textguarani}% + \doesglyphexist{145}{\textpeso}% + \doesglyphexist{147}{\textrecipe}% + \doesglyphexist{152}{\textpertenthousand}% + \doesglyphexist{153}{\textpilcrow}% + \doesglyphexist{154}{\textbaht}% + \doesglyphexist{156}{\textdiscount}% + \doesglyphexist{158}{\textopenbullet}% + \doesglyphexist{159}{\textservicemark}% + \doesglyphexist{160}{\textlquill}% + \doesglyphexist{161}{\textrquill}% + \doesglyphexist{168}{\textasciidieresis}% + \doesglyphexist{171}{\textcopyleft}% + \doesglyphexist{173}{\textcircledP}% + \doesglyphexist{180}{\textasciiacute}% + \doesglyphexist{184}{\textreferencemark}% + \doesglyphexist{187}{\textsurd}% + }{1}{2}% +% \end{macrocode} +% All fonts (up to now) that belong to sub-encoding 1 do have the +% \cs{textcircled} glyph, but it is too small to be usable. So this +% test for this group currently doesn't do much good---but who +% knows maybe one day a font shows up in which this glyph is +% actually missing. +% \begin{macrocode} + \testgroup{% + \doesglyphexist{79}{\textcircled}% this is not a proper test because the symbol is + % usually available but not usable + }{0}{1}% + \testgroup{% + \doesglyphexist{13}{\textquotestraightbase}% + \doesglyphexist{18}{\textquotestraightdblbase}% + \doesglyphexist{23}{\textcapitalcompwordmark}% + \doesglyphexist{31}{\textascendercompwordmark}% + \doesglyphexist{36}{\textdollar}% + \doesglyphexist{39}{\textquotesingle}% + \doesglyphexist{42}{\textasteriskcentered}% + \doesglyphexist{132}{\textdagger}% + \doesglyphexist{133}{\textdaggerdbl}% + \doesglyphexist{135}{\textperthousand}% + \doesglyphexist{136}{\textbullet}% + \doesglyphexist{151}{\texttrademark}% + \doesglyphexist{162}{\textcent}% + \doesglyphexist{163}{\textsterling}% + \doesglyphexist{165}{\textyen}% + \doesglyphexist{166}{\textbrokenbar}% + \doesglyphexist{167}{\textsection}% + \doesglyphexist{169}{\textcopyright}% + \doesglyphexist{170}{\textordfeminine}% + \doesglyphexist{172}{\textlnot}% + \doesglyphexist{174}{\textregistered}% + \doesglyphexist{176}{\textdegree}% + \doesglyphexist{177}{\textpm}% + \doesglyphexist{182}{\textparagraph}% + \doesglyphexist{183}{\textperiodcentered}% + \doesglyphexist{186}{\textordmasculine}% + \doesglyphexist{188}{\textonequarter}% + \doesglyphexist{189}{\textonehalf}% + \doesglyphexist{190}{\textthreequarters}% + \doesglyphexist{214}{\texttimes}% + \doesglyphexist{246}{\textdiv}% + }{-1}{0}% +% \end{macrocode} +% If all groups have all glyphs then we have the full encoding +% (subset 0). +% \begin{macrocode} + \ifsafesubencodingfound\else + \def\subencodingresult{0}% + \fi +% \end{macrocode} +% If the font is missing some of the core glyphs we make a remark +% about this, because they will never display. +% \begin{macrocode} + \typeoutdetails{-----------------------------------------}% + \typeout{TS1 encoding subset for #1\ifcoremisses \space(ignoring core misses)\fi + \space (\ifnum\subencodingresult = + \currsubencoding{#1} ok\else bad\fi)}% + \typeout{Use sub-encoding \subencodingresult + \ifnum\subencodingresult = \currsubencoding{#1}\else + \space (not \currsubencoding{#1})\fi} + \typeout{-----------------------------------------^^J}% + \fi +} +% \end{macrocode} +% +% This tests all declarations (or most of them) that have been +% added to the kernel. It is called if no family is given interactively. +% \begin{macrocode} +\long\def\testallkerneldefinedfamilies{% +\testallgroups{ccr}% {0} +\testallgroups{cmbr}% {0} +%%\testallgroups{cmr}% {0} % don't test this one as it is the fallback + % thus reports that the family is not found +\testallgroups{cmss}% {0} +\testallgroups{cmtl}% {0} +\testallgroups{cmtt}% {0} +\testallgroups{cmvtt}% {0} +\testallgroups{pxr}% {0} +\testallgroups{pxss}% {0} +\testallgroups{pxtt}% {0} +\testallgroups{qag}% {0} +\testallgroups{qbk}% {0} +\testallgroups{qcr}% {0} +\testallgroups{qcs}% {0} +\testallgroups{qhvc}% {0} +\testallgroups{qhv}% {0} +\testallgroups{qpl}% {0} +\testallgroups{qtm}% {0} +\testallgroups{qzc}% {0} +\testallgroups{txr}% {0} +\testallgroups{txss}% {0} +\testallgroups{txtt}% {0} +% +% Next would claim to be 0 (or 2) +% +%\testallgroups{lmr}% {1} +%\testallgroups{lmdh}% {1} +%\testallgroups{lmss}% {1} +%\testallgroups{lmssq}% {1} +%\testallgroups{lmvtt}% {1} +%\testallgroups{lmtt}% {1} % missing TM, SM and pertenthousand so really 2 +% +% these are no longer in TeX Live +% +%\testallgroups{ptmx}% {2} % gone for a long time it seems +%\testallgroups{ptmj}% {2} % ditto +%\testallgroups{ul8}% {2} % ditto +% +% next block has tofu chars so results are wrong +% +%\testallgroups{bch}% {5} % tofu for blank, ohm +%\testallgroups{futj}%{5} % tofu for blank, interrobang/down, ohm +%\testallgroups{futs}%{5} % tofu for blank, ohm +%\testallgroups{futx}%{5} % probably (currently broken distrib) +%\testallgroups{pag}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{pbk}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{pcr}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{phv}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{pnc}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{pplj}%{5} % tofu for blank +%\testallgroups{pplx}%{5} % tofu for blank +%\testallgroups{ppl}% {5} % tofu for blank interrobang/down +%\testallgroups{ptm}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{pzc}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{ul9}% {5} % tofu for blank, interrobang/down, ohm +%\testallgroups{dayroms}%{6} % tofu for blank, interrobang/down, ohm +%\testallgroups{dayrom}% {6} % tofu for blank, interrobang/down, ohm +%\testallgroups{augie}%{8} % really only missing euro and full of tofu +%\testallgroups{put}% {8} +%\testallgroups{uag}% {8} % probably (currently broken distrib) +%\testallgroups{ugq}% {8} +% +\testallgroups{zi4}% {9} +% +%% not installed normally +% +%\testallgroups{hls}% {5} +%\testallgroups{hlst}% {5} +%\testallgroups{hlct}% {5} +%\testallgroups{hlh}% {5} +%\testallgroups{hlx}% {8} +%\testallgroups{hlce}% {8} +%\testallgroups{hlcn}% {8} +%\testallgroups{hlcw}% {8} +%\testallgroups{hlcf}% {8} - +\testallgroups{lato-LF}% {0} % with a bunch of tofu inside --- should probably be changed +\testallgroups{opensans-TLF}%{0} % with a bunch of tofu inside --- should probably be changed +\testallgroups{cantarell-TLF}% {0} % with a bunch of tofu inside --- should probably be changed +\testallgroups{fbb-LF}% {0} % missing centoldstyle ---> 2 +\testallgroups{tli}% {1} % with lots of tofu inside --- should probably be changed +\testallgroups{Alegreya-OsF}% {2} +\testallgroups{AlegreyaSans-OsF}% {2} +\testallgroups{DejaVuSans-TLF}% {2} +\testallgroups{DejaVuSansCondensed-TLF}% {2} +\testallgroups{DejaVuSansMono-TLF}% {2} this is missing \textfractionsolidus which makes it 7 really +\testallgroups{EBGaramond-LF}% {2} +\testallgroups{Tempora-TLF}% {2} +\testallgroups{Tempora-TOsF}% {2} +\testallgroups{Arimo-TLF}% {3} +\testallgroups{Crlt-TLF}% {3} changed from Carlito- +\testallgroups{FiraSans-LF}% {3} should be 4 +\testallgroups{IBMPlexSans-TLF}% {3} +\testallgroups{Merriwthr-OsF}% {3} changed from Merriweather- and should be 2 +\testallgroups{Montserrat-LF}% {3} now 2 +\testallgroups{MontserratAlternates-LF}%{3} now 2 +\testallgroups{SourceCodePro-TLF}% {3} +\testallgroups{SourceCodePro-TOsF}% {3} +\testallgroups{SourceSansPro-OsF}% {3} +\testallgroups{SourceSerifPro-LF}% {3} +\testallgroups{Tinos-TLF}% {3} +\testallgroups{AccanthisADFStdNoThree-LF}%{4} +\testallgroups{Cabin-TLF}% {4} +\testallgroups{Caladea-TLF}% {4} +\testallgroups{Chivo-LF}% {4} +\testallgroups{ClearSans-TLF}% {4} +\testallgroups{Coelacanth-LF}% {4} +\testallgroups{CrimsonPro-LF}% {4} +\testallgroups{FiraMono-TLF}% {4} +\testallgroups{FiraMono-TOsF}% {4} +\testallgroups{Go-TLF}% {4} +\testallgroups{GoMono-TLF}% {4} +\testallgroups{InriaSans-LF}% {4} +\testallgroups{InriaSerif-LF}% {4} +\testallgroups{LibertinusSans-LF}% {4} +\testallgroups{LibertinusSerif-LF}% {4} +\testallgroups{LibreBodoni-TLF}% {4} +\testallgroups{LibreFranklin-TLF}% {4} +\testallgroups{LinguisticsPro-LF}% {4} +\testallgroups{LinguisticsPro-OsF}% {4} +\testallgroups{LinuxBiolinumT-LF}% {4} +\testallgroups{LinuxLibertineT-LF}% {4} +\testallgroups{MerriwthrSans-OsF}% {4} name change and now 2 +\testallgroups{MintSpirit-LF}% {4} +\testallgroups{MintSpiritNoTwo-LF}% {4} +\testallgroups{PTMono-TLF}% {4} +\testallgroups{PTSans-TLF}% {4} +\testallgroups{PTSansCaption-TLF}% {4} +\testallgroups{PTSansNarrow-TLF}% {4} +\testallgroups{PTSerif-TLF}% {4} +\testallgroups{PTSerifCaption-TLF}% {4} +\testallgroups{Raleway-TLF}% {4} +\testallgroups{Raleway-TOsF}% {4} +\testallgroups{Roboto-LF}% {4} +\testallgroups{RobotoMono-TLF}% {4} +\testallgroups{RobotoSlab-TLF}% {4} +\testallgroups{Rosario-LF}% {4} +\testallgroups{SticksTooText-LF}% {4} +\testallgroups{UniversalisADFStd-LF}%{4} +\testallgroups{Almndr-OsF}% {5} name change +\testallgroups{Baskervaldx-LF}% {5} +\testallgroups{BaskervilleF-LF}% {5} now 2 +\testallgroups{Bttr-TLF}% {5} name changed from Bitter-... +\testallgroups{Cinzel-LF}% {5} +\testallgroups{CinzelDecorative-LF}%{5} +\testallgroups{DejaVuSerif-TLF}% {5} +\testallgroups{DejaVuSerifCondensed-TLF}% {5} +\testallgroups{GilliusADF-LF}% {5} +\testallgroups{charssil-TLF} %% missing should be 5 +\testallgroups{GilliusADFCond-LF}%{5} +\testallgroups{GilliusADFNoTwo-LF}%{5} +\testallgroups{GilliusADFNoTwoCond-LF}%{5} +\testallgroups{Lbstr-LF}% {5} name change and should be 7 +\testallgroups{OldStandard-TLF}% {5} +\testallgroups{PlyfrDisplay-LF}%{5} name change +\testallgroups{PlyfrDisplay-OsF}% {5} name change +\testallgroups{TheanoDidot-TLF}% {5} +\testallgroups{TheanoDidot-TOsF}% {5} +\testallgroups{TheanoModern-TLF}% {5} +\testallgroups{TheanoModern-TOsF}%{5} +\testallgroups{TheanoOldStyle-TLF}%{5} +\testallgroups{TheanoOldStyle-TOsF}%{5} +\testallgroups{Crimson-TLF}% {6} +\testallgroups{IBMPlexMono-TLF}% {6} now 3 +\testallgroups{IBMPlexSerif-TLF}% {6} now 3 +\testallgroups{LibertinusMono-TLF}%{6} should be 8 +\testallgroups{LibertinusSerifDisplay-LF}%{6} +\testallgroups{LinuxLibertineDisplayT-LF}%{6} +\testallgroups{LinuxLibertineMonoT-LF}%{6} +\testallgroups{LinuxLibertineMonoT-TLF}%{6} +\testallgroups{Ovrlck-LF}% {6} name changed +\testallgroups{CormorantGaramond-LF}%{7} +\testallgroups{Heuristica-TLF}% {7} +\testallgroups{Heuristica-TOsF}% {7} +\testallgroups{IMFELLEnglish-TLF}%{7} +\testallgroups{LibreBskvl-LF}% {7} %% wrong name LibreBaskerville-TLF +\testallgroups{LibreCsln-LF}% {7} changed from LibreCaslon- +\testallgroups{Mrcls-LF}% {7} %% wrong name Marcellus-LF +\testallgroups{NotoSans-LF}% {7} +\testallgroups{NotoSansMono-TLF}%{7} now 2 +\testallgroups{NotoSansMono-TOsF}%{7} now 2 +\testallgroups{NotoSerif-LF}% {7} +\testallgroups{Quattro-LF}% {7} changed from Quattrocento- +\testallgroups{QuattroSans-LF}% {7} changed from QuattrocentoSans- +\testallgroups{XCharter-TLF}% {7} now 2 +\testallgroups{XCharter-TOsF}% {7} now 2 +\testallgroups{erewhon-LF}% {7} now 2 +\testallgroups{ComicNeue-TLF}% {7} +\testallgroups{ComicNeueAngular-TLF}%{7} +\testallgroups{Frm-LF}%{7} % the superiors are missing; name changed from Forum-LF +\testallgroups{Cochineal-TLF}% {8} now 5 +\testallgroups{AlgolRevived-TLF}%{9} +} +% \end{macrocode} +% +% There interaction with the user. +% \begin{macrocode} +\typeout{^^J=====================================================================} +\typeout{| Enter font family to check (or for kernel defined families)} +\typeout{=====================================================================} +\typein[\FontFamilyToCheck]{} +% \end{macrocode} +% +% \begin{macrocode} +\if!\FontFamilyToCheck! + \typeout{=====================================================================} + \typeout{| Detailed output? (default no)} + \typeout{=====================================================================} + \typein[\Details]{} + \if!\Details! + \def\typeoutdetails#1{} + \else + \let\typeoutdetails\typeout + \fi + \testallkerneldefinedfamilies +\else + \let\typeoutdetails\typeout + \testallgroups\FontFamilyToCheck +\fi +% \end{macrocode} +% +% \begin{macrocode} +\stop +% +% \end{macrocode} +% % \Finale % diff --git a/Master/texmf-dist/source/latex/base/ltthm.dtx b/Master/texmf-dist/source/latex/base/ltthm.dtx index 180b8accfe4..c900f519dd5 100644 --- a/Master/texmf-dist/source/latex/base/ltthm.dtx +++ b/Master/texmf-dist/source/latex/base/ltthm.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltthm.dtx} - [2014/09/29 v1.0f LaTeX Kernel (Theorems)] + [2024/03/18 v1.0g LaTeX Kernel (Theorems)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltthm.dtx} @@ -237,16 +237,31 @@ % \end{macro} % % \begin{macro}{\@thm} +% \changes{v1.0c}{1994/04/17}{Use new std counter error message (FMi)} +% \changes{v1.0g}{2024/03/18}{Use \cs{@kernel@refstepcounter} to avoid an unwanted target (UFi)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2024/03/18}% +% {\@thm}{no link target}% \def\@thm#1#2{% - \refstepcounter{#1}% + \@kernel@refstepcounter{#1}% \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@thm}{no link target}% +%\def\@thm#1#2{% +% \refstepcounter{#1}% +% \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}} +%\EndIncludeInRelease +% % \end{macrocode} % \end{macro} % % \begin{macro}{\@xthm} % \begin{macro}{\@ythm} % \begin{macrocode} +%<*2ekernel> \def\@xthm#1#2{% \@begintheorem{#2}{\csname the#1\endcsname}\ignorespaces} \def\@ythm#1#2[#3]{% @@ -273,11 +288,26 @@ % NFSS} % Providing theorem defaults. % \task{???}{add `reset@font?} +% % \changes{v1.0g}{2024/03/18}{Insert link target in the label (UFi)} % \begin{macrocode} +% +%<*2ekernel|latexrelease> +%\IncludeInRelease{2024/03/18}% +% {\@begintheorem}{add link targets}% \def\@begintheorem#1#2{\trivlist - \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape} + \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2}]\itshape} \def\@opargbegintheorem#1#2#3{\trivlist - \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape} + \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape} +%\EndIncludeInRelease +%\IncludeInRelease{0000/00/00}% +% {\@begintheorem}{add link targets}% +%\def\@begintheorem#1#2{\trivlist +% \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape} +%\def\@opargbegintheorem#1#2#3{\trivlist +% \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape} +%\EndIncludeInRelease +% +%<*2ekernel> \def\@endtheorem{\endtrivlist} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/base/ltvers.dtx b/Master/texmf-dist/source/latex/base/ltvers.dtx index bf5dce4ca18..5031ef83073 100644 --- a/Master/texmf-dist/source/latex/base/ltvers.dtx +++ b/Master/texmf-dist/source/latex/base/ltvers.dtx @@ -112,10 +112,10 @@ % %\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2023-11-01} + {2024-06-01} % %<*2ekernel> -\def\patch@level{1} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} diff --git a/Master/texmf-dist/source/latex/base/ltxdoc.dtx b/Master/texmf-dist/source/latex/base/ltxdoc.dtx index 584f4f51f64..5e8b4946926 100644 --- a/Master/texmf-dist/source/latex/base/ltxdoc.dtx +++ b/Master/texmf-dist/source/latex/base/ltxdoc.dtx @@ -30,7 +30,7 @@ % %\NeedsTeXFormat{LaTeX2e} %\ProvidesClass{ltxdoc} -% [2023/03/28 v2.1j Standard LaTeX documentation class] +% [2024/02/08 v2.1j Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -288,12 +288,13 @@ % \section{Useful abbreviations} % % |\cmd{\foo}| Prints |\foo| verbatim. It may be used inside moving -% arguments. It can \emph{not} be use to record commands that are defined as +% arguments. It can \emph{not} be used to record commands that are defined as % ``|\outer|'' nor is it possible to use it on conditionals such as % |\iftrue| or defined by |\newif|. -% |\cs{foo}| already available with the \texttt{doc} package also prints |\foo|, for those who prefer that +% |\cs{foo}| Already available with the \texttt{doc} package and also prints |\foo|, +% for those who prefer that % syntax. (This second form can be used to record all types of command so the -% above restrictions do not apply. +% above restrictions do not apply.) % \begin{macro}{\cmd} % \changes{v2.0k}{1994/05/21}{New definition, so \cmd\{ works.} % \begin{macro}{\cs} diff --git a/Master/texmf-dist/source/latex/base/nfssfont.dtx b/Master/texmf-dist/source/latex/base/nfssfont.dtx index ae91abf671c..0464053c10f 100644 --- a/Master/texmf-dist/source/latex/base/nfssfont.dtx +++ b/Master/texmf-dist/source/latex/base/nfssfont.dtx @@ -26,8 +26,8 @@ % extension .ins) which are part of the distribution. % % \fi -\def\nfssfontfileversion{v2.2e} -\def\nfssfontfiledate{2020/11/26} +\def\nfssfontfileversion{v2.2f} +\def\nfssfontfiledate{2023/11/07} % % \iffalse @@ -197,7 +197,7 @@ {\PackageWarningNoLine{nfssfont}% {Encoding file `\next' not found.% \MessageBreak - You might have misspelt the name of the encoding + You might have misspelled the name of the encoding \MessageBreak or perhaps this encoding is not a text encoding, \MessageBreak diff --git a/Master/texmf-dist/source/latex/base/slifonts.fdd b/Master/texmf-dist/source/latex/base/slifonts.fdd index 8ddd639d50a..b35cd07a8be 100644 --- a/Master/texmf-dist/source/latex/base/slifonts.fdd +++ b/Master/texmf-dist/source/latex/base/slifonts.fdd @@ -45,7 +45,7 @@ %<*driver, > \ProvidesFile{sfonts.drv} % - [2019/07/09 v2.2f Standard LaTeX slide font definitions] + [2023/12/02 v2.2f Standard LaTeX slide font definitions] % %<*driver> \documentclass{ltxdoc} @@ -95,7 +95,7 @@ % \section{Introduction} % % This file contains the external font information for special -% variants of the the Computer Modern fonts to be used for overhead +% variants of the Computer Modern fonts to be used for overhead % slides. They allow to produce slides in a similar fashion as it was % originally done by \SliTeX{}. % @@ -103,7 +103,7 @@ % format. Instead the standard format may be used and internally only % different font definition files come into play. % -% Note, that that you therefore can easily produce slides in different +% Note that you therefore can easily produce slides in different % fonts just by calling an appropriate package (like |times|) in % your |\usepackage| command. This works, for example, with all % fonts that are defined to be scalable (eg PostScript fonts) since diff --git a/Master/texmf-dist/source/latex/base/syntonly.dtx b/Master/texmf-dist/source/latex/base/syntonly.dtx index 9d3baaa0245..9844585fa56 100644 --- a/Master/texmf-dist/source/latex/base/syntonly.dtx +++ b/Master/texmf-dist/source/latex/base/syntonly.dtx @@ -71,7 +71,7 @@ \ProvidesFile{syntonly.dtx} % %<*package|dtx> - [2017/06/30 v2.1e Standard LaTeX2e package] + [2024/02/08 v2.1e Standard LaTeX2e package] % % \end{macrocode} % @@ -150,7 +150,7 @@ \repeat % \end{macrocode} % Since all font changes occur either via |\selectfont| (in -% text or |\mathversion| (for math mode) it is sufficient +% text) or |\mathversion| (for math mode), it is sufficient % to change these to no-ops. In addition we must prevent % the loading of math fonts, this is done by making % |\getanddefine@fonts| a no-op. @@ -184,7 +184,7 @@ % The |\nopages@| macro disables the \LaTeX{} output routine. % To this end we define a very simple output routine that empties % the output \emph{and} footnote boxes (remember that the latter -% are insertions. +% are insertions). % \begin{macrocode} \def\nopages@{% \output {\setbox\z@\box\@cclv diff --git a/Master/texmf-dist/source/latex/base/utf8ienc.dtx b/Master/texmf-dist/source/latex/base/utf8ienc.dtx index b7dfe4b0c0b..a2701ac5c87 100644 --- a/Master/texmf-dist/source/latex/base/utf8ienc.dtx +++ b/Master/texmf-dist/source/latex/base/utf8ienc.dtx @@ -886,7 +886,8 @@ \else % \end{macrocode} % -% If the input is malformed UTF-8 there may not be enough closing ) so +% If the input is malformed UTF-8 there may not be enough closing +% \iffalse(\fi ) so % add 5 so there are always some remaining then cleanup and remove % any remaining ones at the end. This avoids |\numexpr| parse errors % while outputting a package error. @@ -1660,7 +1661,7 @@ % \end{macrocode} % According to the Unicode standard Ux04C5 should be an L with ``tail'' not % with descender (which also exists as Ux04A2) but it looks as if the char -% names do not make this distinction). Should they? +% names do not make this distinction. Should they? % \begin{macrocode} %\DeclareUnicodeCharacter{04C5}{\CYRLDSC} %\DeclareUnicodeCharacter{04C6}{\cyrldsc} diff --git a/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx b/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx index 89304a754f8..7bd6b945462 100644 --- a/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx +++ b/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2022 +% Copyright 1993-2023 % The LaTeX3 Project and any individual authors listed elsewhere % in this file. % @@ -65,7 +65,7 @@ %\ProvidesFile{t2aenc.def} %\ProvidesFile{t2benc.def} %\ProvidesFile{t2cenc.def} - [2022/06/11 v1.0j Cyrillic encoding definition file] + [2023/11/07 v1.0k Cyrillic encoding definition file] % \end{macrocode} % % To assure that |\MakeUppercase| and |\MakeLowercase| will work @@ -118,8 +118,13 @@ \DeclareTextCommand{\d}{\LastDeclaredEncoding}[1] {\hmode@bgroup \o@lign{\relax#1\crcr\hidewidth\ltx@sh@ft{-1ex}.\hidewidth}\egroup} +% \end{macrocode} +% +% \changes{v1.0k}{2023/11/07}{Add \cs{hmode@bgroup} to \cs{k} to match +% other encoding definitions (gh/1148)} +% \begin{macrocode} \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1] - {\oalign{\null#1\crcr\hidewidth\char12}} + {\hmode@bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup} \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding} {\%\char 24 } \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding} diff --git a/Master/texmf-dist/source/latex/firstaid/firstaid.ins b/Master/texmf-dist/source/latex/firstaid/firstaid.ins index 22067390cd1..5de510ba513 100644 --- a/Master/texmf-dist/source/latex/firstaid/firstaid.ins +++ b/Master/texmf-dist/source/latex/firstaid/firstaid.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2020-2023 +%% Copyright (C) 2020-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -44,7 +44,7 @@ reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2020-2023 +Copyright (C) 2020-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx b/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx index 2317c051412..152737eaf77 100644 --- a/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx +++ b/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2023 +%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2024 %% %% The LaTeX Project and any individual authors listed elsewhere %% in this file. @@ -111,8 +111,8 @@ % \end{macrocode} % % \begin{macrocode} -\def\LaTeXFirstAidDate{2024/02/29} -\def\LaTeXFirstAidVersion{v1.1c} +\def\LaTeXFirstAidDate{2024/03/20} +\def\LaTeXFirstAidVersion{v1.1e} % \end{macrocode} % % \begin{macrocode} @@ -612,8 +612,21 @@ % routines in \pkg{expl3}. % \begin{macrocode} \AddToHook{package/acro/after}[firstaid]{% - \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms and other abbreviations (CN)} - {\UseName{prop_new:c}{l__acro_tmpa_prop}}% + \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms + and other abbreviations (CN)} + {\UseName{prop_new:c}{l__acro_tmpa_prop}% +% \end{macrocode} +% With the 2024 June release of \LaTeX{} it will also fail to patch +% \cs{endlongtable} and therefore errors when loading. However, the +% patch it tries never worked (because it was setting a local +% boolean at a point where it was more or less immediately +% reset). Thus, rather than fixing the patch approach (which +% requires to surround the patch with \cs{ExplSyntaxOn} +% \verb*/\catcode`\ =10 / and \cs{ExplSyntaxOff}) we simply disable +% the patch for now. +% \begin{macrocode} + \acsetup{patch/longtable=false}% + }% } % \end{macrocode} % @@ -636,11 +649,78 @@ % routines in \pkg{expl3}. % \begin{macrocode} \AddToHook{package/chemnum/after}[firstaid]{% - \FirstAidNeededT{chemnum}{sty}{2021/01/21 v1.3a a comprehensive approach for the numbering of chemical compounds (CN)} + \FirstAidNeededT{chemnum}{sty}{2021/01/21 v1.3a a comprehensive + approach for the numbering of chemical compounds (CN)} {\UseName{prop_new:c}{l__chemnum_tmpa_prop}}% } % \end{macrocode} % +% \subsection{The \pkg{cleveref} package first aid} +% +% The \pkg{cleveref} package expects only two data containers +% for its internal \cs{newlabel} command. This fails if +% \pkg{xr-hyper} is used which expands every \cs{newlabel} to +% five data container and puts the file name into the last one. +% \begin{macrocode} +\AddToHook{package/cleveref/after}[firstaid]{% + \FirstAidNeededT{cleveref}{sty}{2018/03/27 v0.21.4 Intelligent cross-referencing} + {% +% \end{macrocode} +% This are the two commands which retrieve the data from the label info. +% We change them to expect five arguments. +% \begin{macrocode} + \def\cref@getref#1#2{% + \expandafter\let\expandafter#2\csname r@#1@cref\endcsname% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter\@firstoffive#2}}% <-------- five + \def\cpageref@getref#1#2{% + \expandafter\let\expandafter#2\csname r@#1@cref\endcsname% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter\@secondoffive#2}}% <----------- five +% \end{macrocode} +% We also need to redefine the internal label commands of cleveref. +% This must be done after \pkg{cleveref} has made its changes +% in \texttt{begindocument} so we add it to the same hook using +% the hook label used by \pkg{cleveref}. +% This way it is guaranteed to overwrite the definitions. +% \begin{macrocode} + \AddToHook{begindocument}[cleveref]{% + \def\label@noarg#1{% + \cref@old@label{#1}% + \@bsphack% + \edef\@tempa{{page}{\the\c@page}}% + \setcounter{page}{1}% + \edef\@tempb{\thepage}% + \expandafter\setcounter\@tempa% + \cref@constructprefix{page}{\cref@result}% + \protected@write\@auxout{}% + {\string\newlabel{#1@cref}{{\cref@currentlabel}% + {[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <----- five + \@esphack}% + \def\label@optarg[#1]#2{% + \cref@old@label{#2}% + \@bsphack% + \edef\@tempa{{page}{\the\c@page}}% + \setcounter{page}{1}% + \edef\@tempb{\thepage}% + \expandafter\setcounter\@tempa% + \cref@constructprefix{page}{\cref@result}% + \protected@edef\cref@currentlabel{% + \expandafter\cref@override@label@type% + \cref@currentlabel\@nil{#1}}% + \protected@write\@auxout{}% + {\string\newlabel{#2@cref}{{\cref@currentlabel}% + {[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <------- five + \@esphack}% + } + }% +} +% \end{macrocode} +% % \begin{macrocode} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/graphics/color.dtx b/Master/texmf-dist/source/latex/graphics/color.dtx index cf3a7efbcf0..130a960d099 100644 --- a/Master/texmf-dist/source/latex/graphics/color.dtx +++ b/Master/texmf-dist/source/latex/graphics/color.dtx @@ -2,7 +2,7 @@ % \iffalse % %% color.dtx Copyright (C) 1994--1999 David Carlisle -%% Copyright (C) 2005-2022 LaTeX Project +%% Copyright (C) 2005-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -21,7 +21,7 @@ % \ProvidesFile{color.drv} % \fi % \ProvidesFile{color.dtx} - [2022/01/06 v1.3d Standard LaTeX Color (DPC)] + [2024/01/14 v1.3d Standard LaTeX Color (DPC)] % % \iffalse %<*driver> @@ -168,7 +168,7 @@ % % \begin{option}{dvips} % \begin{option}{xdvi} -% Tom Rokicki's dvips driver, and the X Windows previewer, xdvi which uses +% Tom Rokicki's dvips driver, and the X Windows previewer, xdvi, which uses % (a subset of) the same |\specials|. % \begin{macrocode} \DeclareOption{dvips}{\def\Gin@driver{dvips.def}% @@ -248,7 +248,7 @@ % \changes{v0.3k}{1995/09/07} % {Merge dviwindo and dvipsone options} % The drivers of the Y\&Y \TeX\ system. -% (Which use the same |\specials|). +% (Which use the same |\specials|.) % \begin{macrocode} \DeclareOption{dvipsone}{\def\Gin@driver{dvipsone.def}} \DeclareOption{dviwindo}{\ExecuteOptions{dvipsone}} @@ -360,7 +360,7 @@ % The |dvipsnames| option predeclares all the names in the colour % prologue of dvips. The |dvips| option automatically implies % |dvipsnames| unless this choice is overruled with the |nodvipsnames| -% option. For other drivers, eg |textures| you may use this option to +% option. For other drivers, eg |textures|, you may use this option to % explicitly request that these names be declared. % \begin{macrocode} \DeclareOption{dvipsnames}{\def\c@lor@namefile{dvipsnam.def}} @@ -371,7 +371,7 @@ % % \begin{option}{usenames} % The |usenames| option modifies the behaviour of |\DefineNamedColor| -% So that it declares the same name as a ```user's colour'' for use in +% so that it declares the same name as a ``user's colour'' for use in % a |\color| command, as well as a name in the |named| colour model. % The normal behaviour is just to declare the name in the named colour % model. @@ -530,7 +530,7 @@ % |\color| or |\textcolor| commands to refer to a colour specified by % \emph{colour-spec} in the colour model \emph{model}. % -% |\definecolor| associates the \emph{name} the to a colour in +% |\definecolor| associates the \emph{name} to a colour in % \emph{model}. So |\color{|\emph{name}|}| would check \emph{name} % then issue a |\special| for the colour model \emph{model}. % @@ -579,12 +579,12 @@ % names. % % The `color1' drivers (dvips) currently ignore the specification of -% the colour, and once a name is defined, just put the colour name in -% the dvi file. For dvips, The header file \texttt{color.pro} is used to +% the colour and, once a name is defined, just put the colour name in +% the dvi file. For dvips, the header file \texttt{color.pro} is used to % give the cmyk equivalents of the names. % % The `color2' drivers (textures) use a special postscript operator -% that takes both the name and the cmyk equivalent. so if the names are +% that takes both the name and the cmyk equivalent, so if the names are % not being used, `fall back' definitions in the cmyk model are available. % These drivers also allow a numeric value to affect the `density' % of the colour to use. @@ -688,9 +688,9 @@ % % \begin{macro}{\normalcolor} % Early versions of this package redefined |\reset@font| to reset the -% color as well. Current versions do not do this (there are too many -% |\reset@font| commands hidden in strange places) and so defines a -% separate command, |\normalcolor| to reset the colour to the colour in +% color as well. Current versions do not do this (since there are too many +% |\reset@font| commands hidden in strange places) and so they define a +% separate command, |\normalcolor|, to reset the colour to the colour in % effect at the start of the document. % % |\normalcolor| is defined (to |\relax|) in the \LaTeX\ kernel, so it @@ -722,9 +722,9 @@ % the truth as the `macro layer' of \TeX\ does not know where the output % routine is going to re-insert floats. This is why drivers must % maintain their own stack of colours in order to fully support these -% commands. +% commands.) % -% For dvips, the |\current@color| it is something like `|Black|' or +% For dvips, the |\current@color| is something like `|Black|' or % `|rgb 0 1 0|', but other packages should not rely on any particular % format for this macro. % @@ -755,7 +755,7 @@ % definition of this command. A graphics package may want to define it % using a special to produce (for example) a PostScript line. Producing % the line in the |\special| has the advantage that on a preview that -% does not understand |\special|s, the line is automatically omited, +% does not understand |\special|s, the line is automatically omitted, % without needing to modify the source of the document (for instance by % adding the |monochrome| option). % @@ -894,7 +894,7 @@ % \end{macro} % % \begin{macro}{\color@vbox} -% To be used to open a `coloured hbox' +% To be used to open a `coloured vbox' % \changes{v0.3h}{1994/11/22} % {Macro added} % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/graphics/drivers.dtx b/Master/texmf-dist/source/latex/graphics/drivers.dtx index e1c19e0296f..fb5132272b9 100644 --- a/Master/texmf-dist/source/latex/graphics/drivers.dtx +++ b/Master/texmf-dist/source/latex/graphics/drivers.dtx @@ -3,7 +3,7 @@ % %% drivers.dtx Copyright (C) 1994 David Carlisle Sebastian Rahtz %% Copyright (C) 1995 1996 1997 1998 1999 David Carlisle -%% Copyright (C) 2000-2022 LaTeX Project +%% Copyright (C) 2000-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/Master/texmf-dist/source/latex/graphics/epsfig.dtx b/Master/texmf-dist/source/latex/graphics/epsfig.dtx index b8927f2da55..46dc36d0bf8 100644 --- a/Master/texmf-dist/source/latex/graphics/epsfig.dtx +++ b/Master/texmf-dist/source/latex/graphics/epsfig.dtx @@ -2,7 +2,7 @@ % \iffalse % %% epsfig.dtx Copyright (C) 1994-1996 1999 Sebastian Rahtz -%% Copyright (C) 2000-2022 LaTeX Project +%% Copyright (C) 2000-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -19,7 +19,7 @@ % \ProvidesFile{epsfig.drv} % \fi % \ProvidesFile{epsfig.dtx} - [2017/06/25 v1.7b (e)psfig emulation (SPQR)] + [2024/01/14 v1.7b (e)psfig emulation (SPQR)] % % \iffalse %<*driver> @@ -51,7 +51,7 @@ \RequirePackage{graphicx} % \end{macrocode} % \subsection{Emulation of `psfig' syntax} -% Emulate "epsfig.sty", and most varieties of psfig +% Emulate \texttt{epsfig.sty}, and most varieties of psfig % \begin{macro}{\psfig,\epsfig} % \begin{macrocode} \def\psfig#1{% @@ -83,7 +83,7 @@ % \end{macrocode} % \end{macro} % \subsection{Emulation of `epsf' syntax} -% Emulate Rokicki's "epsf.tex" supplied with the ever-popular dvips. +% Emulate Rokicki's \texttt{epsf.tex}, supplied with the ever-popular dvips. % \begin{macro}{\epsfbox,\epsffile} % \begin{macrocode} \newdimen\epsfxsize diff --git a/Master/texmf-dist/source/latex/graphics/graphics.dtx b/Master/texmf-dist/source/latex/graphics/graphics.dtx index 92b3c8f335a..2392ac09d10 100644 --- a/Master/texmf-dist/source/latex/graphics/graphics.dtx +++ b/Master/texmf-dist/source/latex/graphics/graphics.dtx @@ -2,7 +2,7 @@ % \iffalse % %% graphics.dtx Copyright (C) 1994 David Carlisle Sebastian Rahtz -%% Copyright (C) 1995-2022 LaTeX Project +%% Copyright (C) 1995-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -17,9 +17,9 @@ \ProvidesFile{graphics.dtx} % %<+package>\NeedsTeXFormat{LaTeX2e}[1995/12/01] -%<+package>\providecommand\DeclareRelease[3]{} -%<+package>\providecommand\DeclareCurrentRelease[2]{} %<+package> +% Try to fulfill rollback requests to early years by using the 2017 version: +%<+package>\DeclareRelease{}{1994-06-01}{graphics-2017-06-25.sty} %<+package>\DeclareRelease{}{2017-06-25}{graphics-2017-06-25.sty} %<+package>\DeclareCurrentRelease{}{2019-10-01} %<+package> @@ -27,7 +27,7 @@ % \ProvidesFile{graphics.drv} % \fi % \ProvidesFile{graphics.dtx} - [2022/03/10 v1.4e Standard LaTeX Graphics (DPC,SPQR)] + [2024/05/23 v1.4g Standard LaTeX Graphics (DPC,SPQR)] % % \iffalse %<*driver> @@ -69,18 +69,18 @@ % \section{Introduction} % % This package implements various `graphics' functions. The main -% features are a) inclusion of `graphics' files. b) Rotation of sections -% of the page, c) Scaling of sections of the page. +% features are: a) inclusion of `graphics' files; b) rotation of sections +% of the page; c) scaling of sections of the page. % % The design is split into three `levels'. % \begin{itemize} % \item The user interface. This is the collection of commands designed -% to appear in a document text. Actually two separate user interface +% to appear in a document text. Actually two separate user interfaces % have been implemented. The `standard' interface, described here, and a % more powerful, and more `user-friendly' interface provided by the % |graphicx| package. % \item The core functions. These functions, which are also implemented -% in this file do all the `main work'. The `user-interface functions +% in this file, do all the `main work'. The `user-interface functions' % just collect together the information from any optional-arguments or % star-forms, and then call one of these functions. % \item The driver files. It is not possible to achieve the @@ -90,7 +90,7 @@ % and the syntax required to pass instructions to the drivers is also % not standardised. So the `core functions' never access |\special| % directly, but rather call a series of commands that must be defined in -% a special file customised for each driver. The accompanying file, +% a special file customised for each driver. The accompanying file % |drivers.dtx| has suitable files for a range of popular drivers. % \end{itemize} % @@ -99,9 +99,9 @@ % driver that is to be used to print the document. You may wish to set % up a configuration file so that this option always takes effect, even % if not specified in the document. To do this, produce a file -% |graphics.cfg| containing the line:\\ +% |graphics.cfg| containing the line\\ % |\ExecuteOptions{dvips}|\\ -% (or whichever other driver you wish.) +% (or whichever other driver you wish). % % Apart from the driver options there are a few other options to control % the behaviour of the package. @@ -166,7 +166,7 @@ % |\graphicspath{{eps/}{tiff/}}| % would cause the system to look in the subdirectories |eps| and |tiff| % of the current directory. The default setting of this path is -% |\input@path| that is: graphics files will be found wherever \TeX\ +% |\input@path|, so that graphics files will be found wherever \TeX\ % files are found. % % \DescribeMacro @@ -204,7 +204,7 @@ % \emph{default rule}. For instance the |dvips| driver file declares all % files to be of type |eps| unless a more specific rule is declared. % -% Since Version v0.6, extensions should be specified including the |.| +% Since Version v0.6, extensions should be specified including the |.|, % that is, |.eps| not |eps|. % % \emph{type} is the `type' of file involved. All files of the same type @@ -241,7 +241,7 @@ % used to denote the filename. Thus using the dvips driver, one may % use\\ % |\DeclareGraphicsRule{.ps.gz}{eps}{.ps.bb}{`zcat #1}|\\ -% the final argument causes dvips to use the |zcat| command to unzip the +% The final argument causes dvips to use the |zcat| command to unzip the % file before inserting it into the PostScript output. % % \subsection{Rotation} @@ -297,18 +297,18 @@ % \DescribeMacro % {\Gread@eps}\marg{file}\\ % For each \emph{type} of graphics file supported, the driver file must -% define |\Ginclude@|\emph{type} and, optionally |\Gread@|\emph{type}. +% define |\Ginclude@|\emph{type} and, optionally, |\Gread@|\emph{type}. % The read command is responsible for obtaining size information from -% the file specified in the |\DeclareGraphicsRule| command. However the +% the file specified in the |\DeclareGraphicsRule| command. However, the % kernel defines a function, |\Gread@eps|, which can read PostScript % files to find the % |%%BoundingBox| comment. This function will be used for any type for % which a specific function has not been declared. |\Gread@eps| accepts % a generalised version of the bounding box comment. \TeX\ units may be % used (but there must be no space before the unit). If the unit is -% omitted |bp| is assumed. So\\ +% omitted, |bp| is assumed. So\\ % |%%BoundingBox 0 0 2in 3in|\\ -% Would be accepted by this function, to produce a 2in wide, by 3in high +% would be accepted by this function, to produce a 2in wide by 3in high % graphic. % % \subsection{Rotation} @@ -334,7 +334,7 @@ % \DescribeMacro % {\Gscale@box@dddd} % \marg{dima}\marg{dimb}\marg{dimc}\marg{dimd}\marg{text}\\ -% Scale \emph{text} in horizontally by a factor \emph{dima}/\emph{dimb}, +% Scale \emph{text} horizontally by a factor \emph{dima}/\emph{dimb}, % and vertically by a factor of \emph{dimc}/\emph{dimd}. % % \DescribeMacro @@ -353,7 +353,7 @@ % |\Ginclude@|\emph{type}\\ % The Graphics kernel function will call this driver-defined function % with the filename as argument, and certain additional information will -% be provided as follows.: +% be provided as follows: % % \noindent\begin{tabular}{p{.4\textwidth}p{.5\textwidth}} % |\Gin@llx|, |\Gin@lly|,\newline @@ -362,7 +362,7 @@ % Registers storing the natural size.\\ % |\Gin@req@width|\newline |\Gin@req@height| & % Registers storing the required size, after scaling.\\ -% |\Gin@scalex|, |\Gin@scaley| & macros with the scale factors. A value +% |\Gin@scalex|, |\Gin@scaley| & Macros with the scale factors. A value % of |!| means: Scale by the same amount as the other direction.\\ % |\ifGin@clip| & |\newif| token, true if the graphic should be % `clipped' to the bounding box. @@ -371,11 +371,11 @@ % Optionally the driver may define a command of the form:\\ % |\Gread@|\emph{type}\\ % This is responsible for reading an external file to find the bounding -% box information. If such a command is not declared, but a read-file is -% specified the command |\Gread@eps|, which is defined in the Graphics -% Kernel will be used. +% box information. If such a command is not declared but a read-file is +% specified, the command |\Gread@eps|, which is defined in the Graphics +% Kernel, will be used. % -% \subsection{Literal Postscript} +% \subsection{Literal PostScript} % Drivers that are producing PostScript output may want to define % the following macros. They each take one argument which should be % passed to an appropriate special. They are not used directly by this @@ -384,7 +384,7 @@ % |\Gin@PS@raw|, Literal PostScript special.\\ % |\Gin@PS@restored|, Literal PostScript special, the driver will % surround this with a save-restore pair.\\ -% |\Gin@PS@literal@header|, Postscript to be inserted in the header +% |\Gin@PS@literal@header|, PostScript to be inserted in the header % section of the PostScript file.\\ % |\Gin@PS@file@header|, external file to be inserted in the header % section of the PostScript file. @@ -550,7 +550,7 @@ % \changes{v0.3g}{1994/03/15} % {Use dvips def file not development version} % \begin{option}{xdvi} -% Tomas Rockicki's PostScript driver (unix, MSDOS, VMS\ldots). +% Tomas Rokicki's PostScript driver (unix, MSDOS, VMS\ldots). % The |X11| previewer |xdvi| supports basically the same set of % |\specials|. % \begin{macrocode} @@ -672,7 +672,7 @@ % \begin{option}{pctex32} % \changes{v1.0b}{1996/10/29} % {pctex32 option added} -% PC\TeX\ (MSDOS/Windows) . +% PC\TeX\ (MSDOS/Windows). % \begin{macrocode} \DeclareOption{pctexps}{\def\Gin@driver{pctexps.def}} \DeclareOption{pctexwin}{\def\Gin@driver{pctexwin.def}} @@ -913,7 +913,7 @@ % \end{macro} % % \begin{macro}{\Gin@iii} -% Set the coordinates of the {\bfseries l}lower {\bfseries l}eft corner, +% Set the coordinates of the {\bfseries l}ower {\bfseries l}eft corner, % and the coordinates of the {\bfseries u}pper {\bfseries r}ight % corner. The coordinates may be any \TeX\ dimension, defaulting to |bp|. % \changes{v0.6c}{1994/12/15} @@ -944,8 +944,8 @@ % is invisibly small but files conforming to Adobe DSC should have % \emph{integer} Bounding Box Coordinates, and conceivably some drivers % might demand integer values. -% (Although most seem to accept real values (if they accept bounding box -% coordinates at all) in the |\special|. This is the reason why the +% Although most seem to accept real values (if they accept bounding box +% coordinates at all) in the |\special|, this is the reason why the % mechanism uses |\def| and not \TeX\ lengths, as in earlier releases of % the package. % \begin{macrocode} @@ -1454,8 +1454,8 @@ % {New macro} % \begin{macro}{\Gread@generic@aux} % \begin{macro}{\Gread@eps} -% Read an EPS file (|#1|) and search for a line -% starting with |%%BoundingBox| and returns the result +% Read an EPS file (|#1|), search for a line +% starting with |%%BoundingBox|; then return the result % by setting four dimension registers % |\Gin@llx|, |\Gin@lly|, |\Gin@urx| and |\Gin@ury|. % \changes{v0.5e}{1994/11/02} @@ -1701,7 +1701,7 @@ % \begin{macro}{\Grot@left} % \begin{macro}{\Grot@right} % \begin{macro}{\Grot@depth} -% Final Rotated box dimensions +% Final rotated box dimensions % \begin{macrocode} \let\Grot@height\@ovxx \let\Grot@left\@ovyy @@ -1920,8 +1920,8 @@ % \end{macrocode} % Now we should translate back by $(O_x,O_y)$, but \TeX\ can not really % deal with boxes that do not have the reference point at the left edge. -% (Everything with a $-$ve $x$-coordinate would over-print earlier -% text). So we modify the horizontal translation so that the +% (Everything with a negative $x$-coordinate would over-print earlier +% text.) So we modify the horizontal translation so that the % reference point as understood by \TeX\ \emph{is} at the left edge. % This means that the `centre of rotation' is not fixed by |\rotatebox|, % but typically moves horizontally. We also need to find the image of @@ -2157,7 +2157,7 @@ % \end{macrocode} % \end{macro} % -% Restore Catcodes +% Restore catcodes. % \begin{macrocode} \Gin@codes \let\Gin@codes\relax diff --git a/Master/texmf-dist/source/latex/graphics/graphicx.dtx b/Master/texmf-dist/source/latex/graphics/graphicx.dtx index 8c200915859..92f1af1d396 100644 --- a/Master/texmf-dist/source/latex/graphics/graphicx.dtx +++ b/Master/texmf-dist/source/latex/graphics/graphicx.dtx @@ -2,7 +2,7 @@ % \iffalse % %% graphicx.dtx Copyright (C) 1994 David Carlisle Sebastian Rahtz -%% Copyright (C) 1995-2022 LaTeX Project +%% Copyright (C) 1995-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/Master/texmf-dist/source/latex/graphics/keyval.dtx b/Master/texmf-dist/source/latex/graphics/keyval.dtx index 9fce6267e06..02f9a15ec7c 100644 --- a/Master/texmf-dist/source/latex/graphics/keyval.dtx +++ b/Master/texmf-dist/source/latex/graphics/keyval.dtx @@ -1,7 +1,7 @@ % % \iffalse %% keyval.dtx Copyright (C) 1993 1994 1995 1997 1998 1999 David Carlisle -%% Copyright (C) 2000-2022 David Carlisle, LaTeX Project +%% Copyright (C) 2000-2024 David Carlisle, LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/Master/texmf-dist/source/latex/graphics/lscape.dtx b/Master/texmf-dist/source/latex/graphics/lscape.dtx index d173af6468a..eca5aa432bd 100644 --- a/Master/texmf-dist/source/latex/graphics/lscape.dtx +++ b/Master/texmf-dist/source/latex/graphics/lscape.dtx @@ -2,7 +2,7 @@ % \iffalse % %% lscape.dtx Copyright (C) 1994 1999-2000 David Carlisle -%% Copyright (C) 2000-2022 LaTeX Project +%% Copyright (C) 2000-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/Master/texmf-dist/source/latex/graphics/rotating.dtx b/Master/texmf-dist/source/latex/graphics/rotating.dtx index ac64086082a..bac5759956a 100644 --- a/Master/texmf-dist/source/latex/graphics/rotating.dtx +++ b/Master/texmf-dist/source/latex/graphics/rotating.dtx @@ -5,7 +5,7 @@ % File: rotating.dtx %% Copyright (C) 1995-1999 Sebastian Rahtz and Leonor Barroca %% Copyright (C) 2001-2003,2007-2009 Robin Fairbairns -%% Copyright (C) 2016-2022 LaTeX Project +%% Copyright (C) 2016-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. % diff --git a/Master/texmf-dist/source/latex/graphics/trig.dtx b/Master/texmf-dist/source/latex/graphics/trig.dtx index 4b673494aff..d2fa91f91f7 100644 --- a/Master/texmf-dist/source/latex/graphics/trig.dtx +++ b/Master/texmf-dist/source/latex/graphics/trig.dtx @@ -1,6 +1,6 @@ % \iffalse %% File: trig.dtx Copyright (C) 1993-1999 David Carlisle -%% Copyright (C) 2000-2022 LaTeX Project +%% Copyright (C) 2000-2024 LaTeX Project %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -19,7 +19,7 @@ % \ProvidesFile{trig.drv} % \fi % \ProvidesFile{trig.dtx} - [2021/08/11 v1.11 sin cos tan (DPC)] + [2023/12/02 v1.11 sin cos tan (DPC)] % % \iffalse % @@ -214,7 +214,7 @@ % \end{macro} % % \begin{macro}{\TG@reduce} -% Repeatedly use one of the the relations +% Repeatedly use one of the relations % $\sin(x)=\sin(180-x)=\sin(-180-x)$ to get $x$ in the range $-90 \leq % x\leq 90$. Then call |\TG@series|. % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx b/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx index b37ae6c9d79..a629d9c5515 100644 --- a/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % %% File: documentmetadata-support.dtx -% Copyright (C) 2021-2023 The LaTeX Project +% Copyright (C) 2021-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -18,8 +18,8 @@ % for those people who are interested or want to report an issue. % % \begin{macrocode} -\def\documentmetadatasupportversion{1.0f} -\def\documentmetadatasupportdate{2023-09-01} +\def\documentmetadatasupportversion{1.0h} +\def\documentmetadatasupportdate{2024-03-26} % \end{macrocode} % % @@ -84,8 +84,17 @@ % features developed as part of the multi-year ``Tagged PDF'' % project~\cite{blueprint}. % -% -% +% \section{The \cs{DocumentMetadata} command} +% +% \begin{function}{\DocumentMetadata} +% \begin{syntax} +% \cs{DocumentMetadata}\Arg{key-value list} +% \end{syntax} +% +% The command should be used as the first command in a document, before +% \cs{documentclass}. It takes a key-value argument. +% \end{function} + % \section{Currently supported key/values} % % @@ -116,7 +125,8 @@ % e.g., \texttt{lang=de-DE}. If not given the default value used is |en-US|. % % \item[\texttt{pdfstandard}] Choice key to set the pdf standard. -% Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u| and |A-4| are accepted as +% Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u|, |A-4|, |A-4E| +% and |A-4F| are accepted as % values. The casing is irrelevant, |a-1b| works too. % Note that using these % key doesn't mean that the document actually follows the standard. \LaTeX{} @@ -162,12 +172,12 @@ % \item[\texttt{phase-I}] % This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it % will load the tagpdf package. It will also activate tagging by issuing -% |\tagpdfsetup{activate,interwordspace}|. This phase +% |\tagpdfsetup{activate,activate/spaces}|. This phase % is frozen. % \item[\texttt{phase-II}] % It differs from \texttt{phase-I} only in one point: It will % additionally activate tagging of paragraphs with -% |\tagpdfsetup{paratagging}|. In the upcoming months it will +% |\tagpdfsetup{para/tagging}|. In the upcoming months it will % also enable automatic tagging of other basic document elements. % \item[\texttt{phase-III}] % This is the current development phase. @@ -179,7 +189,7 @@ % and it supports only a limited number of add-on packages. % \end{description} % -% The various testphase modules can also be loaded individually (and least in theory, +% The various testphase modules can also be loaded individually (at least in theory, % there can be hidden dependencies). If loaded like this, the tagpdf package is not % loaded and tagging is not activated! The list of modules will change over time. % \begin{description} @@ -213,8 +223,19 @@ % \item[\texttt{text}] This module adds tagging support to the \LaTeX{} logo and % to the \cs{emph} command. % This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{marginpar}] This module adds tagging support to the \cs{marginpar} +% command. This code is also loaded by the \texttt{phase-III} key. +% \item[\texttt{title}] This module add tagging support to the \cs{maketitle} +% command if a standard class is used. It also enhances the \cs{title} +% and \cs{author} commands to fill the XMP-metadata and set the window title. +% It is not compatible with packages and classes which redefine these commands +% too. The module is currently not loaded by any \texttt{phase} key. % \item[\texttt{math}] This adapts math for tagging. This is only a prototype. % The module is currently not loaded by any \texttt{phase} key. +% \item[\texttt{table}] This provides basic tagging for +% \texttt{tabular}, \texttt{longtable} and similar table environments. +% The module is currently not loaded by any \texttt{phase} key. Its use and +% restrictions is documented in \texttt{latex-lab-table.pdf}.% % \item[\texttt{firstaid}] This contains small adjustments to external packages. % The module is currently not loaded by any \texttt{phase} key. % \end{description} @@ -274,8 +295,28 @@ \ExplSyntaxOn\makeatletter % \end{macrocode} +% \subsection{Variables} +% These variable definitions are currently also done in ltdocinit. +% They can be removed from there once latex-lab has been updated to +% provide them too. +% \begin{variable}{\g_@@_firstaidoff_clist} +% A list to store the firstaid code which should be disabled +% \begin{macrocode} +\clist_if_exist:NF \g_@@_firstaidoff_clist + { \clist_new:N \g_@@_firstaidoff_clist } +% \end{macrocode} +% \end{variable} +% \begin{variable}{\g_@@_testphase_tl} +% a tl to store the testphase loading code so that we can load them at +% the end of the command. +% \begin{macrocode} +\tl_if_exist:NF \g_@@_testphase_tl + { \tl_new:N \g_@@_testphase_tl } +% \end{macrocode} +% \end{variable} - +% \subsection{\cs{DocumentMetadata}} +% % \begin{macro}{\DocumentMetadata} % % \cs{DocumentMetadata} should not be used after @@ -309,14 +350,35 @@ \file_input:n {l3backend-testphase-\c_sys_backend_str.def} \ExplSyntaxOff\makeatother % \end{macrocode} -% Set the default language (this requires that the backend has been loaded), -% process the rest of the keys, -% and setup the generic driver. +% +% Process the init keys and setup the generic driver. % \begin{macrocode} - \keys_set_filter:nnn { document / metadata } { init } { lang=en-US, #1 } + \keys_set_filter:nnn { document / metadata } { init } { #1 } \bool_if:NT \g_@@_active_bool { \PassOptionsToPackage{customdriver=hgeneric-testphase}{hyperref} +% \end{macrocode} +% Finally we setup the language default. +% This is done after the begindocument hook so that it can pick up settings +% from babel. If the Catalog dictionary already contains a lang value we do nothing, +% otherwise we use the value stored in \cs{BCPdata}, either the main language +% (if its exists) or the fall back language. +% Note: if babel is loaded without a language this gives the language \texttt{und}. +% \begin{macrocode} + \g@addto@macro\@kernel@after@begindocument + { + \pdfdict_get:nnN {g__pdf_Core/Catalog}{Lang}\l_@@_tmpa_tl + \quark_if_no_value:NT\l_@@_tmpa_tl + { + \tl_if_empty:eTF { \BCPdata{main.language} } + { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{language} } } + { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{main.language} } } + \msg_warning:nne { meta } { lang-missing }{ \l_@@_tmpb_tl } + \exp_last_unbraced:Ne + \AddToDocumentProperties{[document]{lang}{\l_@@_tmpb_tl}} + \pdfmanagement_add:nne {Catalog} {Lang}{(\l_@@_tmpb_tl)} + } + } } % \end{macrocode} % \cs{pdfmanagement_add:nnn} has collected values in this hook. @@ -348,15 +410,8 @@ % \end{macrocode} % \end{macro} - - - +%\subsection{\cs{DocumentMetadata} keys} % \begin{macrocode} -%FMi defined elsewhere -%FMi -%FMi \clist_new:N \g_@@_firstaidoff_clist -%FMi \tl_new:N \g_@@_testphase_tl -% UFi should the definition move to here? \keys_define:nn { document / metadata } { backend .choices:nn = @@ -388,7 +443,7 @@ % this uses internal command from pdfmeta, it should probably move there ... ,pdfstandard .code:n = { - \exp_args:Nnx + \exp_args:Nne \keys_set:nn {document / metadata} {_pdfstandard=\str_uppercase:n{#1}} } ,_pdfstandard .choices:nn = @@ -400,6 +455,30 @@ } \AddToDocumentProperties [document]{pdfstandard}{#1} } + ,_pdfstandard / A-4F .code:n = + { + \prop_if_exist:cTF { g__pdfmeta_standard_pdf/A-4F_prop } + { + \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4F_prop } + } + { + \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4_prop } + \prop_gput:Nnn \g__pdfmeta_standard_prop{conformance}{F} + } + \AddToDocumentProperties [document]{pdfstandard}{A-4F} + } + ,_pdfstandard / A-4E .code:n = + { + \prop_if_exist:cTF { g__pdfmeta_standard_pdf/A-4E_prop } + { + \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4E_prop } + } + { + \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4_prop } + \prop_gput:Nnn \g__pdfmeta_standard_prop{conformance}{E} + } + \AddToDocumentProperties [document]{pdfstandard}{A-4E} + } ,_pdfstandard / unknown .code:n = { \msg_warning:nnn{pdf}{unknown-standard}{#1} @@ -413,7 +492,7 @@ { \RequirePackage{tagpdf} \AddToDocumentProperties [document]{testphase/tagpdf}{loaded} - \tagpdfsetup{activate,paratagging,interwordspace} + \tagpdfsetup{activate,para/tagging,activate/spaces} \AddToDocumentProperties [document]{tagging}{active} \AddToDocumentProperties [document]{tagging/para}{active} \AddToDocumentProperties [document]{tagging/interwordspace}{active} @@ -450,7 +529,7 @@ package/tagpdf/after } { - \tagpdfsetup{paratagging-show} + \tagpdfsetup{debug/show=para} } } ,debug / log .code:n = @@ -460,7 +539,7 @@ package/tagpdf/after } { - \tagpdfsetup{log=#1} + \tagpdfsetup{debug/log=#1} } } ,debug / tagpdf .code:n = @@ -498,6 +577,11 @@ { LaTeX-lab~package~'#1'~not~found. } +\msg_new:nnn { meta } { lang-missing } + { + The~language~has~not~been~set~in~\token_to_str:N + \DocumentMetadata.\\Setting~it~to~'#1'~as~fallback. + } % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx index e1f95730fae..57e27067cbf 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx @@ -2,7 +2,7 @@ % %% File: latex-lab-amsmath.dtx % -% Copyright (C) 2022,2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -66,7 +66,7 @@ % \subsection{File declaration} % \begin{macrocode} \ProvidesFile{latex-lab-amsmath.ltx} - [2023-01-05 v0.1a amsmath adaptions] + [2024-02-12 v0.1b amsmath adaptions] % \end{macrocode} % \subsection{Tagpdf support} % To make the code independent from tagging being loaded and active @@ -90,7 +90,11 @@ \def\intertext##1{% \ifvmode\else\\\@empty\fi \noalign{% - \penalty\postdisplaypenalty\vskip\belowdisplayskip +% \end{macrocode} +% we have to flip the sign and use a negative \cs{belowdisplayskip} +% as we flipped the sign at the outside. +% \begin{macrocode} + \penalty\postdisplaypenalty\vskip-\belowdisplayskip \vbox{ % \end{macrocode} % Stop tagging when measuring: @@ -105,9 +109,13 @@ % \begin{macrocode} \tag_mc_end_push: % \end{macrocode} -% We are already in a par so we change now to Span: +% We are already in a par so we change now to text: +% \begin{macrocode} + \tagpdfsetup{para/tag=P}% +% \end{macrocode} +% TODO why \cs{tagpdfparaOn} needed? % \begin{macrocode} - \tagpdfsetup{paratag=Span}% + \tagpdfparaOn \noindent\ignorespaces##1\par % \end{macrocode} % Restart the MC @@ -119,6 +127,110 @@ } % \end{macrocode} % +% \subsection{\cs{text}} +% +% The \cs{text} command uses \cs{mathchoice} which \enquote{typesets} the argument +% four times. This makes it quite problematic for tagging. Without precautions +% structure objects would be created four times and would get MC-chunks as kids +% that doesn't really exist. amsmath contains a switch that allows to execute code +% only in the first (displaymath) branch, but that isn't usable here. At first because +% we don't know if the first branch creates the same structure as the one that is +% actually used. At second because the engines executes some commands like \cs{label} +% and \cs{pdfannot} only at shipout from the branch that really was used. So we would +% get structure data from one \cs{mathchoice}-branch and MC-labels and links from another +% one and that gets very messy. +% +% We therefore have to avoid that tagging is active in unused branches. In pdflatex it +% is not possible to detect the mathstyle before, so we use a label. With lualatex is +% is possible to redefine \cs{text} not to use \cs{mathchoice} +% +% \begin{macrocode} +\AddToHook{package/amstext/after} + { +% \end{macrocode} +% currently amsmath is loaded in a begindocument hook, so this +% test is fine. If amstext is loaded earlier (in the kernel), this needs perhaps a change. +% \begin{macrocode} + \tag_if_active:T + { + \sys_if_engine_luatex:TF + { + \def\text@#1{{% + \ifcase\mathstyle + \hbox{{#1}}\or + \hbox{{#1}}\or + \hbox{{#1}}\or + \hbox{{#1}}\or + \hbox{{\let\f@size\sf@size\selectfont#1}}\or + \hbox{{\let\f@size\sf@size\selectfont#1}}\or + \hbox{{\let\f@size\ssf@size\selectfont#1}}\or + \hbox{{\let\f@size\ssf@size\selectfont#1}}\or + \ERROR + \fi + \check@mathfonts + }} + } + { + \def\text@#1 + {{ + \int_gincr:N\g__math_mathchoice_int + \tag_stop: + \mathchoice + { + \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{0} + \textdef@\displaystyle\f@size{#1} + } + { + \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{2} + \textdef@\textstyle\f@size{\firstchoice@false #1} + } + { + \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{4} + \textdef@\textstyle\sf@size{\firstchoice@false #1} + } + { + \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{6} + \textdef@\textstyle \ssf@size{\firstchoice@false #1} + } + \check@mathfonts + }} + } + } + } +% \end{macrocode} +% +% \subsection{\cs{pmb}} +% \cs{pmb} prints is argument three times. For tagging we must mark +% two of occurences as artifact. +% For luatex the attributes in the box must be reset, for this +% we switch to expl3-boxes. +% \begin{macrocode} +\AddToHook{package/amsbsy/after} + { + \def\pmb@@@@#1#2#3{\leavevmode\hbox_set:Nn\l_@@_tmpa_box{xxx#3} + \dimen@-\box_wd:N\l_@@_tmpa_box + \kern-.5\ex@\box_use:N\l_@@_tmpa_box + \tag_mc_end:\tag_mc_begin:n{artifact} + \tag_mc_reset_box:N\l_@@_tmpa_box + \kern\dimen@\kern.25\ex@\raise.4\ex@\box_use:N\l_@@_tmpa_box + \kern\dimen@\kern.25\ex@\box_use_drop:N\l_@@_tmpa_box + \tag_mc_end:\tag_mc_begin:n{} + } + \def\pmb@#1#2{\hbox_set:Nn\l_@@_tmpa_box{$\m@th#1{#2}$} + \setboxz@h{$\m@th#1\mkern.5mu$}\pmbraise@\wdz@ + \binrel@{#2} + \dimen@-\box_wd:N\l_@@_tmpa_box + \binrel@@@@{ + \mkern-.8mu\box_use:N\l_@@_tmpa_box + \tag_mc_end:\tag_mc_begin:n{artifact} + \tag_mc_reset_box:N\l_@@_tmpa_box + \kern\dimen@\mkern.4mu\raise\pmbraise@\box_use:N\l_@@_tmpa_box + \kern\dimen@\mkern.4mu\box_use_drop:N\l_@@_tmpa_box + \tag_mc_end:\tag_mc_begin:n{} + } + } + } +% \end{macrocode} % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx index a467bf31582..e8ee192a7b2 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx @@ -16,8 +16,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabbibdate{2023-07-20} -\def\ltlabbibversion{0.81a} +\def\ltlabbibdate{2024-02-12} +\def\ltlabbibversion{0.81b} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -124,6 +124,17 @@ % but has to test if this anchor is already known. % \end{description} % +% \section{Provided or redefined commands} +% +% \begin{function}{\@extra@binfo,\@extra@b@citeb} +% +% These are taken from hyperref, they are for chapterbib compability (and also +% signal to chapterbib not to change the citation commands) +% \end{function} +% +% \begin{function}{\@bibitem,\@lbibitem} +% The internal item commands. +% \end{function} % % \section{Implementation} % \begin{macrocode} @@ -264,7 +275,7 @@ \AddToHookWithArguments{bibcite/before} { \tag_mc_end_push: - \exp_args:Nx\tagstructbegin{tag=Reference,ref=cite.#1\@extra@b@citeb} + \exp_args:Ne\tagstructbegin{tag=Reference,ref=cite.#1\@extra@b@citeb} \tagmcbegin{} } \AddToHookWithArguments{bibcite/after}[tag] @@ -318,7 +329,7 @@ { \leavevmode \tag_mc_end_push: - \exp_args:Nx\tag_struct_begin:n{tag=Reference,ref=cite.#1\@extra@b@citeb} + \exp_args:Ne\tag_struct_begin:n{tag=Reference,ref=cite.#1\@extra@b@citeb} \tag_mc_begin:n{} } \AddToHook{cmd/hyper@natlinkend/after} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx index e0a723ca87c..7d08b270d25 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-block.dtx (C) Copyright 2021-2023 LaTeX Project +%% File: latex-lab-block.dtx (C) Copyright 2021-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -9,10 +9,10 @@ % % https://www.latex-project.org/lppl.txt % -\def\ltlabblockdate{2023-09-01} -\def\ltlabblockversion{0.8h} +\def\ltlabblockdate{2024-03-23} +\def\ltlabblockversion{0.8n} %<*driver> -\documentclass{l3doc} +\documentclass[kernel]{l3doc} \usepackage{amstext} \EnableCrossrefs \CodelineIndex @@ -308,7 +308,7 @@ % \end{TemplateDescription} % % The maximum number of \xt{blockenv}s that can be nested into each -% other is is restricted by the \LaTeX{} counter +% other is restricted by the \LaTeX{} counter % \texttt{maxblocklevels} with a default value of \texttt{6}. If this % value is increased then it is necessary to provide additional % instances, e.g., \texttt{displayblock-7}, etc. Decreasing is, of @@ -646,11 +646,59 @@ % % \end{description} % +% \section{Debugging} +% +% \begin{function}{\DebugBlocksOn,\DebugBlocksOff, \block_debug_on:, \block_debug_off:} +% +% These commands enable/disable debugging messages. +% +% \end{function} % +% \section{New and redefined kernel command} +% +% \begin{function}{\@doendpe} +% The original \LaTeXe{} command is augmented to allow for tagging. +% \end{function} % +% \begin{function}{\legacyverbatimsetup,\legacylistsetupcode} +% \emph{to be documented} +% \end{function} +% +% \begin{function}{\@setupverbinvisiblespace} +% A counterpart definition to the kernel command \cs{@setupverbinvisiblespace}, +% needed as we need to handle real space chars in verbatim. +% \end{function} +% +% \begin{function}{endblockenv,\g_block_nesting_depth_int} +% \emph{to be documented} +% \end{function} +% +% \begin{function}{\newtheorem,\@thm,\@begintheorem} +% Redefined to make theorems tagging aware. +% \end{function} % +% \begin{function}{\item,\@itemlabel} +% The \cs{item} is redefined. +% \end{function} % -% +% \begin{function}{\c@maxblocklevels} +% A counter to increase or decrease the number of supported +% level. If increased, one needs to supply additional level instances. +% \end{function} +% +% \begin{function}{\begin} +% The \cs{begin} is slightly redefine to handle \cs{@doendpe} better. +% TODO: move to kernel +% \end{function} +% +% \begin{function}{\para_end:} +% TODO: consider name, document +% \end{function} +% +% \begin{function}{para/begin} +% The para/begin hook is enhanced to support list ends +% \end{function} +% % \end{documentation} % % \StopEventually{\setlength\IndexMin{200pt} \PrintIndex } @@ -674,10 +722,6 @@ blockenv implementation] % \end{macrocode} % -% We make use of templates: -% \begin{macrocode} -\RequirePackage{xtemplate} -% \end{macrocode} % Generell kernel changes, also loaded by the sec and toc code. % \begin{macrocode} \RequirePackage{latex-lab-kernel-changes} @@ -691,7 +735,7 @@ \tl_new:N \l_@@_item_align_tl \tl_new:N\l_@@_legacy_env_params_tl % \end{macrocode} - +% % \subsection{Handling \cs{par} after the end of the list} % % An empty line (or a \cs{par}) after a list has semantic meaning as @@ -767,11 +811,11 @@ % given use in the document. This section is devoted to template % interfaces, and the template code is covered later. % \begin{macrocode} -\DeclareObjectType{blockenv}{1} -\DeclareObjectType{block}{1} -\DeclareObjectType{para}{1} -\DeclareObjectType{list}{1} -\DeclareObjectType{item}{1} +\NewTemplateType{blockenv}{1} +\NewTemplateType{block}{1} +\NewTemplateType{para}{1} +\NewTemplateType{list}{1} +\NewTemplateType{item}{1} % \end{macrocode} % \end{objecttype} % @@ -854,7 +898,7 @@ item-instance : instance{item} = basic , item-skip : skip = \itemsep , item-penalty : integer = \UseName{@itempenalty} , - item-indent : length = 0pt , % was \itemindent + item-indent : length = \itemindent , label-width : length = \labelwidth , label-sep : length = \labelsep , legacy-support : boolean = false , @@ -893,8 +937,8 @@ % This section collects \pkg{expl3} commands that will be useful. % % \begin{macro}{\@@_skip_set_to_last:N,\@@_skip_remove_last:} -% Set a skiip register to the value of an immediately preceding -% skip or zero if there was none +% Set a skip register to the value of an immediately preceding +% skip or zero if there was none. % \begin{macrocode} \cs_new_protected:Npn \@@_skip_set_to_last:N #1 { \skip_set:Nn #1 { \tex_lastskip:D } @@ -907,12 +951,9 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\tl_if_novalue:nTF} -% % \begin{macrocode} \cs_generate_variant:Nn \tl_if_novalue:nTF { o } % \end{macrocode} -% \end{macro} % % % \subsubsection{Debugging} @@ -1342,14 +1383,14 @@ \@definecounter {#2} \IfNoValueTF {#4} { % @ynthm - \tl_gset:cx { the #2 } + \tl_gset:ce { the #2 } { \@thmcounter{#2} } } { % @xnthm \@newctr{#1}[#4] - \tl_gset:cx { the #2 } + \tl_gset:ce { the #2 } { \expandafter\noexpand\csname the#4\endcsname \@thmcountersep @@ -1802,7 +1843,7 @@ fixed-word-spaces = \l__par_fixed_word_spaces_bool , % name?? final-hyphen-demerits = \finalhyphendemerits , cr-cmd = \\ , - para-class = \l_tag_para_attr_class_tl , + para-class = \l__tag_para_attr_class_tl , } { \tl_if_empty:nF {#1} { \SetTemplateKeys{para}{std}{#1} } @@ -2260,6 +2301,9 @@ \exp_after:wN \use_ii:nn \l_@@_item_align_tl } } +% \end{macrocode} +% Add another box level to the label box: +% \begin{macrocode} \hbox_set:Nn \l_@@_one_label_box { \box_use_drop:N \l_@@_one_label_box } } @@ -2488,10 +2532,13 @@ { \@inmatherr \item % \end{macrocode} -% TODO: Test for being outside of a list needs updating! +% TODO: Check if test for being outside of a list is sensible % \begin{macrocode} - \tl_if_empty:oTF \@@_item_instance:n %%FMi? - { \msg_error:nnn { @@ } { item-in-nonlist } { \item[{#1}] } } + \cs_if_free:NTF \@@_item_instance:n + { + \@latex@error{Lonely~\string\item--perhaps~a~missing~ + list~environment}\@ehc + } { \legacy_if:nTF { @newlist } { \__kernel_list_item_begin: } @@ -2630,7 +2677,7 @@ % % \item Then open an new (inner) structure (by default % \texttt{Figure} but typically the one specified on the instance). -% \item At the end of the block close the the inner structure +% \item At the end of the block close the inner structure % (\texttt{Figure} or explicit one) % but leave the \texttt{text-unit} open to be either continued or closed due to a % following \cs{par}. @@ -3290,6 +3337,7 @@ \DeclareInstance{item}{description}{std} { label-format = \normalfont\bfseries #1 , + label-align = left } % \end{macrocode} % \end{instance} @@ -3303,10 +3351,10 @@ { \tagpdfsetup { - newattribute = {justify} {/O /Layout /TextAlign/Justify}, - newattribute = {center} {/O /Layout /TextAlign/Center}, - newattribute = {raggedright}{/O /Layout /TextAlign/Start}, - newattribute = {raggedleft} {/O /Layout /TextAlign/End}, + role/new-attribute = {justify} {/O /Layout /TextAlign/Justify}, + role/new-attribute = {center} {/O /Layout /TextAlign/Center}, + role/new-attribute = {raggedright}{/O /Layout /TextAlign/Start}, + role/new-attribute = {raggedleft} {/O /Layout /TextAlign/End}, } } % \end{macrocode} @@ -3389,9 +3437,7 @@ % % In this section we provide code to the various kernel hooks to support % the tagging of the different displayblock environments. -% -% -% +% % All of the following definitions should only be made if tagging % is active! % \begin{macrocode} @@ -3424,8 +3470,13 @@ { \int_compare:nNnT \l_@@_flattened_level_int < 2 { - \int_gincr:N \g__tag_para_main_begin_int - \tagstructbegin{tag=\l__tag_para_main_tag_tl} + \__tag_gincr_para_main_begin_int: + \tag_struct_begin:n + { + tag=\l__tag_para_main_tag_tl, + attribute-class=\l__tag_para_main_attr_class_tl, + } + \__tag_para_main_store_struct: } } } @@ -3445,7 +3496,7 @@ \cs_set:Npn \@@_beginpar_hmode:N #1 { \tag_mc_end: - \int_gincr:N \g__tag_para_end_int + \__tag_gincr_para_end_int: \@@_debug_typeout:n{increment~ /P \on@line } \bool_if:NT \l__tag_para_show_bool { \tag_mc_begin:n{artifact} @@ -3492,7 +3543,7 @@ { \@@_debug_typeout:n{Structure-end~ \l__tag_para_main_tag_tl\space after~ displayblock \on@line } - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \tag_struct_end: %text-unit } } @@ -3551,16 +3602,21 @@ { \bool_if:NF \l__tag_para_flattened_bool { - \int_gincr:N \g__tag_para_main_begin_int - \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} + \__tag_gincr_para_main_begin_int: + \tag_struct_begin:n + { + tag=\l__tag_para_main_tag_tl, + attribute-class=\l__tag_para_main_attr_class_tl, + } + \__tag_para_main_store_struct: } } - \int_gincr:N \g__tag_para_begin_int + \__tag_gincr_para_begin_int: \@@_debug_typeout:n{increment~ P \on@line } \tag_struct_begin:n { tag=\l__tag_para_tag_tl - ,attribute-class=\l_tag_para_attr_class_tl + ,attribute-class=\l__tag_para_attr_class_tl } \__tag_check_para_begin_show:nn {green}{#1} \tag_mc_begin:n {} @@ -3572,15 +3628,20 @@ \cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 { \bool_if:NF \l__tag_para_flattened_bool { - \int_gincr:N \g__tag_para_main_begin_int - \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl} + \__tag_gincr_para_main_begin_int: + \tag_struct_begin:n + { + tag=\l__tag_para_main_tag_tl, + attribute-class=\l__tag_para_main_attr_class_tl, + } + \__tag_para_main_store_struct: } - \int_gincr:N \g__tag_para_begin_int + \__tag_gincr_para_begin_int: \@@_debug_typeout:n{increment~ P \on@line } \tag_struct_begin:n { tag=\l__tag_para_tag_tl - ,attribute-class=\l_tag_para_attr_class_tl + ,attribute-class=\l__tag_para_attr_class_tl } \__tag_check_para_begin_show:nn {green}{#1} \tag_mc_begin:n {} @@ -3594,14 +3655,14 @@ { \bool_if:NT \l__tag_para_bool { - \int_gincr:N \g__tag_para_end_int + \__tag_gincr_para_end_int: \@@_debug_typeout:n{increment~ /P \on@line } \tag_mc_end: \__tag_check_para_end_show:nn {red}{} \tag_struct_end: \bool_if:NF \l__tag_para_flattened_bool { - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \tag_struct_end: } } @@ -3657,7 +3718,7 @@ \DeclareRobustCommand*\begin[1]{% \UseHook{env/#1/before}% \@ifundefined{#1}% - {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}% + {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}% {\def\reserved@a{\def\@currenvir{#1}% \edef\@currenvline{\on@line}% \@execute@begin@hook{#1}% @@ -3680,7 +3741,7 @@ { \bool_if:NF \l__tag_para_flattened_bool { - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \tag_struct_end: } \@endpefalse @@ -3722,7 +3783,7 @@ \@@_debug_typeout:n{block-end \on@line} \legacy_if:nT { @endpe } { - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \@@_debug_typeout:n{close~ /text-unit \on@line} \tagstructend } @@ -3752,11 +3813,17 @@ { \tagpdfsetup { + role/new-attribute = {itemize}{/O /List /ListNumbering/Unordered}, + role/new-attribute = {enumerate}{/O /List /ListNumbering/Ordered}, + role/new-attribute = {description}{/O /List /ListNumbering/Description}, +% \end{macrocode} +% Initially, we had \texttt{/None} for the basic \env{list} +% environment, but that is not allowed in PDF/UA-2 if the list +% contains any Lbl tags. So now we default to +% \texttt{Unordered}. +% \begin{macrocode} % default if unknown - newattribute = {list}{/O /List /ListNumbering/None}, - newattribute = {itemize}{/O /List /ListNumbering/Unordered}, - newattribute = {enumerate}{/O /List /ListNumbering/Ordered}, - newattribute = {description}{/O /List /ListNumbering/Description}, + role/new-attribute = {list}{/O /List /ListNumbering/Unordered}, } } % \end{macrocode} @@ -3792,7 +3859,7 @@ \cs_set:Npn \__kernel_list_label_begin: { % % FMi: this needs a different logic to decide when to make the label -% an artifact (after cleaning up the the \item code ), therefore +% an artifact (after cleaning up the \item code ), therefore % disabled for now % \tl_if_empty:oTF \@itemlabel % { @@ -3835,7 +3902,7 @@ \cs_set:Npn \@@_list_item_end: { \legacy_if:nT { @endpe } { - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \tagstructend % text-unit % \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on@line } } @@ -3854,7 +3921,7 @@ \cs_set:Npn \@@_list_end: { \legacy_if:nT { @endpe } { - \int_gincr:N \g__tag_para_main_end_int + \__tag_gincr_para_main_end_int: \tagstructend % text-unit \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on@line } } diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx index e2ee78b2fff..ce0d46f8155 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-firstaid.dtx (C) Copyright 2023 LaTeX Project +%% File: latex-lab-firstaid.dtx (C) Copyright 2023-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -16,8 +16,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabfirstaiddate{2023-07-20} -\def\ltlabfirstaidversion{0.85a} +\def\ltlabfirstaiddate{2024-05-25} +\def\ltlabfirstaidversion{0.85d} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -55,6 +55,7 @@ % patches once the packages have been updated. % \section{Implementation} +% % \begin{macrocode} %<*package> %<@@=tag> @@ -64,8 +65,153 @@ \ltlabfirstaiddate\space v\ltlabfirstaiddate\space Temporary patches to external packages needed for the tagging project] % \end{macrocode} +% \begin{macro}{\FirstAidNeededT} +% This is a very simple help to ensure that we only apply first aid +% to an unmodified package or class. It only works in the case the +% file has already been loaded and the csname \cs{ver@\#1.\#2} got +% defined (holding the current date, version, and short description +% info). We then compare its content to a frozen string and make +% the modification \verb=#3= only if both agree. If they differ we +% assume that the package/class in question got updated by its +% maintainer. +% \begin{macrocode} +\ExplSyntaxOn +\providecommand\FirstAidNeededT[3]{ + \exp_args:Ncx\str_if_eq:onF{ver@#1.#2}{#3} + { \typeout{==>~ First~ Aid~ for~ #1.#2~ no~ longer~ applied!^^J + \@spaces Expected:^^J + \@spaces\@spaces #3^^J + \@spaces but~ found:^^J + \@spaces\@spaces \use:c{ver@#1.#2}^^J + \@spaces so~ I'm~ assuming~ it~ got~ fixed. + } } + \exp_args:Ncx\str_if_eq:onT{ver@#1.#2}{#3} +} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% \subsection{ams classes} +% The amsart and amsbook classes do not use \cs{@author} to store the author list +% but a command \cs{authors}. To be able to nevertheless use the authors in the +% xmp-metadata we map \cs{@author} to this new command. +% +% \begin{macrocode} +\AddToHook{class/amsart/after} + {\def\@author{\authors}} +\AddToHook{class/amsbook/after} + {\def\@author{\authors}} +% \end{macrocode} +% +% +% +% \subsection{verse} +% +% The \pkg{verse} package has its own definition of the +% \env{verse} environment, which would tag correctly, except that +% it is overwritten by the block code in the hook +% \texttt{begindocument/before}. So the simplest way to make +% tagging work is to reinstall the package version afterwards, +% which is what we are doing here. +% \begin{macrocode} +\AddToHook{package/verse/after}[latex-lab-firstaid]{% + \FirstAidNeededT{verse}{sty}{2014/05/10 v2.4b verse typesetting}% + {% + \AtBeginDocument{% + \renewenvironment{verse}[1][\linewidth]{% + \stepcounter{verse@envctr}% + \setcounter{poemline}{0}\refstepcounter{poemline}% + \setcounter{vslineno}{1}% + \let\\=\@vscentercr + \list{}{\itemsep \z@ + \itemindent -\vindent + \listparindent\itemindent + \parsep \stanzaskip + \ifdim #1 < \linewidth + \rightmargin \z@ + \setlength{\leftmargin}{\linewidth}% + \addtolength{\leftmargin}{-#1}% + \addtolength{\leftmargin}{-0.5\leftmargin}% + \else + \rightmargin \leftmargin + \fi + \addtolength{\leftmargin}{\vindent}}% + \item[]% + }% + {\endlist}% + }% + }% +} +% \end{macrocode} +% Of course, this means that the +% optional argument of the environment then only accepts a length +% value and not any more a key value list for altering the +% environment settings. +% +% A more elabroate version could be something like this that allows +% key/val and legacy interface. Or one could extend the list +% template to support a \texttt{list-width} key. +%\begin{verbatim} +% \ExplSyntaxOn +% \cs_new_protected:Npn \ExtractAndDropKey #1#2#3#4#5 { +% \tl_set_eq:NN #4 \c_novalue_tl % or empty? +% \keys_define:nn { #1 } { #2 .code:n = \tl_set:Nn #4{##1} } +% \keys_set_known:nnN { #1 } { #3 } #5 +% } +% \ExplSyntaxOff +% +% % Change the env definition for verse matching verse.sty +% % This keeps the verse.sty interface as it is and only adjusts the +% % main environment to use the basic list env with the verse.sty +% % specific settings. +% \makeatletter +% +% \AddToHook{package/verse/after}{% +% \AtBeginDocument{% +% \RenewDocumentEnvironment{verse}{={verse-width}!O{\linewidth}}% +% {% +% \stepcounter{verse@envctr}% +% \setcounter{poemline}{0}\refstepcounter{poemline}% +% \setcounter{vslineno}{1}% +% \let\\=\@vscentercr +% % +% \ExtractAndDropKey{verse}{verse-width}{#1}\@vswidth\@vsremainingkvlist +% % If other keys have been specified but not verse-width we have no +% % default for \@vswidth and need to set it again +% \ExpandArgs{o}\IfNoValueT \@vswidth +% {\def\@vswidth{\linewidth}}% +% % +% % This is a bit ugly but we can't stick \cs{@vsremainingkvlist} into +% % the instance argument as keys are expected to be visible on +% % top-level not hidden inside a macro. The alternative is to push +% % in \verb=#1= but then the key/value \verb/verse-width=.../ is +% % passed into the instance which is not known there (not harmful as +% % it will get ignored but noticeably more and unnecessary +% % processing). +% % +% \def\next##1{% +% \UseInstance{blockenv}{list}% +% {% +% item-indent =-\vindent,% +% parindent =-\vindent,% +% par-skip =\stanzaskip,% +% item-skip =0pt,% +% leftmargin = (\linewidth-\@vswidth)/2+\vindent,% +% rightmargin = \ifdim\@vswidth<\linewidth 0pt +% \else (\linewidth-\@vswidth)/2\fi,% +% ##1% +% }}% +% \ExpandArgs{o}\next\@vsremainingkvlist +% \item\relax +% }{\endblockenv}% +% }% +% } +% \makeatother +%\end{verbatim} +% +% % \subsection{blindtext} +% % The blindtext package generates lists with nested \cs{loop} command. % The inner loop introduces a group around the list which error when lists are tagged % as \cs{@doendpe} is lost. @@ -106,7 +252,10 @@ }% } % \end{macrocode} +% +% % \subsection{cleveref} +% % The cleveref package redefines \cs{@makefntext} and this means that the patches in % the new footnote code fails. We use a hook instead % \begin{macrocode} @@ -130,9 +279,48 @@ }% } % \end{macrocode} +% +% \subsection{booktabs} +% In some cases booktabs inserts a +% \cs{multispan} into the table (through the commands \cs{@cmidruleb} +% and \cs{@cmidrulea} and this then errors +% with the tagging code. +% This affects both tabular and longtable +% (but longtable more as booktabs handles lines in longtable differently). +% See also issue \url{https://github.com/latex3/tagging-project/issues/69} +% +% +\ExplSyntaxOn +\AddToHook{package/booktabs/after} + { + \def\@cmidrulea{ + \multispan\@cmidla + &\multispan\@cmidlb + \unskip\hskip\cmrkern@l + { + \tag_mc_begin:n{artifact} + \CT@arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@} + \hskip\cmrkern@r + \tag_mc_end: \int_gdecr:N \g__tbl_row_int + \cr} + + \def\@cmidruleb{% + \multispan\@cmidlb + \unskip\hskip \cmrkern@l% + { + \tag_mc_begin:n{artifact} + \CT@arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@} + \hskip\cmrkern@r + \tag_mc_end: \int_gdecr:N \g__tbl_row_int + \cr} + } +\ExplSyntaxOff +% % \begin{macrocode} % % \end{macrocode} +% +% % \begin{macrocode} %<*latex-lab> \ProvidesFile{firstaid-latex-lab-testphase.ltx} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx index 3bd34836008..a8171337133 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx @@ -16,8 +16,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabfloatdate{2023-07-20} -\def\ltlabfloatversion{0.81a} +\def\ltlabfloatdate{2024-03-23} +\def\ltlabfloatversion{0.81e} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -86,8 +86,8 @@ % In PDF~2.0 there is the suitable \texttt{Aside} tag which hopefully will % be handled correctly regarding the reading order once processor actually support % PDF~2.0. But in PDF~1.7 we rolemap it to \texttt{Note} and this doesn't lead to -% a good reading order. The code therefore collect the float structures and moves -% them to a \texttt{Sect} the end of the document or the chapter +% a good reading order. The code therefore collects the float structures and moves +% them to a \texttt{Sect} at the end of the document or the chapter % (H-floats once they are handled will not be moved). % % To fulfill the requirement that a \texttt{Caption} should be at the begin or end, we always @@ -106,6 +106,8 @@ % % The code add two keys for the \cs{tagtool} command % +% +% \begin{function}{flush-floats,split-float} % \begin{description} % \item[flush-floats] This will flush out the collected floats sofar (currently % table and figure. The value is a sectioning level, e.g. \texttt{section} or \texttt{chapter}, @@ -117,9 +119,19 @@ % \item[split-float] This can be used inside a float if there are two captions. % It will only work reasonably well if the content of the float parts are in a sensible order % and can be separated by this command. More complex setups with tabulars will need more -% thoughts +% thoughts. +% \end{description} +% \end{function} +% +% \section{Kernel commands} +% \begin{function}{\@current@float@struct} +% This variable holds the structure number of current float structure. +% \end{function} % -% \end{description} +% \begin{function}{\@makecaption} +% \cs{@makecaption} is defined by the classes so we overwrite it for now +% at begin document. +% \end{function} % % % \begin{macrocode} @@ -182,7 +194,7 @@ \seq_map_inline:Nn\g_@@_float_types_seq { \tag_struct_begin:n{tag=##1s,stash} - \prop_gput:Nnx\g_@@_float_sect_prop {##1-struct}{\int_use:N\c@g__tag_struct_abs_int} + \prop_gput:Nne\g_@@_float_sect_prop {##1-struct}{\int_use:N\c@g__tag_struct_abs_int} \tag_struct_end: } } @@ -239,6 +251,7 @@ {\par\__tag_sec_end:n{-10}\@@_float_stop_sect:} \DeclareHookRule{tagpdf/finish/before}{latex-lab/float}{before}{tagpdf} % \end{macrocode} +% % \subsection{Splitting floats} % \begin{macro}{split-float} % TODO: check if the target affect spacing!! @@ -249,7 +262,7 @@ { \@@_float_end: \@@_float_begin: - \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int} + \MakeLinkTarget*{floatstructure.\int_use:N\c@g__tag_struct_abs_int} } } % \end{macrocode} @@ -290,12 +303,12 @@ { \exp_args:Ne \tag_struct_begin:n{tag=float,parent=0\prop_item:No\g_@@_float_sect_prop{\@captype-struct}}% - \prop_gput:Nxx \g_@@_float_sect_prop {\@captype-used}{true} + \prop_gput:Nee \g_@@_float_sect_prop {\@captype-used}{true} } { \tag_struct_begin:n{tag=float} } - \tl_set:Nx\@current@float@struct{\tag_get:n{struct_num}}% + \tl_set:Ne\@current@float@struct{\tag_get:n{struct_num}}% \typeout{Float structure: \@current@float@struct} } @@ -324,7 +337,7 @@ % \end{macrocode} % If the float is in hmode we have to interrupt the P % \begin{macrocode} - \@nameuse{@@_float_stoppar:} %<---end P + \@nameuse{@@_float_stop_par:}% <---end P \@floatpenalty -\@Mii \else \@floatpenalty-\@Miii @@ -381,7 +394,7 @@ % \end{macrocode} % We add a target for links. TODO: check that it doesn't affect spacing!! % \begin{macrocode} - \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int}% + \MakeLinkTarget*{floatstructure.\number\value{g__tag_struct_abs_int}}% }% % \end{macrocode} % The end code of the float ... @@ -400,7 +413,7 @@ \penalty\@floatpenalty \else \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack - \@nameuse{@@_float_start_par:} %restart P safe here?? + \@nameuse{@@_float_start_par:}% restart P safe here?? \fi \fi } @@ -423,7 +436,7 @@ \penalty\@floatpenalty \else \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack - \@nameuse{@@_float_start_par:} %restart P safe here?? + \@nameuse{@@_float_start_par:}% restart P safe here?? \fi \fi \else @@ -446,10 +459,24 @@ \let\@kernel@refstepcounter\refstepcounter %as long it is not in the kernel \def\caption{% \ifx\@captype\@undefined - \@latex@error{\noexpand\caption outside float}\@ehd + \@latex@error{\noexpand\caption\c_space_tl outside~float}\@ehd \expandafter\@gobble - \else - \@kernel@refstepcounter\@captype + \else +% \end{macrocode} +% if a caption is used outside a float no +% target has been set and \cs{@current@float@struct} is empty +% \begin{macrocode} + \tl_if_empty:NTF\@current@float@struct + { + \refstepcounter\@captype + } + { + \@kernel@refstepcounter\@captype +% \end{macrocode} +% we need to reset the target for \cs{addcontentsline}. +% \begin{macrocode} + \xdef\@currentHref{floatstructure.\@current@float@struct}% + } \expandafter\@firstofone \fi {\@dblarg{\@caption\@captype}}% @@ -471,7 +498,6 @@ { \long\def\@makecaption#1#2{% \vskip\abovecaptionskip - \xdef\@currentHref{tagstructure.\@current@float@struct}% % \end{macrocode} % we don't want tagging when storing the caption for the singleline check % \begin{macrocode} @@ -482,12 +508,21 @@ % we stop paratagging. TODO: check % \begin{macrocode} \tagtool{para=false} - \tag_struct_begin:n{tag=Caption,parent=\@current@float@struct} +% \end{macrocode} +% if caption is used outside a float there is perhaps no number, then we use +% the parent structure and hope ... +% \begin{macrocode} + \tl_if_empty:NT \@current@float@struct + { \tl_set:Ne \@current@float@struct {\tag_get:n{struct_num}} } + \tag_struct_begin:n{tag=Caption,parent=\@current@float@struct} % \end{macrocode} % move the caption to the begin of the float structure: % \begin{macrocode} - \seq_gpop_right:cN {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl - \seq_gput_left:cV {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl + \tag_if_active:T + { + \seq_gpop_right:cN {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl + \seq_gput_left:cV {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl + } \ifdim \wd\@tempboxa >\hsize \tag_struct_begin:n{tag=Lbl} \tag_mc_begin:n{} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx index 2389906c5ac..a3d044ab87d 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % %% File: latex-lab-footnotes.dtx -% Copyright (C) 2022-2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,8 +17,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabfootnotedate{2023-09-04} -\def\ltlabfootnoteversion{0.8c} +\def\ltlabfootnotedate{2024-03-12} +\def\ltlabfootnoteversion{0.8d} %<*driver> \documentclass{l3doc} @@ -454,6 +454,14 @@ % option. % \end{itemize} % +% \subsection{Debugging sockets and hooks} +% +% For some rudimentary debugging we currently have \cs{DebugFNotesOn} +% (and \cs{DebugFNotesOff}). At the moment \cs{DebugFNotesOn} only +% shows the current settings for hooks and sockets related to the +% footnote code and then +% automatically turns itself off again. +% % % \section{Tagging and hyperlinking support} % @@ -978,13 +986,22 @@ % \end{hookdecl} % % \subsection{Debugging code} -% the debugging code is just temporary +% The debugging code is just temporary % -% For now we have debugging turned on by default % \begin{macrocode} \bool_new:N \g_fnote_debug_bool -\bool_gset_true:N \g_fnote_debug_bool % \end{macrocode} + +% \begin{macro}{\DebugFNotesOn,\DebugFNotesOff} +% +% \begin{macrocode} +\cs_new_protected:Npn \DebugFNotesOn { \bool_gset_true:N \g_fnote_debug_bool } +\cs_new_protected:Npn \DebugFNotesOff { \bool_gset_false:N \g_fnote_debug_bool } +% \end{macrocode} +% \end{macro} +% +% +% % We log the hooks in the footnote mark command, but only once % \begin{macrocode} \cs_new_protected:Npn \@@_debug_footnotemark: @@ -1485,10 +1502,18 @@ \tl_if_in:NnTF \l_@@_patch_tl { \hb@xt@ } { \cs_set_eq:NN \@@_tmp:w \@@_patch_hb@xt@:w } { - \tl_if_in:NnTF \l_@@_patch_tl { \@makefnmark } - { \cs_set_eq:NN \@@_tmp:w \@@_patch_@makefnmark:w } - { \ERROR - \cs_set_eq:NN \@@_tmp:w \exp_stop_f: } +% \end{macrocode} +% Some styles/classes use \verb=\makebox[...][...]= instead of \cs{hb@xt@} +% so try to patch those too. +% \begin{macrocode} + \tl_if_in:NnTF \l_@@_patch_tl { \makebox } + { \cs_set_eq:NN \@@_tmp:w \@@_patch_makebox:w } + { + \tl_if_in:NnTF \l_@@_patch_tl { \@makefnmark } + { \cs_set_eq:NN \@@_tmp:w \@@_patch_@makefnmark:w } + { \ERROR + \cs_set_eq:NN \@@_tmp:w \exp_stop_f: } + } } } \tl_set:Nf \l_@@_patch_tl @@ -1512,6 +1537,17 @@ % \begin{macrocode} \cs_new:Npn \@@_patch_hb@xt@:w #1 \hb@xt@ #2 # { \exp_stop_f: #1 \@makefntext@processX { \hb@xt@ #2 } } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \@@_patch_makebox:w #1 \makebox #2 # + { \exp_stop_f: #1 \@makefntext@processX { \makebox #2 } } +% \end{macrocode} +% +% If the definition contains neither \cs{hbox}, \cs{hb@xt@} nor \cs{makebox}, +% we see if it contains \cs{@makefnmark} and if so put the socket +% before that. +% \begin{macrocode} \cs_new:Npn \@@_patch_@makefnmark:w #1 \@makefnmark { \exp_stop_f: #1 \@makefntext@processX { \use:n } { \@makefnmark } } % \end{macrocode} @@ -1539,7 +1575,12 @@ \cs_set_eq:NN \@makefntext \fnote_makefntext:n } { - \@@_patch: +% \end{macrocode} +% If \cs{@makefntext} contains the definition from \pkg{footmisc} +% we do nothing, otherwise we try to patch. +% \begin{macrocode} + \cs_if_eq:NNF \@makefntext \footmisc@hang@makefntext + { \@@_patch: } } } @@ -2421,8 +2462,9 @@ \else \ifFN@hangfoot - \long\def\@makefntext#1{% + \long\def\footmisc@hang@makefntext#1{% \bgroup + \SuspendTagging{footmisc}% \setbox\@tempboxa\hbox{% \ifdim\footnotemargin>\z@ \hb@xt@\footnotemargin{\@makefnmark\hss}% @@ -2437,14 +2479,33 @@ \parshape \@ne \leftmargin \linewidth \footnotesize \@setpar{{\@@par}}% + \ResumeTagging{footmisc}% \leavevmode - \llap{\box\@tempboxa}% +% \end{macrocode} +% Typesetting the mark twice means that one can't have any material +% inside that gets unhappy in that case. Tha shouldn't be a +% problem, but perhaps we have to come up with a more elaborate +% solution in the end. +% \begin{macrocode} + \UseSocket{tagsupport/fntext/mark}% + {\llap{% + \ifdim\footnotemargin>\z@ + \hb@xt@\footnotemargin{\@makefnmark\hss}% + \else + \@makefnmark + \fi + }}% \parskip\hangfootparskip\relax \parindent\hangfootparindent\relax \footnotelayout#1% \par \egroup } +% \end{macrocode} +% Defined in a roundabout way so that we can test for it when +% patching classes that are not updated. +% \begin{macrocode} + \let \@makefntext \footmisc@hang@makefntext \else @@ -2723,9 +2784,8 @@ \@footnotemark } % \end{macrocode} -% TEMP PATCHES FOR TESTING +% % \begin{macrocode} - \endinput % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx index 158b0d2a9c4..5ea4a2db9c7 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-graphic.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-graphic.dtx (C) Copyright 2022-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -15,8 +15,8 @@ % https://github.com/latex3/latex2e/required/latex-lab % % for those people who are interested or want to report an issue. -\def\ltlabgraphicdate{2023-10-13} -\def\ltlabgraphicversion{0.80b} +\def\ltlabgraphicdate{2024-03-13} +\def\ltlabgraphicversion{0.80d} % %<*driver> \documentclass{l3doc} @@ -184,7 +184,10 @@ \RequirePackage{l3opacity} % \end{macrocode} % -% +% Needed during switch to e-type: +% \begin{macrocode} +\cs_generate_variant:Nn \@@_prop_gput:Nnn {cne} +% \end{macrocode} % \begin{macro}{\@@_graphic_savepos:n} % this is the command which stores the position. Similar to % zref-savepos it uses two savepos commands @@ -323,7 +326,7 @@ \msg_new:nnn {tag}{alt-text-missing} { Alternative~text~for~graphic~is~missing.\\ - Using~'#1'~instead + Using~the~file~name~'#1'~instead. } \cs_new_protected:Npn\Gin@tag@struct@begin { @@ -449,8 +452,9 @@ % \end{macrocode} % and here the tagging stops. % \begin{macrocode} + \fi \Gin@tag@struct@end %new - \fi} + } } % \end{macrocode} % @@ -894,7 +898,7 @@ % The structure and the mc must be open earlier, before the \cs{setbox} (at least % for luatex it has to). TODO: think about interface if more attributes are needed. % \begin{macrocode} - \@@_prop_gput:cnx + \@@_prop_gput:cne { g_@@_struct_\int_eval:n {\c@g_@@_struct_abs_int}_prop } { A } { @@ -970,7 +974,7 @@ {red} {\int_use:N\g_@@_graphic_int} } - \@@_prop_gput:cnx + \@@_prop_gput:cne { g_@@_struct_\int_eval:n {\c@g_@@_struct_abs_int}_prop } { A } { diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx new file mode 100644 index 00000000000..ca79d8a67fa --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx @@ -0,0 +1,259 @@ +% \iffalse meta-comment +% +%% File: latex-lab-marginpar.dtx +%% +% Copyright (C) 2024 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% 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 +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +\def\ltlabmarginpardate{2024-02-12} +\def\ltlabmarginparversion{0.85b} + +%<*driver> +\documentclass[kernel]{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-marginpar.dtx} +\end{document} +% +% +% \fi +% +% \title{The \textsf{latex-lab-marginpar} package\\ +% Changes related to the tagging of margin notes} +% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} +% \date{v\ltlabmarginparversion\ \ltlabmarginpardate} +% +% \maketitle +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% \begin{abstract} +% \end{abstract} +% +% \section{Introduction} +% +% This module contains changes to improve the tagging (in the standard classes) of +% margin notes created with the \cs{marginpar} command. +% +% Such margin notes are rather small but nevertheless tagging is not trivial and poses +% a number of interesting problems both regarding the structure and the implementation. +% +% \subsection{Structure} +% \cs{marginpar} creates small boxes in the margin of a page. +% While they are technically floats they also typically +% relate to the paragraph beside them, so their structure element should be placed near +% such a paragraph. +% +% They can be tagged either as artifacts (if they are merely distracting decoration), +% as small headings before the paragraph, or as |Aside|. Unlike the PDF 1.7 fallback |Note| +% the structure |Aside| is not allowed inside |P|, +% so if |Aside| is used, it must be placed before or after the current |P| in the surounding |text-unit|, +% or it must split the |P|. Splitting is probably not so good as +% |\marginpar| is often used somewhere in the middle of sentence. +% The best default is probably to use |Aside|, find the parent |text-unit| and add it there. +% +% \subsection{Implementation} +% +% |marginpar| has an optional argument which allows to define a different content +% on left/right margins for odd/even pages (depending on twoside and \cs{reversemarginpar}). +% +% The current implementation stores *both* arguments in boxes and +% decides in the output routine which +% one to use. This is quite problematic for tagging, as the unused box produces +% structure objects, literals, labels, MCID numbers, +% and perhaps OBJR-objects from links +% which must be later thrown away again (or are thrown away by the engine). +% While it is theoretically not impossible to create +% both boxes while taging is active but to keep everything on hold and insert +% the real structure only when the box is used it is in practice quite difficult, +% slow and error prone. +% +% There are a number of options to avoid this hassle. +% +% \begin{description} +% \item[Minimal tagging] One option is to disable tagging when the boxes +% are built and when the box is used to surround them with a simple Aside. +% +% \begin{description} +% \item[Pro:] easy to implement +% \item[Contra:] +% Content that perhaps needed tagging (|\LaTeX| logo with /ActualText, images, links) is not tagged. +% \end{description} +% +% \item[Remaking the box] +% Tagging is deactivated when the boxes are created. +% The arguments are stored and when the box should be used in the output routine +% (and when it is known which one will be used) the box is (re)created, now with proper tagging. +% +% Contra: The content can change e.g. if it uses counters or macros that are redefine later before the +% output routine is called. As tagging is done later, it is not trivial to insert the +% |Aside| in the right place in the paragraph structure. +% +% \item[Two pass compilation] +% A label is used to detect which argument/boxed is used and +% tagging is activated only for this one. +% +% Contra: costs a |label| and requires a two pass compilation (which is needed anyway). +% This should be ok. |\marginnote| uses a label too, and the same +% label could also be used to resolve problems if a margin note +% moves to a new page (and so replace the mparhack package). +% \end{description} +% +% The last option seems the best and is therefore implemented. +% +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +%<@@=tag> +% \end{macrocode} +% \begin{macrocode} +\ProvidesExplPackage {latex-lab-testphase-marginpar} {\ltlabmarginpardate} {\ltlabmarginparversion} + {Changes related to the tagging of the margin notes} +% \end{macrocode} +% \subsection{Variables} +% We need a variable to make the label unique. +% Todo: Not sure about the name. +% \begin{macro}{\g__kernel_marginpar_int} +% \begin{macrocode} +\int_new:N \g__kernel_marginpar_int +% \end{macrocode} +% \end{macro} +% +% \subsection{Tagging sockets} +% +% \begin{socketdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end} +% \begin{macrocode} +\socket_new:nn {tagsupport/marginpar/begin}{0} +\socket_new:nn {tagsupport/marginpar/end}{0} +% \end{macrocode} +% \end{socketdecl} +% \begin{plugdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end} +% \begin{macrocode} +\socket_new_plug:nnn {tagsupport/marginpar/begin}{default} + { + \if_mode_horizontal: + \tag_mc_end: + \tag_struct_begin:n{tag=Aside,parent=\g__tag_para_main_struct_tl}% + \else: + \tag_struct_begin:n{tag=Aside}% + \fi: + } +\socket_new_plug:nnn {tagsupport/marginpar/end}{default} + { + \tag_struct_end: + \if_mode_horizontal: \tag_mc_begin:n{} \fi: + } +\socket_assign_plug:nn {tagsupport/marginpar/begin}{default} +\socket_assign_plug:nn {tagsupport/marginpar/end}{default} +% \end{macrocode} +% \end{plugdecl} + +% \subsection{Kernel command changes} +% \begin{macro}{\@savemarbox } +% We add sockets that add a tagging structure Aside: +% \begin{macrocode} +\long\def \@savemarbox #1#2{% + \UseTaggingSocket{marginpar/begin} + \global\setbox #1% + \color@vbox + \vtop{% + \hsize\marginparwidth + \@parboxrestore + \@marginparreset + #2\par + \@minipagefalse + \outer@nobreak + }% + \color@endbox + \UseTaggingSocket{marginpar/end} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ympar} +% We must avoid that \cs{@xympar} creates tagging structure: +% \begin{macrocode} +\long\def\@ympar#1{% + \@savemarbox\@marbox{#1}% + \global\setbox\@currbox\copy\@marbox + \tag_stop: + \@xympar + \tag_start:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@xmpar} +% \cs{@xmpar} is the command used if an optional argument is present. +% In this case we must stop tagging for \cs{@xympar} as above +% but also decide which of the two @savemarbox should have tagging active. +% We add a label to \cs{@marbox}. If that exist tagging is activated for this +% box else for the other one. +% \begin{macrocode} +\long\def\@xmpar[#1]#2{% + \int_gincr:N\g__kernel_marginpar_int + \property_if_recorded:eTF { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int } + { + \@savemarbox\@marbox {#1 + \property_record:ee + { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page} + }% + \tag_stop: + \@savemarbox\@currbox{#2}% + \tag_start: + } +% \end{macrocode} +% order matters! the tagged box should be first so that it can pick up +% the correct text-unit number. +% \begin{macrocode} + { + \@savemarbox\@currbox{#2}% + \tag_stop: + \@savemarbox\@marbox{#1 + \property_record:ee + { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page}} + \tag_start: + } + \tag_stop: + \@xympar + \tag_start: + } +% +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{marginpar-latex-lab-testphase.ltx} + [\ltlabmarginpardate\space v\ltlabmarginparversion\space + Changes related to the tagging of the margin notes] + +\RequirePackage{latex-lab-testphase-marginpar} + +% +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx index 285471addc3..0dbc5911852 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx @@ -2,7 +2,7 @@ % %% File: latex-lab-math.dtx % -% Copyright (C) 2022-2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -19,8 +19,8 @@ % for those people who are interested or want to report an issue. % % -\def\ltlabmathdate{2023-09-11} -\def\ltlabmathversion{0.5c} +\def\ltlabmathdate{2024-04-16} +\def\ltlabmathversion{0.5j} % %<*driver> \documentclass{l3doc} @@ -46,7 +46,14 @@ % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}} % \providecommand\class[1]{\texttt{#1.cls}} % \providecommand\pkg[1]{\texttt{#1}} -% \providecommand\hook[1]{\texttt{#1}} +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} % % ^^A \car {...} for marginal comments % ^^A \car*{...} for longer inline comments @@ -59,8 +66,6 @@ % {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A % {\todo[#2]{#3}}} % -% -% % \begin{abstract} % This is an experimental prototype. It captures math material % (basically okay, but the interfaces for packages aren't yet @@ -75,6 +80,18 @@ % \car*{Todo: update all the documentation! Both here and % (what little there is!) in the implementation section.} % +% Tagging math involves a variety of tasks that require that math is captured before the +% typesetting +% \begin{itemize} +% \item When typesetting the math MC-tags and structure commands must +% be inserted at the begin and the end, and perhaps also around lines +% or other subparts of the equation. +% \item The source and/or a mathml-representation of the source must be available +% so that it can be (perhaps after some preprocessing) be used in an associated file +% or in an alternate text +% \item It must be possible to measure the math for e.g. a bbox setting. +% \end{itemize} +% % This file implements capture of all math mode material at the outer % level, i.e., a formula is captured in its entirety with inner text % blocks (possibly containing further math) absorbed as part of the @@ -84,7 +101,24 @@ %\end{verbatim} % would only result in a single capture of the tokens % ``\verb*/a \in A \text{ for all $a<5$}/''. +% % +% \section{Math capture} \label{sec:mathcapture} +% In the current setup +% \begin{itemize} +% \item |$|, |\(...\)| and |$$| grab (through a command in \cs{everymath}/cs{everydisplay}) +% if the boolean \cs{l_@@_collected_bool} is false. +% If the boolean is true they behave normally and can for example contain verbatim. +% +% \item All (registered) environments grab their body +% regardless of the state of the boolean. For +% |equation|, |equation*| and |math| this is a change as they no longer can +% contain verbatim. +% +% \item BUG: |\[...\]| grabs if \cs{l_@@_collected_bool} is false. If it is +% true it falls back to |equation*| and then errors because this can't find the end. +% \end{itemize} +% % \subsection{Code level interfaces} % % \begin{function}{\math_register_env:n, \math_register_env:nn} @@ -109,7 +143,8 @@ % \end{syntax} % Declares that the captured math content should be passed to the % \meta{tokens}, which will receive the environment type as |#1| and -% the content as |#2|. +% the content as |#2|. The processing is done before the typesetting. It is not +% applied if \cs{ifmeasuring@} is true. % \end{function} % % \subsection{Document level interfaces} @@ -129,38 +164,275 @@ % \end{itemize} % \end{function} % +% \section{Math tagging} +% +% The tagging code has to handle +% \begin{itemize} +% \item the embedding into the surrounding. This means +% \begin{itemize} +% \item closing and reopening MC-chunks +% \item closing and reopening text/P-structures +% \item handling interferences of the tagging code with penalties and spacing. +% \end{itemize} +% \item the actual tagging which means to do some or all of the following tasks: +% \begin{itemize} +% \item setup content for an associated source file +% \item setup content for an associated mathml file +% \item setup content for the /Alt key +% \item setup content for the /ActualText key +% \item setup attributes +% \item add associated files +% \item add a Formula structure +% \item surround subparts (e.g. lines) with Formula sub structures +% (perhaps with their own set of additional content) +% \item surround elements of the equation with mathml structure elements +% (currently only luatex with luamml) +% \end{itemize} +% \end{itemize} +% +% \subsection{Inline math} +% +% The embedding code is added through +% the sockets +% \begin{itemize} +% \item |tagsupport/math/inline/begin| +% \item |tagsupport/math/inline/end| +% \end{itemize} +% The sockets simply push and pop the MC currently. Without +% tagging they use the noop-plug. +% +% The actual tagging is in done through the sockets +% \begin{itemize} +% \item |tagsupport/math/inline/formula/begin| +% This socket takes the math as argument and its code +% should output it for typesetting. Without tagging the +% socket uses the identity plug. +% The |default| plug of the socket calls these three internal sockets +% for the tagging support: +% \begin{itemize} +% \item |tagsupport/math/content| This should set up the various +% content variables (empty variables are ignored by the structure code +% and so can be used to suppress a setting). +% \item |tagsupport/math/struct/begin| This calls \cs{tag_struct_begin:n}. +% It should also write the associated files if needed. +% \item |tagsupport/math/substruct/begin| this handles subparts. +% TODO: does it really make sense in inline math to have that?? +% \end{itemize} +% \item |tagsupport/math/inline/formula/end| +% This socket ends the formula structure(s). The |default| +% plug calls these internal sockets: +% \begin{itemize} +% \item |tagsupport/math/substruct/end| +% \item |tagsupport/math/struct/end| +% \end{itemize} +% \end{itemize} +% +% \subsection{Display math} +% +% \textit{to be written} +% +% \subsection{Associated Files} +% +% The current code allows the attachment of two types of associated file to the +% Formula structure: +% the \LaTeX\ source and a MathML representation. +% Technically both can be attached---AF is an array +% of file references---practically there can be problems with PDF consumers: +% e.g. ngpdf used both and so showed the equation twice +% (this has been corrected in the newest version) and +% Foxit seems to see only the first AF in the array (so we attach the +% mathml as first file). +% +% The \LaTeX\ source can be (and is) attached automatically. +% It can be suppressed by an option with +% \texttt{math/tex/AF=false}, see below. +% +% The MathML is attached if a file |\jobname-mathml.html| is found and +% if it contains a suitable MathML snippet for the current formula. +% The MathML processing can be suppressed globally by emptying the list of +% mathml files with |math/mathml/sources=|. Locally for a formula |math/mathml/AF=false| +% can be used. +% +% For a MathML representation a file with such representations must be provided. +% If the equation is numbered the numbering should be part of the MathML as +% the |Lbl| substructure is ignored if an MathML is used (see https://github.com/foxitsoftware/PDF_UA-2). +% +% The MathML representation is given in a special format. +% It is meant to be a valid html file +% that can be viewed in a browser. +% For this it can start with || and end with || +% It should have the extension \texttt{.html}. The \meta{mathml} content +% is read with special catcodes, so can contain ambersands, hashes, comment chars +% and unmatched braces such as |{| +% +% The file should contain a number of representations in this format: +% \begin{quote} +% |
| \\ +% |

\mml| \meta{key}|

|\\ +% |

|\meta{source}|

| \\ +% |

|\meta{hash}|

| \\ +% | |\\ +% \meta{mathml}\\ +% | |\\ +% |
| +% \end{quote} +% The keywords |
|, |

\mml|, |

|, || |

| are required as +% they are used to delimit the arguments by the \LaTeX{} code. +% +% \meta{key} and \meta{source} are only used for debugging, they help to identify +% the equation referred by this representation. The source should be used correctly escaped +% |&| and |<| so that if gives valid html! +% +% \meta{attributes} is not required either, but can e.g. contain attributes +% to improve the display in a browser: +% \begin{verbatim} +% +% \end{verbatim} +% It can also contain the name space declaration: |xmlns="http://www.w3.org/1998/Math/MathML"|% +% \footnote{But it is probably not needed and only blows up the PDF.} +% +% +% By default the code tries at the begin of the document +% to read a file |\jobname-mathml.html| in the |html|-format. +% The file name can be changed with |mathml/setfiles={filename1,filename2}| +% (without extension, |html| is added automatically). +% If there is a list, all files are loaded. +% If a file doesn't exist it is ignored, only an info is written to the log. +% +% Currently every MathML-snippet from a file is embedded into the PDF, +% it is not checked first if it is actually used (simply writing everything to the PDF +% is a bit easier than keeping everything in memory and also means that +% the snippets are one after the other in the PDF). +% +% As mentioned above the MathML-AF can be suppressed for the equations in a group with +% |math/mathml/AF=false|, or +% completly by setting |math/mathml/sources=| in the preamble. +% +% Files embedded in a PDF can be listed in the attachments panel of a PDF viewer. +% This is probably not so useful for lots of small files (but one could create +% collections), but as long as PDF editors or viewers don't offer +% proper support to access the AF it can help so have them there. The MathML are +% added by default, but the \LaTeX{} source not. This can be changed with +% |viewer/pane/mathsource=true| (anywhere in the document) and |viewer/pane/mathml=false| (in the +% preamble, before the external file is read). +% +% \subsection{Options} +% +% % \section{Known current bugs, etc.} % \car*{New Section, now with subsections.\\ % As indicated, these lists are probably incomplete.\\ % Some of these have been addressed in a more recent branch.} % % \subsection{Capture/grabbing problems} -% +% % \begin{enumerate} % \item Incorrect grabbing of |$|-math when there is also % explicit |$|-math within a \textit{text environment} % that is itself within the math that should all be grabbed. +% For example, +% \begin{verbatim} +% $a\begin{minipage}{1cm}$b$\end{minipage}$ +% \end{verbatim} +% would only result in the capture of the tokens +% ``\verb*/a\begin {minipage}{1cm}/''. +% This can be avoided by an additional brace group: +% \begin{verbatim} +% $a{\begin{minipage}{1cm}$b$\end{minipage}}$ +% \end{verbatim} +% % \item Similar incorrect grabbing with |$$| also. +% % \item The grabbing, for all the display environments (and |\) \]|), needs % to deal with nesting: \pkg{amsmath} contains code for this. -% \item +% +% \item The math can't contain verbatim and verbatim-like commands. This is +% nothing new for the \pkg{amsmath} environments but changes |$| and |\[\]| +% and |equation*| (see e.g. tagging-project issue \#30). +% +% \item Begin and end of the math or math environment can not be hidden in commands. +% For example \verb+>{$}l<{$}+ in a tabular would lead to errors. +% Defining |\[| to fall back to |equation*| doesn't work if |equation*| is +% a grabbing environment. +% +% \item The behaviour of |\[...\]| is faulty. See above. % \end{enumerate} % +% \subsection{Fake math} +% In a number of places in \LaTeX{} math commands (mainly |$|) is used +% only for technical reason, e.g. to access a math font, to setup a symbol +% or to use \cs{vcenter}. +% +% The code identifies such fake math mostly by making use of the \cs{m@th} command +% where two methods are used for the automatic detection: +% +% \begin{itemize} +% \item After grabbing math content the code checks if the content contains the token +% \cs{m@th} and if yes it doesn't call the processor before reinserting +% the content and perhaps adding tagging code. +% This method requires that the math can be grabbed (e.g. that the end dollar is visible) +% and that the \cs{m@th} is visible. It applies for example in \cs{@iiiparbox} where the +% code from |$\vcenter| to |\m@th$| is grabbed an put back. It does not work for +% example for |tabular| where the dollars and the \cs{m@th} token are spread around +% over three commands. |tabular| needs therefore manual intervention. +% +% A look in the list of usages (in \texttt{usage-of-m@th.md}) justifies this approach. +% All usages are either not math at all, or related to small elements that probably +% shouldn't be grabbed and processed on their own. +% +% \item \cs{m@th} is redefined so that it sets the boolean \cs{l_@@_collected_bool} +% to true. If \cs{m@th} is used inside math that has been grabbed +% this doesn't change much as the boolean is set by the grabbing anyway. For usages +% outside math the benefit is not so clear: The setting avoids that in \cs{LaTeXe} +% the epsilon is processed as math, but it also prevents that the content of the amsmath +% command \cs{boxed} is processed as math. +% It means that if one wants to reenable math processing inside some (fake) math +% one has to do it after \cs{m@th} calls. +% \end{itemize} +% +% Open problems +% \begin{enumerate} +% \item The grabbing code doesn't pass the info that it detected a \cs{m@th} token. +% This means that the tagging code has to do the same check (and doesn't do this +% in all cases yet). +% +% \item Commands are missing to locally disable the grabbing and processing, e.g. +% to handle |tabular|. +% +% \item It must be checked if setting the boolean in \cs{m@th} really makes sense +% or if commands like \cs{LaTeXe} should be handled manually. +% +% \end{enumerate} +% +% \subsection{Processor} +% +% The grabbed math is at first passed to the processor. The processor is not called +% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m@th} +% token is detected. +% It is not quite clear what purpose the processor has. As it is a public interface +% it can't be used for internal code. And typesetting happens later and the processor +% can't really change this. Currently it is mostly used for debugging and messages. +% If the \cs{m@th} is found the \cs{l_@@_fakemath_bool} is set, so if the code +% is changed this must be preserved. +% % \subsection{Other problems} % % \begin{enumerate} % \item -% The presence of \cs{m@th} in association with \cs{ensuremath} +% The presence of \cs{m@th} in association with \cs{ensuremath} % does not necessarily indicate fakemath. This is because % wanting mathsurround to be zero is very reasonable and common, % \emph{even when the math is genuine} (and hence needs to be collected). +% +% TODO: this claim needs some examples. +% % \item User-defined environments can create problems; but this area, of % new, copied and changed environments, has not yet been developed. % % \car*{Joseph wrote, inter alia:\\ % My thinking [regarding] \cs{RegisterMathEnvironment}\\ % - (New) Math environments should not be created-then-patched, but only -% generated by a [(future)] dedicated command (\cs{DeclareMathEnviornment}, +% generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment}, % presumably)\\ % - Math environments created with \pkg{ltcmd} [commands] should not be copied, . . .\\ % - Package authors should be able to manually set up math environments with a public boolean.} @@ -172,7 +444,10 @@ % \begin{enumerate} % \item Add (some of) the math display commands that were \enquote{lifted from % plain}, e.g., \cs{displaylines} \cs{eqalign}(??). -% \item +% \item The breqn packages changes catcodes and that isn't yet covered +% by our mechanism. +% \item \cs{intertext} is not correctly taken into account by the +% code splitting multiline math into subformulas. % \end{enumerate} % % @@ -218,36 +493,823 @@ % have conditional definitions and deals with how to define \cs{[}/\cs{]} % neatly. % \begin{macrocode} -\tl_gput_right:Nn \@kernel@before@begindocument - { \RequirePackage { amsmath } } +\AddToHook{begindocument/before}{ \RequirePackage { amsmath } } % \end{macrocode} % % % \subsection{Data structures} % -% -% -% \begin{variable}{\l_@@_collected_bool} +% \begin{variable}{\l_@@_collected_bool} % Tracks whether math mode material has been collected, which happens inside % \pkg{amsmath} environments as well as those handled directly here. +% If true following math will not grab and/or process. +% See \ref{sec:mathcapture} for details. +% \begin{macrocode} +\bool_new:N \l_@@_collected_bool +% \end{macrocode} +% \end{variable} % +% \begin{variable}{\l_@@_fakemath_bool} +% Tracks whether math mode material has been identified as fake math during +% the grabbing phase, which happens currently if the +% grabbed contents contains the \cs{m@th} token. % % \begin{macrocode} -\bool_new:N \l_@@_collected_bool +\bool_new:N \l_@@_fakemath_bool % \end{macrocode} % \end{variable} -% +% +% % \car{Change first tl name below: `env' $=>$ `info'?\\ % Or do we need an extra storage tl?} % % \begin{variable}{\g_@@_grabbed_env_tl, \g_@@_grabbed_math_tl} -% \cs{g_@@_grabbed_env_tl} contains the name of the math environment (\texttt{math} in the case -% of inline math, \cs{g_@@_grabbed_math_tl} the math content. +% \cs{g_@@_grabbed_env_tl} contains the name of the math environment +% (\texttt{math} in the case of inline math, +% \cs{g_@@_grabbed_math_tl} the math content. % \begin{macrocode} \tl_new:N \g_@@_grabbed_env_tl \tl_new:N \g_@@_grabbed_math_tl % \end{macrocode} % \end{variable} +% +% \begin{variable}{\l_@@_tmpa_tl,\l_@@_tmpa_skip,\l_@@_tmpa_str} +% Temporary variables +% \begin{macrocode} +\tl_new:N \l_@@_tmpa_tl +\skip_new:N \l_@@_tmpa_skip +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_@@_content_alt_tl, +% \l_@@_content_actual_tl, +% \l_@@_content_AF_tl} +% Temporary variables to hold math content that should +% be used in actual or alt text and stored as AF. +% \begin{macrocode} +\tl_new:N \l_@@_content_alt_tl +\tl_new:N \l_@@_content_actual_tl +\tl_new:N \l_@@_content_AF_source_tl +\tl_new:N \l_@@_content_AF_source_tmpa_tl +\tl_new:N \l_@@_content_AF_mathml_tl +% \end{macrocode} +% \end{variable} +% +% \subsection{Tagging tools} +% The following commands implement small tagging code chunks. +% This should probably be collected and moved into tagpdf later. +% \begin{macro}{\__tag_tool_close_P:} +% This closes a P/text-chunk, both the MC and the structure and +% increases the counter manually. +% \begin{macrocode} +\cs_new_protected:Npn \__tag_tool_close_P: + { + \tag_if_active:T + { + \tag_mc_end: %end P-chunk, should perhaps be \tag_mc_end_push: ... + \__tag_gincr_para_end_int: + \__tag_check_para_end_show:nn{red}{} %debug: show para + \tag_struct_end: + } + } +% \end{macrocode} +% \end{macro} +% +% We add also an attribute. +% \begin{macrocode} +\tl_new:N\l_@@_attribute_class_tl +\tagpdfsetup + {role/new-attribute = {inline} {/O /Layout /Placement/Inline}, + role/new-attribute = {display} {/O /Layout /Placement/Block}, + } +% \end{macrocode} +% +% \subsection{Code related to AF} +% Booleans to handle the options. +% \begin{variable}{ +% \l__tag_math_texsource_AF_bool, +% \l__tag_math_texsource_pane_bool, +% \l__tag_math_mathml_AF_bool, +% \g__tag_math_mathml_AF_bool, +% \l__tag_math_mathml_pane_bool, +% \l__tag_math_alt_bool +% } +% \begin{macrocode} +\bool_new:N\l__tag_math_texsource_AF_bool +\bool_new:N\l__tag_math_texsource_pane_bool +\bool_new:N\l__tag_math_mathml_AF_bool +\bool_new:N\g__tag_math_mathml_AF_bool +\bool_new:N\l__tag_math_mathml_pane_bool +\bool_new:N\l__tag_math_alt_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{ +% \g_@@_mathml_total_int, +% \g_@@_mathml_int, +% \g_@@_math_total_int, +% \g_@@_mathml_AF_found_int, +% \g_@@_mathml_AF_attached_int, +% } +% \cs{g_@@_mml_total_int} records the mathml fragments read in. +% \cs{g_@@_mml_int} records the mathml fragments read in with a different hash. +% \cs{g_@@_AF_total_int} records the number of math structures that try to +% attach a mathml AF. +% \cs{g_@@_AF_found_int} records the number of math structures for which a fitting +% mathml is found. +% \cs{g_@@_AF_attached_int} records the number of math structures which got a mathml fragment +% (if mathml-AF are not disabled locally this should be the equal to the previous number. +% +% \begin{macrocode} +\int_new:N\g_@@_mathml_total_int +\int_new:N\g_@@_mathml_int +\int_new:N\g_@@_math_total_int +\int_new:N\g_@@_mathml_AF_found_int +\int_new:N\g_@@_mathml_AF_attached_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l__tag_math_mathml_files_clist} +% A sequence to store the file list for the mathml. +% \begin{macrocode} +\clist_new:N\l__tag_math_mathml_files_clist +\clist_put_right:Ne\l__tag_math_mathml_files_clist {\c_sys_jobname_str-mathml} +% \end{macrocode} +% \end{variable} + +% This is the internal variant of the \cs{mml} command. +% \begin{macro}{\@@_AF_mml:nnnn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_AF_mml:nnnn #1 #2 #3 #4 +%#1 number, #2 tex source for debugging, #3 hash, #4 mathml + { + \int_gincr:N \g_@@_mathml_total_int +% \end{macrocode} +% mathml with the same hash should be included only once: +% \begin{macrocode} + \tl_if_exist:cF { g_@@_mathml_#3_tl } + { + \int_gincr:N \g_@@_mathml_int +% \end{macrocode} +% a simple Desc key, take care that it is a valid string! +% \begin{macrocode} + \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)} + \pdffile_embed_stream:nnN {#4}{mathml-#1.xml}\l_@@_tmpa_tl +% \end{macrocode} +% not strictly necessary but makes the files visible in the file attachment +% page +% \begin{macrocode} + \bool_if:NT \l__tag_math_mathml_pane_bool + {\pdfmanagement_add:nne {Catalog/Names}{EmbeddedFiles}{\l_@@_tmpa_tl}} + \tl_new:c{g_@@_mathml_#3_tl} + \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl + } + } +% \end{macrocode} +% \end{macro} +% +% The html reader. +% \begin{macrocode} +\cs_new_protected:Npn \@@_AF_html_reader:w#1#2

#3

#4

#5

#6{ + \endgroup + \@@_AF_mml:nnnn{#1}{#2}{#3}{#4} + } +% \end{macrocode} + +% +% \begin{socketdecl}{tagsupport/math/mathml/write} +% This writes a html-dummy with the hash and the math content. +% This should be optional, so it uses a socket that can be disabled +% +% \begin{macrocode} +\socket_new:nn {tagsupport/math/mathml/write}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{plugdecl}{On} +% \begin{macrocode} +\socket_new_plug:nnn{tagsupport/math/mathml/write}{On} + { + \str_set:NV\l_@@_tmpa_str\l_@@_content_AF_source_tl + \str_replace_all:Nnn\l_@@_tmpa_str{&}{&} + \str_replace_all:Nnn\l_@@_tmpa_str{<}{<} + \iow_now:Ne \g_@@_writedummy_iow + { + \iow_newline: +
+ \iow_newline: +

\c_backslash_str mml\c_space_tl \int_use:N \g_@@_math_total_int

+ \iow_newline: +

\l_@@_tmpa_str

+ \iow_newline: +

\l_@@_content_hash_tl

+ \iow_newline: + + \iow_newline: +
+ \iow_newline: + } + } +% \end{macrocode} +% \end{plugdecl} +% And now a key to activate the socket. +% \begin{macrocode} + +\keys_define:nn { __tag / setup } + { + math/mathml/write-dummy .code:n = + { + \bool_gset_true:N \g__tag_math_mathml_AF_bool + \tl_if_exist:NF\g_@@_writedummy_iow + { + \iow_new:N \g_@@_writedummy_iow + \iow_open:Nn \g_@@_writedummy_iow + { + \c_sys_jobname_str-mathml-dummy.html + } + \iow_now:Ne \g_@@_writedummy_iow + { + + \iow_newline: + + } + \AssignSocketPlug {tagsupport/math/mathml/write}{On} + \AddToHook{enddocument/afterlastpage} + { + \iow_now:Nn \g_@@_writedummy_iow {} + \iow_close:N \g_@@_writedummy_iow + } + } + }, + math/mathml/write-dummy .usage:n=preamble + } +% \end{macrocode} +% +% \begin{macro}{\@@_AF_process_mathml_files:} +% \begin{macrocode} +\box_new:N\l_@@_tmpa_box +\cs_new_protected:Npn \@@_AF_process_mathml_files: + { + \hbox_set:Nn \l_@@_tmpa_box + { + \pdfdict_put:nnn { l_pdffile/Filespec }{AFRelationship} { /Supplement } + \pdfdict_put:nne + { l_pdffile }{Subtype} + { \pdf_name_from_unicode_e:n{application/mathml+xml} } + \char_set_catcode_other:N \# + \cs_set_eq:NN\mml \@@_AF_html_reader:w + \clist_map_inline:Nn \l__tag_math_mathml_files_clist + { + \file_if_exist:nTF {##1.html} + { + \typeout{Info:~reading~mathml~file~##1} + \file_input:n {##1.html} + \bool_gset_true:N\g__tag_math_mathml_AF_bool + } + { + \typeout{Info:~mathml~file~##1~does~not~exist}%info message + } + } + } + \bool_if:NT\g__tag_math_mathml_AF_bool + { + \typeout{Info:~Activating~mathml~support} + \AssignSocketPlug{tagsupport/math/struct/begin}{test-mathml} + \AssignSocketPlug{tagsupport/math/struct/end}{test-mathml} +% \end{macrocode} +% mathml handling doesn't like subparts, so we disable them for now: +% \begin{macrocode} + \AssignSocketPlug{tagsupport/math/substruct/begin}{single} + \AssignSocketPlug{tagsupport/math/substruct/end}{single} + \AddToHook{enddocument/info} + { + \iow_term:n{MathML~statistic} + \iow_term:n{================} + \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl + MathML~fragments~read} + \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl + different~MathML~fragments} + \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl + math~fragments~found} + \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl + fitting~MathML~AF~found} + \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl + MathML~AF~attached} + } + } + } +\AddToHook{begindocument}{\@@_AF_process_mathml_files:} +% \end{macrocode} +% \end{macro} +% +% \subsection{Mathstyle detection} +% In some cases we need to detect the mathstyle used in a \cs{mathchoice} +% command and to disable/enable tagging in the unused branches. +% This is currently only used in the amstext command \cs{text} +% but is perhaps also needed in other cases, so we create a general command. +% +%\begin{macro}{\l_@@_mathstyle_int,\g_@@_mathchoice_int,mathstyle} +% \begin{macrocode} +\int_new:N \l_@@_mathstyle_int +\int_new:N \g_@@_mathchoice_int +\property_new:nnnn{mathstyle}{now}{-1}{\int_use:N \l_@@_mathstyle_int } +% \end{macrocode} +%\end{macro} +% For now internal, but perhaps will need a public version. +% The command should be used in every branch of a \cs{mathchoice} +% (with the correct mathstyle number) and with an unique label (which should +% be the same in every branch). +% \cs{g_@@_mathchoice_int} can be e.g. increased before the mathchoice and +% then used. +% \begin{macro}{\@@_tag_if_mathstyle:nn} +% \begin{macrocode} +\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2 + %#1 refers to label + %#2 is a number for the mathstyle (typically 0,2,4,6) + { + \int_set:Nn \l_@@_mathstyle_int {#2} + \property_record:nn {#1} { mathstyle } + \int_compare:nNnTF { \property_ref:nn {#1}{ mathstyle} } = { #2 } + { \tag_start: }{ \tag_stop: } + } +\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en} +% \end{macrocode} +% \end{macro} +% +% \subsection{Tagging options} +% \begin{macrocode} +\keys_define:nn { __tag / setup } + { + math/mathml/sources .clist_set:N = \l__tag_math_mathml_files_clist, + math/alt/use .bool_set:N = \l__tag_math_alt_bool, + viewer/pane/mathml .bool_set:N = \l__tag_math_mathml_pane_bool, + viewer/pane/mathml .initial:n = true, + viewer/pane/mathsource .bool_set:N = \l__tag_math_texsource_pane_bool, + math/mathml/AF .bool_set:N = \l__tag_math_mathml_AF_bool, + math/mathml/AF .initial:n = true, + math/tex/AF .bool_set:N = \l__tag_math_texsource_AF_bool, + math/tex/AF .initial:n = true + } +% \end{macrocode} +% +% \subsection{Sockets} +% \subsubsection{Main inline math sockets} +% +% \begin{socketdecl} +% { +% tagsupport/math/inline/begin, +% tagsupport/math/inline/end, +% tagsupport/math/inline/formula/begin, +% tagsupport/math/inline/formula/end, +% } +% The first two sockets are meant to embed inline +% math into the surrounding (so to close/reopen e.g. MC-chunks). +% The other two implement the actual formula structure. +% The formula sockets are despite their naming not symmetric: +% the begin socket is issued after the math has started, while +% the end socket is after the math! +% \begin{macrocode} +\socket_new:nn {tagsupport/math/inline/begin}{0} +\socket_new:nn {tagsupport/math/inline/end}{0} +\socket_new:nn {tagsupport/math/inline/formula/begin}{1} % +\socket_new:nn {tagsupport/math/inline/formula/end}{0} +% \end{macrocode} +%\end{socketdecl} +% +% +% \begin{plugdecl}{MC} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/inline/begin} + {MC} + {\tag_mc_end_push:} +\socket_new_plug:nnn + {tagsupport/math/inline/end} + {MC} + {\tag_mc_begin_pop:n{}} +% \end{macrocode} +% \end{plugdecl} +% +% We probably will want to test different tagging receipes. +% \begin{plugdecl}{default} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/inline/formula/begin} + {default} + { + \socket_use:n{tagsupport/math/content} + \socket_use:n{tagsupport/math/struct/begin} +% \end{macrocode} +% TODO: does inline math need subformula handling? +% \begin{macrocode} + % inner formula if multiple parts (not really implemented yet) + \socket_use:n{tagsupport/math/substruct/begin} + #1 + \socket_use:n{tagsupport/math/end} + } +\socket_new_plug:nnn + {tagsupport/math/inline/formula/end} + {default} + { + \socket_use:n{tagsupport/math/substruct/end} + \socket_use:n{tagsupport/math/struct/end} + } +% \end{macrocode} +% \end{plugdecl} +% +% \subsubsection{Main display math sockets} +% +% \begin{socketdecl} +% { +% tagsupport/math/display/begin, +% tagsupport/math/display/end, +% tagsupport/math/display/formula/begin, +% tagsupport/math/display/formula/end, +% } +% The first two sockets are meant to embed display +% math into the surrounding (so to close/reopen e.g. MC-chunks and +% P-structure). +% The other two implement the actual formula structure. +% The formula sockets are despite their naming not symmetric: +% the begin socket is issued after the math has started, while +% the end socket is after the math! +% \begin{macrocode} +\socket_new:nn {tagsupport/math/display/begin}{0} +\socket_new:nn {tagsupport/math/display/end}{0} +\socket_new:nn {tagsupport/math/display/formula/begin}{1} % +\socket_new:nn {tagsupport/math/display/formula/end}{0} +% \end{macrocode} +%\end{socketdecl} + +% \begin{plugdecl}{default} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/display/begin} + {default} + { \__tag_tool_close_P: } +\socket_new_plug:nnn + {tagsupport/math/display/end} + {default} + { + } +% \end{macrocode} +% \end{plugdecl} + + +% \begin{plugdecl}{default} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/display/formula/begin} + {default} + { + \socket_use:n{tagsupport/math/content} + \socket_use:n{tagsupport/math/struct/begin} + \socket_use:n{tagsupport/math/substruct/begin} + #1 + \socket_use:n{tagsupport/math/end} + } +\socket_new_plug:nnn + {tagsupport/math/display/formula/end} + {default} + { + \socket_use:n{tagsupport/math/substruct/end} + \socket_use:n{tagsupport/math/struct/end} + } +% \end{macrocode} +% \end{plugdecl} +% +% \subsubsection{Internal sockets} +% +% \begin{variable}{\l_@@_content_template_tl} +% The default text used as alt or actual text. +% \begin{macrocode} +\tl_new:N\l_@@_content_template_tl +\tl_set:Nn \l_@@_content_template_tl + { + LaTeX~ formula~ starts~ + \exp_not:N\begin{\g_@@_grabbed_env_tl} + \c_space_tl + \exp_not:V\g_@@_grabbed_math_tl + \c_space_tl + \exp_not:N\end{\g_@@_grabbed_env_tl} + \c_space_tl LaTeX~ formula~ ends~ + } +% \end{macrocode} +% \end{variable} + +% \begin{variable}{\l_@@_texsource_template_tl} +% The default text used as texsource +% \begin{macrocode} +\tl_new:N\l_@@_texsource_template_tl +\tl_const:Nn\c_@@_inline_env_tl {math} +\tl_set:Nn \l_@@_texsource_template_tl + { + \tl_if_eq:NNTF\g_@@_grabbed_env_tl\c_@@_inline_env_tl + { + $ + \exp_not:V\g_@@_grabbed_math_tl + $ + } + { + \exp_not:N\begin{\g_@@_grabbed_env_tl} + \exp_not:V\g_@@_grabbed_math_tl + \exp_not:N\end{\g_@@_grabbed_env_tl} + } + } +% \end{macrocode} +% \end{variable} + +% +% \begin{socketdecl}{tagsupport/math/content} +% The math content is stored in associated files and used for +% actual and alternative text. As the exact text is still +% unclear we use a socket to be able to test variants. +% The socket should set all four tl vars above, if needed +% to identical values. It can use the two variables +% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl} +% \begin{macrocode} +\socket_new:nn {tagsupport/math/content}{0} +% \end{macrocode} +% \end{socketdecl} +% +% Some default sockets to set the contents. +% TODO: think about naming convention. +% TODO: think how this should organized so that one +% has options to change from the outside and so that +% there are less repetitions. +% \begin{plugdecl}{actual+source} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/content} + {actual+source} + { + \tl_set:Ne\l_@@_content_actual_tl + { + \l_@@_content_template_tl + } + \tl_set:Ne \l_@@_content_AF_source_tl + { + \l_@@_texsource_template_tl + } + \tl_set:Nn \l_@@_content_AF_mathml_tl {} + \tl_set:Nn \l_@@_content_alt_tl {} + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{alt+source} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/content} + {alt+source} + { + \tl_set:Ne\l_@@_content_alt_tl + { + \l_@@_content_template_tl + } + \tl_set:Ne \l_@@_content_AF_source_tl + { + \l_@@_texsource_template_tl + } + \tl_set:Nn \l_@@_content_AF_mathml_tl {} + \tl_set:Nn \l_@@_content_actual_tl {} + } +% \end{macrocode} +% \end{plugdecl} +% \begin{macrocode} +\socket_assign_plug:nn {tagsupport/math/content}{alt+source} +% \end{macrocode} +% +% \begin{socketdecl}{tagsupport/math/struct/begin, +% tagsupport/math/struct/end} +% For the main structure we use a socket too. +% This allow e.g. to create a special one for luamml +% which setups additional objects. +% The begin socket can use the two variables +% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl} +% \begin{macrocode} +\socket_new:nn {tagsupport/math/struct/begin}{0} +\socket_new:nn {tagsupport/math/struct/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{plugdecl}{default} +% TODO: think about some naming convention ... +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/struct/begin} + {default} + { + \bool_if:NTF\l__tag_math_texsource_AF_bool + { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl } + { \tl_clear:N \l_@@_content_AF_source_tmpa_tl } + \tag_struct_begin:n + { + tag=Formula, + texsource = \l_@@_content_AF_source_tmpa_tl, + title-o = \g_@@_grabbed_env_tl, + actualtext = \l_@@_content_actual_tl, + alt = \l_@@_content_alt_tl + } + } +\socket_new_plug:nnn + {tagsupport/math/struct/end} + {default} + { \tag_struct_end: } + +\socket_assign_plug:nn {tagsupport/math/struct/begin}{default} +\socket_assign_plug:nn {tagsupport/math/struct/end}{default} +% \end{macrocode} +% \end{plugdecl} +% +% \begin{plugdecl}{test-mathml} +% This (test-)socket tries to add a mathml-AF to formula. +% It is activated if a mathml.html has been found and loaded. +% Additionally it also sets an attribute +% (this can perhaps be done by default anyway.) +% As it disturbs the reading of the AF it currently deactivates the /Alt key, +% unless it has been reenabled with |math/alt/use=true| +% \begin{macrocode} +\cs_generate_variant:Nn \str_mdfive_hash:n {o} +\tl_new:N\l_@@_content_hash_tl +% \end{macrocode} +% we need to save the grabbed math: +% \begin{macrocode} +\tl_new:N\l_@@_grabbed_math_tl +% \end{macrocode} +% the socket definition +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/struct/begin} + {test-mathml} + { + \int_gincr:N\g_@@_math_total_int + \tl_set:Ne\l_@@_content_hash_tl + {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }} + \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl + \tl_if_eq:NnTF\g_@@_grabbed_env_tl {math} + { + \tl_set:Nn\l_@@_attribute_class_tl{inline} + } + { + \tl_set:Nn\l_@@_attribute_class_tl{display} + } + \bool_if:NF\l__tag_math_alt_bool + { \tl_set:Nn \l_@@_content_alt_tl{} } +% \end{macrocode} +% debugging option. TODO: hide in debug key. +% \begin{macrocode} + \tl_if_exist:cTF { g_@@_mathml_ \l_@@_content_hash_tl _tl } + { + \int_gincr:N\g_@@_mathml_AF_found_int + \bool_if:NTF \l__tag_math_mathml_AF_bool + { + \int_gincr:N\g_@@_mathml_AF_attached_int + \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl} + } + { + \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl} + } + } + { + \typeout{WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl} + } + \socket_use:n {tagsupport/math/mathml/write} % write hash if request + \bool_if:NTF\l__tag_math_texsource_AF_bool + { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl } + { \tl_clear:N \l_@@_content_AF_source_tmpa_tl } + \tag_struct_begin:n + { + tag=Formula, + attribute-class=\l_@@_attribute_class_tl, % + AFref = + \bool_if:NT\l__tag_math_mathml_AF_bool + { + \cs_if_exist_use:c {g_@@_mathml_ \l_@@_content_hash_tl _tl} + }, + texsource = \l_@@_content_AF_source_tmpa_tl, % should be after mathml AF! + title-o = \g_@@_grabbed_env_tl, % + alt = \l_@@_content_alt_tl + } + } +% \end{macrocode} +% not really needed but looks more symmetric: +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/struct/end} + {test-mathml} + { + \tag_struct_end: + } +% \end{macrocode} +% \end{plugdecl} +% +% \begin{socketdecl}{tagsupport/math/substruct/begin, +% tagsupport/math/substruct/end} +% This holds the code to handle subparts of the formula. +% \begin{macrocode} +\socket_new:nn {tagsupport/math/substruct/begin}{0} +\socket_new:nn {tagsupport/math/substruct/end}{0} +% \end{macrocode} +% \end{socketdecl} +% +% \begin{plugdecl}{default} +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/substruct/begin} + {default} + { \grabaformulapartandstart } +\socket_new_plug:nnn + {tagsupport/math/substruct/end} + {default} + { + \tagmcend + \if@subformulas + \tagstructend + \fi + } +\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default} +\socket_assign_plug:nn {tagsupport/math/substruct/end}{default} +% \end{macrocode} +% \end{plugdecl} + +% \begin{plugdecl}{single} +% We need an option to disable subparts as it is unclear +% if consumers can handle them: +% \begin{macrocode} +\socket_new_plug:nnn + {tagsupport/math/substruct/begin} + {single} + { + \typeout{====>subpart~splitting~deactivated} + \typeout{====>grabbed~math=\meaning\g_@@_grabbed_math_tl} + \tag_mc_begin:n{} + } +\socket_new_plug:nnn + {tagsupport/math/substruct/end} + {single} + { \tag_mc_end:} +% \end{macrocode} +% \end{plugdecl} +% +% \begin{socketdecl}{tagsupport/math/end} +% A socket used at the end of the math (before the closing dollar(s)) +% which can e.g. set a flag for luamml. +% \begin{macrocode} +\socket_new:nn {tagsupport/math/end}{0} +% \end{macrocode} +% \end{socketdecl} + +% +% \begin{macro}{\__tag_math_disable:} +% Similar to the table code we collect the plugs that should be +% assigned to do nothing if we don't want tagging +% \begin{macrocode} +\cs_new_protected:Npn \__tag_math_disable: + { + \socket_assign_plug:nn {tagsupport/math/inline/begin}{noop} + \socket_assign_plug:nn {tagsupport/math/inline/end}{noop} + \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{identity} + \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{noop} + \socket_assign_plug:nn {tagsupport/math/display/begin}{noop} + \socket_assign_plug:nn {tagsupport/math/display/end}{noop} + \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{identity} + \socket_assign_plug:nn {tagsupport/math/display/formula/end}{noop} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\__tag_math_enable:} +% Similar to the table code we collect the default plugs that should be +% assigned if we want tagging +% \begin{macrocode} +\cs_new_protected:Npn \__tag_math_enable: + { + \socket_assign_plug:nn {tagsupport/math/inline/begin}{MC} + \socket_assign_plug:nn {tagsupport/math/inline/end}{MC} + \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{default} + \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{default} + \socket_assign_plug:nn {tagsupport/math/display/begin}{default} + \socket_assign_plug:nn {tagsupport/math/display/end}{default} + \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{default} + \socket_assign_plug:nn {tagsupport/math/display/formula/end}{default} + } +% \end{macrocode} +% \end{macro} +% At begin document we can activate: +% \begin{macrocode} +\AtBeginDocument{\tag_if_active:T{\__tag_math_enable: }} +% \end{macrocode} % % \subsection{Interface commands} % @@ -260,7 +1322,8 @@ { \legacy_if:nF { measuring@ } { - \tl_if_in:nnF {#2} { \m@th } + \tl_if_in:nnTF {#2} { \m@th } + { \bool_set_true:N\l_@@_fakemath_bool } { \tl_trim_spaces_apply:nN {#2} \@@_process_auxi:nn {#1} } } } @@ -287,15 +1350,15 @@ % % \begin{macro}{\@@_grab_dollar:w} % Grab up to a single |$|, for inline math mode, suppressing -% any processing if the first token is \tn{m@th}. +% any processing if the token is \tn{m@th} found in the content. +% +% \fmi{what's that test doing?} % -% \fmi{what's that test doing?} +% \car{It is some kind of fix, to avoid the remote +% possibility that the math is empty, making the code +% produce an unwanted \texttt{\$\$}.} % -% \car{It is some kind of fix, to avoid the remote -% possibility that the math is empty, making the code -% produce an unwanted \texttt{\$\$}.} -% -%\car{cf.~the code for this in \cs{@ensuredmath}} +%\car{cf.~the code for this in \cs{@ensuredmath}} % %\car{It is harmless but unnecessary in the dollardollar grabbing below.} % @@ -309,91 +1372,62 @@ \tl_if_blank:nF {#1} { \@@_process:nn { math } {#1} % $ -% fairly simple this one % \end{macrocode} -% We do not want math tagging in fakemath or when measuring, -% so we imitate the test inside \cs{@@_process:nn} for now, -% see https://github.com/latex3/tagging-project/issues/5 -% TODO: use socket to get more control about typesetting variants (tagged, drop etc)? +% We do not want math tagging in fakemath or when measuring, +% We also do not want math tagging if tagging has been suspended. % \begin{macrocode} - \legacy_if:nTF { measuring@ } - { #1 $ } - { - \tl_if_in:nnTF {#1} { \m@th } - { #1 $ } - { - \tagmcend %end P-chunk, in code: \tag_mc_end_push: - \@kernel@math@begin - #1 $ - \@kernel@math@end - \tagmcbegin{} % restart P-chunk (whatsits in pdftex) - } - } + \bool_lazy_or:nnTF + {\legacy_if_p:n { measuring@ }} + { \l_@@_fakemath_bool } + { #1 $ } + { + \tag_socket_use:n {math/inline/begin} %end P-MC + \tag_socket_use:nn {math/inline/formula/begin}{#1} + $ + \tag_socket_use:n {math/inline/formula/end} + \tag_socket_use:n {math/inline/end} % restart P-MC + } } } % \end{macrocode} % \end{macro} +% % \begin{macro}{\@@_grab_dollardollar:w} % And for the classical \TeX{} display structure. % \begin{macrocode} - -\skip_new:N \l_@@_tmpa_skip - \cs_new_protected:Npn \@@_grab_dollardollar:w % $$ #1 $$ { \tl_if_blank:nF {#1} { - \@@_tag_dollardollar_display:nn { equation* }{#1} - #1 + \@@_process:nn { equation* } {#1} + \socket_use:n {tagsupport/math/display/begin} + \socket_use:nn{tagsupport/math/display/formula/begin}{#1} $$ } } % \end{macrocode} -% To allow to use the code without tagging we guard. But probably tagpdf should -% provide some tools for such manual para-ends. +% +% The end code is added through a \cs{aftergroup} so we +% store it inside a command. % \begin{macrocode} -\cs_new_protected:Npn \@kernel@close@P { - \tag_if_active:T - { - \tagmcend %end P-chunk, should perhaps be \tag_mc_end_push: ... - \int_gincr:N \g__tag_para_end_int - \bool_if:NT \l__tag_para_show_bool - { \tag_mc_begin:n{artifact} - \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int} - \tag_mc_end: - } - \tag_struct_end: - } -} - - - -\cs_new_protected:Npn \@@_tag_dollardollar_display:nn #1#2 { - \@@_process:nn {#1} {#2} - \@kernel@close@P - \@kernel@math@begin -% \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} -% \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} -% \int_set:Nn \postdisplaypenalty {10000} -%% -% \group_insert_after:N \@@_tag_dollardollar_display_end: -} - -\cs_new_protected:Npn \@@_tag_dollardollar_display_end: { -% \typeout{== tag dollarldollar display end} -% \ShowTagging{struct-stack} - \tagpdfparaOff - \para_raw_end: - \tagpdfparaOn - \l_@@_tmpa_skip \lastskip - \@kernel@math@end - \penalty \postdisplaypenalty +\cs_new_protected:Npn \@@_tag_dollardollar_display_end: + { + % \typeout{== tag dollarldollar display end} + % \ShowTagging{struct-stack} + \para_raw_end: +% \end{macrocode} +% TODO why is that needed? where is para-tagging disabled? +% \begin{macrocode} + \tagpdfparaOn + \l_@@_tmpa_skip \lastskip + \socket_use:n{tagsupport/math/display/formula/end} + \penalty \postdisplaypenalty % \end{macrocode} % This reinserts the below display skips. It must be doubled to % get the right amount: % \begin{macrocode} - \skip_vertical:n { -\l_@@_tmpa_skip * 2 } + \skip_vertical:n { -\l_@@_tmpa_skip * 2 } % \@doendpe % this has no \end{...} to take care of it } @@ -410,13 +1444,13 @@ { \tl_if_blank:nF {#1} { - \@@_process:nn { math } {#1} $ #1 $ } \bool_set_false:N \l_@@_collected_bool } % \end{macrocode} % \end{macro} +% % \begin{macro}{\@@_grab_eqn:w} % For the most common use of \cs{[}/\cs{]}: turn into an environment. % \begin{macrocode} @@ -463,7 +1497,7 @@ % \begin{macro}{\math_register_env:n} % \begin{macro}{\RegisterMathEnvironment} % Set up to capture environment content and make available. -% +% % \begin{macrocode} \cs_new_protected:Npn \math_register_env:nn #1#2 { @@ -472,15 +1506,8 @@ \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } % - \ExpandArgs { nnx } \RenewDocumentEnvironment {#1} { b } + \ExpandArgs { nne } \RenewDocumentEnvironment {#1} { b } { -% \bool_set_true:N \exp_not:N \l_@@_collected_bool -% \cs_if_exist:cTF { @@_env #1 _aux: } -% { -% \exp_not:c { @@_env #1 _aux: } -% ####1 \exp_not:N \@@_env_end: {#1} -% } -% { \exp_not:N \@@_process:nn {#1} {####1} } \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool { % \typeout{===>B1} @@ -490,34 +1517,22 @@ \cs_if_exist:cTF { @@_env #1 _aux: } { \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} + ##1 \exp_not:N \@@_env_end: {#1} } - { \exp_not:N \@@_process:nn {#1} {####1} } + { \exp_not:N \@@_process:nn {#1} {##1} } \exp_not:n { \@kernel@math@registered@begin } \bool_set_true:N \exp_not:N \l_@@_collected_bool } -% \exp_not:N \tracingall +% \exp_not:N \tracingall \exp_not:c { @@_env_ #1 _begin: } - ####1 + ##1 \exp_not:c { @@_env_ #1 _end: } -% \exp_not:c { @@_env_ #1 _end: } % \exp_not:N \tracingnone -% \exp_not:n { \@kernel@math@registered@end } } - { - } + { + } } -\cs_set_protected:Npn \__cs_tmp:w #1 - { - \group_begin: - \exp_args:No \__cs_generate_internal_variant:n - { \tl_to_str:n {#1} } - \group_end: - } -\__cs_tmp:w { nnxx } - - \cs_new_protected:Npn \math_register_halign_env:nn #1#2 { \tl_set:Nn \l_@@_env_name_tl {#1} @@ -525,15 +1540,8 @@ \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } % - \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } + \ExpandArgs { nnee } \RenewDocumentEnvironment {#1} { b } { -% \bool_set_true:N \exp_not:N \l_@@_collected_bool -% \cs_if_exist:cTF { @@_env #1 _aux: } -% { -% \exp_not:c { @@_env #1 _aux: } -% ####1 \exp_not:N \@@_env_end: {#1} -% } -% { \exp_not:N \@@_process:nn {#1} {####1} } \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool { % \typeout{===>B1} @@ -543,23 +1551,24 @@ \cs_if_exist:cTF { @@_env #1 _aux: } { \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} + ##1 \exp_not:N \@@_env_end: {#1} } - { \exp_not:N \@@_process:nn {#1} {####1} } + { \exp_not:N \@@_process:nn {#1} {##1} } \exp_not:n { \@kernel@math@registered@begin } \bool_set_true:N \exp_not:N \l_@@_collected_bool } -% \exp_not:N \tracingall +% \exp_not:N \tracingall \exp_not:c { @@_env_ #1 _begin: } - ####1 -% \exp_not:c { @@_env_ #1 _end: } + ##1 % \exp_not:N \tracingnone } - { - \exp_not:c { @@_env_ #1 _end: } - } + { + \exp_not:c { @@_env_ #1 _end: } + } } - +% \end{macrocode} +% TODO: the following command is neither documented nor used. Is is needed? +% \begin{macrocode} \cs_new_protected:Npn \math_register_odd_env:nn #1#2 { \tl_set:Nn \l_@@_env_name_tl {#1} @@ -567,7 +1576,7 @@ \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1} \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 } % - \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b } + \ExpandArgs { nnee } \RenewDocumentEnvironment {#1} { b } { \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool { @@ -578,19 +1587,19 @@ \cs_if_exist:cTF { @@_env #1 _aux: } { \exp_not:c { @@_env #1 _aux: } - ####1 \exp_not:N \@@_env_end: {#1} + ##1 \exp_not:N \@@_env_end: {#1} } - { \exp_not:N \@@_process:nn {#1} {####1} } + { \exp_not:N \@@_process:nn {#1} {##1} } \exp_not:n { \@kernel@math@registered@begin } \bool_set_true:N \exp_not:N \l_@@_collected_bool } -% \exp_not:N \tracingall +% \exp_not:N \tracingall \exp_not:c { @@_env_ #1 _begin: } - ####1 + ##1 } { \exp_not:c { @@_env_ #1 _end: } -% needed if we don't have $$...$$ +% needed if we don't have $$...$$ % \exp_not:n { \typeout{---> @kernel@math@registered@end }} \exp_not:n { \@kernel@math@registered@end } } @@ -614,7 +1623,7 @@ \cs_new:Npn \@kernel@math@registered@begin { -% \ShowTagging{struct-stack} +% \ShowTagging{struct-stack} %\typeout{==>A1}\ShowTagging{struct-stack,mc-current} \mode_if_vertical:TF { @@ -623,19 +1632,21 @@ % { \__block_list_beginpar_vmode: } % % \typeout{==>~ at:~ \g__tag_struct_tag_tl} -% - \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl } % needs correction! +% + \tag_if_active:T + { + \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl } % needs correction! { % \typeout{==>A2} \__block_beginpar_vmode: } % needs correction! + } } { % \typeout{==>A3} - \@kernel@close@P -% \tagmcend % needs correction! + \__tag_tool_close_P: } - \@kernel@math@begin + \socket_use:nn{tagsupport/math/display/formula/begin}{} \tagpdfparaOff % \typeout{==>MC1}\ShowTagging{mc-current} } @@ -644,13 +1655,14 @@ % \typeout{==>MC2}\ShowTagging{mc-current} \para_raw_end: \tagpdfparaOn - \@kernel@math@end + \socket_use:n{tagsupport/math/display/formula/end} % \typeout{==>MC3}\ShowTagging{mc-current} \@endpetrue } - + \cs_new_protected:Npn \math_register_env:n #1 { \math_register_env:nn {#1} { } } + \NewDocumentCommand \RegisterMathEnvironment { O{} m } { \math_register_env:nn {#2} {#1} } % \end{macrocode} @@ -660,12 +1672,12 @@ % % \begin{macro}{\@@_env_forward:w} % \begin{macrocode} -\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2 +\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2 { \@@_process:nn {#2} {#1} } % \end{macrocode} % \end{macro} -% -% \subsection{Document commands} +% +% \subsection{Document commands} % % \car*{Add one more here: \texttt{displaymath}, which % is equivalent to \cs{[} , \cs{]}\\ @@ -692,9 +1704,9 @@ % at the moment register_env can only do display math % \math_register_env:n { math } \RenewDocumentEnvironment{math} {b}{$#1$}{} -% and this one doesn't work either +% and this one doesn't work either % \math_register_env:n { displaymath } - \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{} + \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{} } % \end{macrocode} % \end{macro} @@ -737,29 +1749,31 @@ { \cs_gset_protected:Npn \[ % \] { - \bool_if:NTF \l_@@_collected_bool - { \begin { equation* } } - { \@@_grab_eqn:w } + \@@_grab_eqn:w + % \bool_if:NTF \l_@@_collected_bool +% { \begin { equation* } } +% { \@@_grab_eqn:w } } % \[ \cs_gset_protected:Npn \] { - \bool_if:NTF \l_@@_collected_bool - { \end{ equation* } } - { \@badmath } + \@badmath +% \bool_if:NTF \l_@@_collected_bool +% { \end{ equation* } } +% { \@badmath } } } % \end{macrocode} % \end{macro} -% +% % % \begin{macro}{\ensuremath} % A bit of nesting fun to make sure we collect only if required. % \fmi{why does ensuremath need handling at all?} -% -% \car{Indeed! Currently, this is setup to process the math that -% it has anyways already captured as its argument; thus it is more +% +% \car{Indeed! Currently, this is setup to process the math that +% it has anyways already captured as its argument; thus it is more % efficient than leaving the capture to be repeated by the \cs{everymath}} -% +% % \begin{macrocode} %\cs_gset_protected:Npn \ensuremath #1 % { @@ -786,47 +1800,6 @@ % have macro control. % \begin{macrocode} -\tl_new:N\tmpmathcontent - - -\def\@kernel@math@begin { -% \typeout{==>~math~begin} -% needs different handling if we support nesting - \tl_gset:Nx\tmpmathcontent - { - LaTeX~ formula~ starts~ - \exp_not:N\begin{\g_@@_grabbed_env_tl} - \space - \exp_not:V\g_@@_grabbed_math_tl - \space - \exp_not:N\end{\g_@@_grabbed_env_tl} - \space LaTeX~ formula~ ends~ - } - \tagstructbegin{tag=Formula, - AFinline-o=\tmpmathcontent, - title-o=\g_@@_grabbed_env_tl, - actualtext=\tmpmathcontent -% alt=\tmpmathcontent - } -% inner formula if multiple parts (not really implemented yet) - \grabaformulapartandstart -% the above does: -% \tagstructbegin{tag=Formula}\tagmcbegin{} -% or just -% \tagmcbegin{} -} -\def\@kernel@math@end { -% \typeout{==>~math~end} -% \ShowTagging{struct-stack} - \tagmcend - \if@subformulas - \tagstructend - \else - \fi - \tagstructend -% \ShowTagging{struct-stack} -} - \exp_args:No \tex_everymath:D { \tex_the:D \tex_everymath:D @@ -841,24 +1814,21 @@ { \tex_the:D \tex_everydisplay:D \iftrue % this may have to be a settable flag! -% { % \typeout{==>~ in~ everydisplay} % \end{macrocode} -% flipping the \cs{belowdisplay} values is done so that we get (assumption) -% a negative skip and not make the page bigger then we take that out, -% then we add the tagging code (in \cs{@@_tag_dollardollar_display_end} ) and -% then we put a real \cs{postdisplaypenalty} in and -% the right skip (of which we don't know if it is short or a -% normal \cs{belowdisplayskip}). This might need some refinement if that skip -% is actually negative from the start +% flipping the \cs{belowdisplay} values is done so that we get (assumption) +% a negative skip and not make the page bigger then we take that out, +% then we add the tagging code (in \cs{@@_tag_dollardollar_display_end} ) and +% then we put a real \cs{postdisplaypenalty} in and +% the right skip (of which we don't know if it is short or a +% normal \cs{belowdisplayskip}). This might need some refinement if that skip +% is actually negative from the start % (not sure it ever is and is worth bothering about) % \begin{macrocode} \skip_set:Nn \belowdisplayskip {-\belowdisplayskip} \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip} \int_set:Nn \postdisplaypenalty {10000} -% \group_insert_after:N \@@_tag_dollardollar_display_end: -% } \fi \bool_if:NF \l_@@_collected_bool { @@ -876,14 +1846,23 @@ \math_register_env:n { eqnarray* } % \end{macrocode} % -% Places where math mode is (ab)used. +% Tabulars currently contain a \$ that shouldn't trigger math +% tagging. % \begin{macrocode} -\clist_map_inline:nn - { tabular } - { - \AddToHook{ env / #1 / begin } - { \bool_set_true:N \l_@@_collected_bool } - } +\RequirePackage{array} +\tl_if_in:NnT\@tabular{$} + { + \def\@tabular{% + \leavevmode + \UseTaggingSocket{tbl/hmode/begin}% + \hbox \bgroup + \bool_set_true:N \l_@@_collected_bool + $ + \bool_set_false:N \l_@@_collected_bool + \col@sep\tabcolsep \let\d@llarbegin\begingroup + \let\d@llarend\endgroup + \@tabarray} + } % \end{macrocode} % % \begin{macro}{\@@_m@th:, \m@th} @@ -898,6 +1877,20 @@ } % \end{macrocode} % \end{macro} +% +% \subsection{Disable math grabbing in the begindocument hook} +% For example amsart uses math to measure text there. +% +% \begin{macrocode} +\tl_gput_right:Nn\@kernel@before@begindocument + { + \bool_set_true:N\l_@@_collected_bool + } +\tl_gput_right:Nn\@kernel@after@begindocument + { + \bool_set_false:N\l_@@_collected_bool + } +% \end{macrocode} % % \subsection{Modifying \pkg{amsmath}} % @@ -934,7 +1927,7 @@ $$\ignorespacesafterend } % \end{macrocode} -% +% % \begin{macrocode} \def\common@align@ending { \math@cr \black@\totwidth@ @@ -1007,9 +2000,11 @@ % \end{macrocode} % % \begin{macrocode} -% +% \math_register_halign_env:nn {align}{} \math_register_halign_env:nn {align*}{} + \math_register_halign_env:nn {alignat}{} + \math_register_halign_env:nn {alignat*}{} \math_register_halign_env:nn {flalign}{} \math_register_halign_env:nn {flalign*}{} \math_register_halign_env:nn {gather}{} @@ -1032,44 +2027,8 @@ \fi } % \end{macrocode} -% -% \begin{macrocode} - \def\intertext@{% - \def\intertext##1{% - \ifvmode\else\\\@empty\fi - \noalign{% -% we have to flip the sign on the skip because we flipped it on the outside - \penalty\postdisplaypenalty\vskip-\belowdisplayskip - \vbox{ -% \end{macrocode} -% Stop tagging when measuring: -% \begin{macrocode} - \ifmeasuring@\tag_stop:\fi - \normalbaselines - \ifdim\linewidth=\columnwidth - \else \parshape\@ne \@totalleftmargin \linewidth - \fi -% \end{macrocode} -% End the previous mc:\fmi{if we use 2 levels of formulas this would -% need changing} -% \begin{macrocode} - \tag_mc_end_push: -% \end{macrocode} -% We are already in a par so we change now to Span:\fmi{not true any longer} -% \begin{macrocode} - \tagpdfsetup{paratag=P}% - \tagpdfparaOn - \noindent\ignorespaces##1\par -% \end{macrocode} -% Restart the MC -% \begin{macrocode} - \tag_mc_begin_pop:n{}}% - \penalty\predisplaypenalty\vskip\abovedisplayskip% - }% - } - } -% \end{macrocode} -% +% +% % \begin{macrocode} \@namedef{math@cr @ @ @ gather}{% \ifst@rred\nonumber\fi @@ -1083,7 +2042,7 @@ \cr } % \end{macrocode} -% +% % \begin{macrocode} \@namedef{math@cr @ @ @ align}{% \ifst@rred\nonumber\fi @@ -1104,7 +2063,7 @@ \cr } % \end{macrocode} -% +% % \begin{macrocode} \def\restore@math@cr{\@namedef{math@cr @ @ @}{ % @@ -1113,7 +2072,7 @@ \cr}} \restore@math@cr % \end{macrocode} -% +% % \begin{macrocode} } % \end{macrocode} @@ -1125,9 +2084,18 @@ % % -% \begin{macro}{} +% \begin{macro}{\@@_split_at_nl:NN} +% This splits grabbed math at newlines. % % \begin{macrocode} +\cs_new:Npn \@@_split_at_nl:NN #1#2 { + \tl_set:Nf \l_@@_tmpa_tl { + \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } + \exp_after:wN \@@_split_at_nl_aux:nnNN \l_@@_tmpa_tl #1 #2 +} +% \end{macrocode} +% and the auxiliary commands +% \begin{macrocode} \cs_new:Npn \@@_split_at_nl_first:w #1 \\ #2 \\ #3 \s_stop { \quark_if_nil:nTF {#2} @@ -1137,8 +2105,15 @@ #2 \\ #3 \s_stop } } -\cs_new:Npn \@@_split_chk_if_begin:ww #1 \begin #2 #3 \s_mark - #4 \\ \q_nil \\ \s_stop + +\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4 + { + \tl_gset:Nn #4 {#1} + \tl_gset:Nn #3 {#2} + } + +\cs_new:Npn \@@_split_chk_if_begin:ww + #1 \begin #2 #3 \s_mark #4 \\ \q_nil \\ \s_stop { \quark_if_nil:nTF {#2} { {#1} {#4} } @@ -1148,7 +2123,9 @@ { } { 1 } } } + \cs_new:Npn \@@_split_cleanup_begin_q_nil:w #1 \begin \q_nil {#1} + \cs_new:Npn \@@_split_collect_one_end:w #1 \end #2 #3 \s_stop #4 #5 { \exp_args:Nf \@@_split_check_count_begins:nnnn @@ -1157,14 +2134,16 @@ } \cs_new:Npn \@@_split_count_begins:n #1 { \int_eval:n { 0 \@@_split_count_begins:w #1 \begin \q_nil } } + \cs_new:Npn \@@_split_count_begins:w #1 \begin #2 { \quark_if_nil:nF {#2} { +1 \@@_split_count_begins:w } } + \cs_new:Npn \@@_split_check_count_begins:nnnn #1 #2 #3 #4 { \int_compare:nNnTF {#1} = {#2} { \exp_last_unbraced:Nf \@@_split_final_cleanup:nn - { \split:n { \@@_split_guard:n {#3} #4 } } + { \@@_split:n { \@@_split_guard:n {#3} #4 } } } { \exp_args:No \use_ii_i:nn @@ -1184,29 +2163,17 @@ { \exp_end: { #4 #1 } } { \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } } } -\NewDocumentCommand \splitnl { mm +m } - { - \tl_set:Nf \l_tmpa_tl { \split:n {#3} } - \show \l_tmpa_tl - \exp_after:wN \__splitnl_aux:nnNN \l_tmpa_tl #1 #2 - } - - -\cs_new:Npn \split:n #1 { + +\cs_new:Npn \@@_split:n #1 { \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } - -\cs_new:Npn \@@_split_at_nl:NN #1#2 { - \tl_set:Nf \l_tmpa_tl { - \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop } - \exp_after:wN \@@_split_at_nl_aux:nnNN \l_tmpa_tl #1 #2 -} - -\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4 - { - \tl_gset:Nn #4 {#1} - \tl_gset:Nn #3 {#2} -} - + +% this looks unused. +%\NewDocumentCommand \splitnl { mm +m } +% { +% \tl_set:Nf \l_@@_tmpa_tl { \split:n {#3} } +% \show \l_@@_tmpa_tl +% \exp_after:wN \__splitnl_aux:nnNN \l_@@_tmpa_tl #1 #2 +% } % \end{macrocode} % \end{macro} % @@ -1233,9 +2200,11 @@ \edef\resulttitle{\g_@@_grabbed_env_tl\space (part)} \tagstructbegin{tag=Formula, % \end{macrocode} -% For now we don't put anything in /alt or /ActualText on subformulas +% For now we don't put real content in /alt or /ActualText on subformulas +% but we add a short text to satisfy the pdf/ua-2 validator % \begin{macrocode} % alt=\result, + alt = subformula, title-o=\resulttitle } } @@ -1301,10 +2270,6 @@ % \end{macrocode} % % \begin{macrocode} -% -% \end{macrocode} -% -% \begin{macrocode} % % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx index 14d8e943624..31e7d31ef62 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx @@ -2,7 +2,7 @@ % %% File: latex-lab-mathpkg.dtx % -% Copyright (C) 2022,2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -68,15 +68,8 @@ \ProvidesFile{latex-lab-mathpkg.ltx} [2023-01-05 v0.1a mathpkg adaptions] % \end{macrocode} -% \subsection{Tagpdf support} -% To make the code independent from tagging being loaded and active -% we load the \pkg{tagpdf-base} package: -% -% \begin{macrocode} -\RequirePackage{tagpdf-base} -% \end{macrocode} -% % +% \subsection{breqn} % \begin{macrocode} \AddToHook{package/breqn/after}{ \RegisterMathEnvironment{dmath} @@ -86,6 +79,7 @@ } % \end{macrocode} % +% \subsection{cases} % Force loading of \pkg{amsmath} before \pkg{cases}. % \begin{macrocode} \AddToHook {package/cases/before}{\RequirePackage{amsmath}} @@ -94,6 +88,29 @@ } % \end{macrocode} % +% \subsection{bm} +% Similar to the amsbsy code in latex-lab-amsmath for \cs{pmb} we need to mark up +% copies as artifact: +% +% \begin{macrocode} +\ExplSyntaxOn +\AddToHook{package/bm/after} + { + \def\bm@pmb@@@@#1#2#3{{% + \hbox_set:Nn\l_@@_tmpa_box{$\m@th#1#3$}% + \dimen@#2\wd\tw@ + \rlap{\box_use:N\l_@@_tmpa_box}% + \tag_mc_end:\tag_mc_begin:n{artifact} + \tag_mc_reset_box:N\l_@@_tmpa_box + \kern\dimen@ + \raise1.5\dimen@\rlap{\box_use:N\l_@@_tmpa_box}% + \kern\dimen@ + \box_use_drop:N\l_@@_tmpa_box + \tag_mc_end:\tag_mc_begin:n{}% + }} + } +\ExplSyntaxOff +% \end{macrocode} % \begin{macrocode} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx index c3f43243b10..aa27cbf01d9 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx @@ -2,7 +2,7 @@ % %% File: latex-lab-mathtools.dtx % -% Copyright (C) 2022,2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -109,7 +109,7 @@ \def\intertext##1{% \ifvmode\else\\\@empty\fi \noalign{% - \penalty\postdisplaypenalty\vskip\belowdisplayskip + \penalty\postdisplaypenalty\vskip-\belowdisplayskip \vskip-\lineskiplimit % CCS \vskip\normallineskiplimit % CCS \vskip\l_MT_above_intertext_sep @@ -135,7 +135,7 @@ % \end{macrocode} % We are already in a par so we change now to Span: % \begin{macrocode} - \tagpdfsetup{paratag=Span} + \tagpdfsetup{para/tag=Span} \noindent\ignorespaces##1\par % \end{macrocode} % Restart the MC @@ -169,7 +169,8 @@ \parshape\@ne \@totalleftmargin \linewidth \MH_fi: \tag_mc_end_push: - \tagpdfsetup{paratag=Span} + \tagpdfsetup{para/tag=Span} + \tagpdfparaOn \noindent\ignorespaces#1\par \tag_mc_begin_pop:n{}} \penalty\predisplaypenalty\vskip\abovedisplayshortskip% @@ -197,7 +198,11 @@ \parshape\@ne \@totalleftmargin \linewidth \MH_fi: \tag_mc_end_push: - \tagpdfsetup{paratag=Span} + \tagpdfsetup{para/tag=P} +% \end{macrocode} +% Why is it needed to enable paratagging?? +% \begin{macrocode} + \tagpdfparaOn \noindent\ignorespaces#1\par \tag_mc_begin_pop:n{}}% \penalty\predisplaypenalty\vskip\abovedisplayshortskip% diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx index 1d3ee828aa4..ffbe5357e76 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx @@ -1,6 +1,8 @@ % \iffalse meta-comment % -%% File: latex-lab-minipage.dtx (C) Copyright 2023 LaTeX Project +%% File: latex-lab-minipage.dtx +%% +% Copyright (C) 2023-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx index 2ec9b0584bf..cfc06c7b093 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx @@ -1,6 +1,8 @@ % \iffalse meta-comment % -%% File: latex-lab-namespace.dtx (C) Copyright 2023 LaTeX Project +%% File: latex-lab-namespace.dtx +%% +% Copyright (C) 2023-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -24,7 +26,7 @@ % \fi % \title{Prototype reimplementation of \LaTeXe{}'s role mapping} % \author{\LaTeX{} Project, initial implementation Ulrike Fischer} -% \date{v0.8 2023-09-04} +% \date{v0.8b 2024-03-24} % % \maketitle % @@ -60,18 +62,33 @@ % \begin{macrocode} title, Title, pdf2, part, Title, pdf2, +% \end{macrocode} +% Headings differ in article and book class. This here is for article: +% \begin{macrocode} section, H1, pdf2, subsection, H2, pdf2, subsubsection,H3, pdf2, paragraph, H4, pdf2, subparagraph, H5, pdf2, +% \end{macrocode} +% And this here is used in book: +% \begin{macrocode} +%chapter, H1, pdf2, +%section, H2, pdf2, +%subsection, H3, pdf2, +%subsubsection, H4, pdf2, +%paragraph, H5, pdf2, +%subparagraph, H6, pdf2, +% \end{macrocode} +% +% \begin{macrocode} list, L, pdf2, itemize, L, pdf2, enumerate, L, pdf2, description, L, pdf2, quote, BlockQuote,pdf, quotation, BlockQuote,pdf, -verbatim, Div, pdf2, +verbatim, Div, pdf2, % overwritten by block item, LI, pdf2, itemlabel, Lbl, pdf2, itembody, LBody, pdf2, diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx index cc60f50de01..9994b15cb8d 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-new-or-1.dtx (C) Copyright 2020-2023 Frank Mittelbach +%% File: latex-lab-new-or-1.dtx (C) Copyright 2020-2024 Frank Mittelbach % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx index d2011256b1a..ee20331a8f4 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % %% File: latex-lab-new-or-2.dtx -% Copyright (C) 2022-2023 The LaTeX Project +% Copyright (C) 2022-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx index ae7a0b85c30..f3786c2ddb8 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-sec.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-sec.dtx (C) Copyright 2022-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -16,10 +16,10 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabsecdate{2023-10-16} -\def\ltlabsecversion{0.84b} +\def\ltlabsecdate{2024-02-12} +\def\ltlabsecversion{0.84c} %<*driver> -\documentclass{l3doc} +\documentclass[kernel]{l3doc} \EnableCrossrefs \CodelineIndex \begin{document} @@ -214,11 +214,11 @@ \fi \IfBooleanTF {#1} { - \tl_gset:Nx \@currentHref {#3} + \tl_gset:Ne \@currentHref {#3} } { \int_gincr:N\g__kernel_target_int - \tl_gset:Nx \@currentHref {target*.\int_use:N\g__kernel_target_int} + \tl_gset:Ne \@currentHref {target*.\int_use:N\g__kernel_target_int} } } \ExplSyntaxOff @@ -260,7 +260,7 @@ tag= {\int_compare:nNnTF {#1}={-1}{Part}{Sect}} ,#2 } - \seq_gpush:Nx \g__tag_sec_stack_seq {{\g__tag_struct_tag_tl}{\int_eval:n{#1}}} + \seq_gpush:Ne \g__tag_sec_stack_seq {{\g__tag_struct_tag_tl}{\int_eval:n{#1}}} } % \end{macrocode} % \end{macro} @@ -289,7 +289,7 @@ \__tag_sec_end:n {#1} } { - \msg_warning:nnxx {tag}{wrong-sect-nesting} + \msg_warning:nnee {tag}{wrong-sect-nesting} { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpa_tl } { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpb_tl } } @@ -670,6 +670,7 @@ \cs_new_protected:Npn \@kernel@tag@hangfrom #1 { \tagstructbegin{tag=\l__tag_para_tag_tl} + \cs_if_exist_use:N \__tag_gincr_para_begin_int: \tagstructbegin{tag=Lbl} \setbox\@tempboxa \hbox diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx index 700d4ce6c17..38596478aeb 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-table.dtx (C) Copyright 2023 LaTeX Project +%% File: latex-lab-table.dtx (C) Copyright 2023-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -16,8 +16,8 @@ % % for those people who are interested or want to report an issue. % -\def\ltlabtbldate{2023-10-30} -\def\ltlabtblversion{0.85d} +\def\ltlabtbldate{2024-05-25} +\def\ltlabtblversion{0.85i} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -115,9 +115,20 @@ % Such tables can be nested. % % If a table should not be tagged as table, for example because it is merely used -% to produce a layout or because it is a not yet (fully) supported table structure, +% as a layout to ensure that the content is properly aligned +% or because it is a not yet (fully) supported table structure, % the tagging can be disabled with -% \verb|\tagpdfsetup{table-tagging=false}|. +% \verb|\tagpdfsetup{table/tagging=false}| or with \verb|\tagpdfsetup{table/tagging=presentation}|% +% \footnote{The key has been renamed. The old name `table-tagging` still works but is +% deprecated. The value \texttt{presentation} refers to the ARIA role \enquote{presentation}.} +% The first option disables the table tagging code and the content of the tabular +% is then treated more or less like running text. This works ok for simple tables using +% only hmode-cells (l/c/r) with normal text content, but fails if the table uses vmode-cells +% (p/m/b). In such cases the second option works better: it keeps the tagging code active +% but changes the tag names to \texttt{Div} and the grouping structure \texttt{NonStruct}. It also +% (re)sets the \texttt{table/header-rows} key to empty. +% The key should currently only be used in a group as there is no key (yet) to reset to the default +% tag names. % % Inside cells the automatic tagging of paragraphs is disabled with the exception of % p/m/b-type cells. @@ -126,9 +137,10 @@ % added with an empty TD-structure. % % There is some basic support\footnote{This is not meant to be the -% final interface, though.} for headers. With +% final interface, though.} for headers. With\footnote{The old key name \texttt{table-header-rows} still +% works but is deprecated.} % \begin{quote} -% \verb|\tagpdfsetup{table-header-rows={|\meta{list of row numbers}\verb|}| +% \verb|\tagpdfsetup{table/header-rows={|\meta{list of row numbers}\verb|}| % \end{quote} % you can % declare which (absolute) row numbers should be tagged as header rows. @@ -139,7 +151,7 @@ % for header columns yet. In a \env{longtable} the code will currently use the \cs{endhead} or % \cs{endfirsthead} rows as header if one of these commands has been % used and in that case the code -% ignores a \texttt{table-header-rows} setting. +% ignores a \texttt{table/header-rows} setting. % % You should not insert meaningful text with \verb+!{...}+ or \verb+@{...}+ or \cs{noalign} % between the rows or columns of the table. @@ -193,7 +205,8 @@ % % \item Not every table should be tagged as a Table structure, often they are % only used as layout help, e.g. to align authors in a title pages. In such uses -% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table-tagging=false}|. +% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table/tagging=false}| +% or \verb|\tagpdfsetup{table/tagging=presentation}|. % % \item Only simple header rows are currently supported. Columns and complex headers with % subheaders will be handled later as that needs some syntax changes. Tables @@ -210,6 +223,8 @@ % % \item The \env{longtable} environment supports footnotes in p-type columns, but it hasn't been % tested yet if this works also with the tagging code. +% +% \item Vertical boxes (\cs{parbox}, \texttt{minipage}, \ldots) inside cells can be problematic. % % \item The code is quite noisy and fills the log with lots of % messages.\footnote{Helpful for us at this stage.} @@ -271,10 +286,11 @@ % \begin{macro} % { % \l_@@_celltag_tl +% \l_@@_pcelltag_tl % ,\l_@@_rowtag_tl +% ,\l_@@_table_tl % ,\l_@@_cellattribute_tl % ,\l_@@_rowattribute_tl -% ,\g_@@_missingcells_int % ,\l_@@_tmpa_clist % ,\l_@@_tmpa_seq % ,\l_@@_tmpa_tl @@ -283,12 +299,19 @@ % \begin{macrocode} \tl_new:N \l_@@_celltag_tl \tl_set:Nn \l_@@_celltag_tl {TD} +\tl_new:N \l_@@_pcelltag_tl +\tl_set:Nn \l_@@_pcelltag_tl {TD} % \end{macrocode} % For the rowtag, probably always TR: % \begin{macrocode} \tl_new:N \l_@@_rowtag_tl \tl_set:Nn \l_@@_rowtag_tl {TR} % \end{macrocode} +% For the tabletag, probably always Table: +% \begin{macrocode} +\tl_new:N \l_@@_tabletag_tl +\tl_set:Nn \l_@@_tabletag_tl {Table} +% \end{macrocode} % And here cell and row attributes: % \begin{macrocode} \tl_new:N \l_@@_cellattribute_tl @@ -296,94 +319,27 @@ \tl_new:N \l_@@_rowattribute_tl \tl_set:Nn \l_@@_rowattribute_tl {} % \end{macrocode} -% This will contain the number of missing cells used: -% \begin{macrocode} -\int_new:N \g_@@_missing_cells_int -% \end{macrocode} % Temp variables % \begin{macrocode} \clist_new:N \l_@@_tmpa_clist -\seq_new:N \l_@@_tmpa_seq \tl_new:N \l_@@_tmpa_tl % \end{macrocode} % \end{macro} % -% \subsection{Sockets} -% -% The code uses a number of sockets to inject the tagging -% commands. These can be easily set to a noop-plug in case the -% automated tagging is not wanted At first sockets for the begin and -% end of cells and rows -% -% \begin{socketdecl}{tagsupport/tblcell/begin, -% tagsupport/tblcell/end, -% tagsupport/tblrow/begin, -% tagsupport/tblrow/end, -% } -% \begin{macrocode} -\NewSocket{tagsupport/tblcell/begin}{0} -\NewSocket{tagsupport/tblcell/end}{0} -\NewSocket{tagsupport/tblrow/begin}{0} -\NewSocket{tagsupport/tblrow/end}{0} -% \end{macrocode} -% \end{socketdecl} -% -% \begin{socketdecl}{tagsupport/tbl/init} -% This socket should be at the begin of the table, inside a group. -% It is meant for settings like disabling paratagging. This socket -% can perhaps be merged later into the begin-sockets when they are -% no longer added as hooks but in the environment definitions. -% \begin{macrocode} -\NewSocket{tagsupport/tbl/init}{0} -% \end{macrocode} -% \end{socketdecl} -% -% -% \begin{socketdecl}{tagsupport/tbl/finalize} -% To fine tune the structure (change cells to header cells, remove -% unwanted structures, move a foot to the end, etc.) we also need a -% socket that is executed at the end of the table but \emph{before} -% all the variables are restored to the outer or default values. -% The code in the socket can make assignments, but probably -% shouldn't do typesetting and not write whatsits. -% \begin{macrocode} -\NewSocket{tagsupport/tbl/finalize}{0} -% \end{macrocode} -% \end{socketdecl} +% \subsection{Tagging support sockets} % -% \begin{socketdecl}{tagsupport/tbl/finalize/longtable} -% \env{longtable} needs its own socket to fine tune the structure. -% Simply switching the plug in the previous socket interferes with -% enabling/disabling the tagging. -% \begin{macrocode} -\NewSocket{tagsupport/tbl/finalize/longtable}{0} -% \end{macrocode} -% \end{socketdecl} -% -% \begin{socketdecl}{tagsupport/tblhmode/begin, -% tagsupport/tblhmode/end, -% tagsupport/tblvmode/begin, -% tagsupport/tblvmode/end -% } -% -% These sockets are used in the begin and end code of environments, -% to allow a fast enabling and disabling of the tagging. We -% distinguish between tables that can be used inside paragraphs and -% standalone tables like longtable. -% \begin{macrocode} -\NewSocket{tagsupport/tblhmode/begin}{0} -\NewSocket{tagsupport/tblhmode/end}{0} -\NewSocket{tagsupport/tblvmode/begin}{0} -\NewSocket{tagsupport/tblvmode/end}{0} -% \end{macrocode} -% \end{socketdecl} % % This are the standard plugs for tagging of cells and rows. % % \begin{plugdecl}{TD} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblcell/begin}{TD} +\NewSocketPlug{tagsupport/tbl/cell/begin}{TD} { +% \end{macrocode} +% Next line was previously outside of the plug, so if we want to execute it +% always even if the noop plug is in force this needs a different solution. +% \begin{macrocode} + \@@_show_curr_cell_data: \tag_struct_begin:n { tag =\l_@@_celltag_tl, @@ -405,7 +361,7 @@ % % \begin{plugdecl}{TD} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblcell/end}{TD} +\NewSocketPlug{tagsupport/tbl/cell/end}{TD} { \tag_mc_end: \tag_struct_end: @@ -415,14 +371,14 @@ % % In p-columns we need a slightly different plug which reactivates the % paragraph tagging. -% tagging -% \begin{plugdecl}{TD} +% \begin{plugdecl}{TDpbox} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblcell/begin}{TDpbox} +\NewSocketPlug{tagsupport/tbl/pcell/begin}{TDpbox} { + \@@_show_curr_cell_data: \tag_struct_begin:n { - tag =\l__tbl_celltag_tl, + tag =\l__tbl_pcelltag_tl, attribute-class =\l__tbl_cellattribute_tl } \seq_gput_right:Ne \g__tbl_struct_cur_seq { \tag_get:n {struct_num} } @@ -436,9 +392,9 @@ % \end{macrocode} % \end{plugdecl} % -% \begin{plugdecl}{TD} +% \begin{plugdecl}{TDpbox} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblcell/end}{TDpbox} +\NewSocketPlug{tagsupport/tbl/pcell/end}{TDpbox} { \tag_struct_end: } @@ -447,7 +403,7 @@ % % \begin{plugdecl}{TR} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblrow/begin}{TR} +\NewSocketPlug{tagsupport/tbl/row/begin}{TR} { \seq_gclear:N \g_@@_struct_cur_seq \tag_struct_begin:n @@ -462,24 +418,28 @@ % % \begin{plugdecl}{TR} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblrow/end}{TR} +\NewSocketPlug{tagsupport/tbl/row/end}{TR} { - \__tag_tbl_add_missing_cells:n { \g_@@_missing_cells_int } + \tag_if_active:T + { + \@@_add_missing_cells: \seq_gput_right:Ne \g_@@_struct_cells_seq { \seq_use:Nn \g_@@_struct_cur_seq {,} } - \int_compare:nNnTF { \g_@@_row_int } = { \seq_count:N\g_@@_struct_cells_seq } + \int_compare:nNnTF { \g_@@_row_int } = + { \seq_count:N \g_@@_struct_cells_seq } { - \typeout + \@@_trace:n {==>~ stucture~stored~for~row~\int_use:N\g_@@_row_int :~ \seq_use:Nn \g_@@_struct_cur_seq {,} } } - { \ERROR } % should not happen ... + { \ERRORtbl/row } % should not happen ... \tag_struct_end: } + } % \end{macrocode} % \end{plugdecl} % @@ -497,6 +457,10 @@ \tag_if_active:T { \bool_set_false:N \l__tag_para_bool +% \end{macrocode} +% We also initialize the structure data variables a this point. +% \begin{macrocode} + \@@_init_struct_data: } } % \end{macrocode} @@ -509,14 +473,41 @@ \NewSocketPlug{tagsupport/tbl/finalize}{Table} { \@@_set_header_rows: +% \end{macrocode} +% Similarly, we restore the outer values of the structure data when +% we leave the table. +% \begin{macrocode} + \@@_restore_struct_data: } % \end{macrocode} % \end{plugdecl} % +% +% +% +% \begin{plugdecl}{Table} +% This plug will initialize the structure in longtable. +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/longtable/init}{Table} + { + \seq_gclear:N\g_@@_struct_rows_seq + \seq_gclear:N\g_@@_struct_cells_seq + \seq_gclear:N\g_@@_struct_cur_seq + \seq_gclear:N\g_@@_LT@firsthead_rows_seq + \seq_gclear:N\g_@@_LT@head_rows_seq + \seq_gclear:N\g_@@_LT@lastfoot_rows_seq + \seq_gclear:N\g_@@_LT@foot_rows_seq + } +% \end{macrocode} +% \end{plugdecl} +% +% + + % \begin{plugdecl}{Table} -% This plug will fine tune the structure of longtable. +% This plug will fine tune the structure in longtable. % \begin{macrocode} -\NewSocketPlug{tagsupport/tbl/finalize/longtable}{Table} +\NewSocketPlug{tagsupport/tbl/longtable/finalize}{Table} { % \end{macrocode} % If neither \cs{endhead} nor \cs{endfirsthead} has been used @@ -582,7 +573,7 @@ \prop_if_exist:cT { g__tag_struct_ \l_@@_tmpa_tl _prop } { - \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact} + \exp_args:No \__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact} } } } @@ -673,7 +664,7 @@ \prop_if_exist:cT { g__tag_struct_ \l_@@_tmpa_tl _prop } { - \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact} + \exp_args:No\__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact} } } } @@ -683,11 +674,40 @@ % \end{macrocode} % \end{plugdecl} % +% +% +% \begin{plugdecl}{Table} +% +% We must avoid that the reuse of the header foot box leads to duplicated +% content, thus reset attribute of the box: +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/longtable/head}{Table} + { + \tagmcbegin{artifact} + \tag_mc_reset_box:N\LT@head + \tagmcend + } +% \end{macrocode} +% \end{plugdecl} +% % \begin{plugdecl}{Table} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblhmode/begin}{Table} +\NewSocketPlug{tagsupport/tbl/longtable/foot}{Table} + { + \tagmcbegin{artifact} + \tag_mc_reset_box:N \LT@foot + \tagmcend + } +% \end{macrocode} +% \end{plugdecl} +% +% +% +% +% \begin{plugdecl}{Table} +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/hmode/begin}{Table} { - \mode_leave_vertical: \tag_mc_end_push: % \end{macrocode} % Close the P-chunk. This assumes that para-tagging is active. @@ -696,7 +716,7 @@ \bool_lazy_and:nnT { \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool } { \tag_struct_end:n { text } } - \tag_struct_begin:n {tag=Table} + \tag_struct_begin:n {tag=\l_@@_tabletag_tl} \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} } } % \end{macrocode} @@ -704,7 +724,7 @@ % % \begin{plugdecl}{Table} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblhmode/end}{Table} +\NewSocketPlug{tagsupport/tbl/hmode/end}{Table} { \tag_struct_end: % \end{macrocode} @@ -721,9 +741,9 @@ % % \begin{plugdecl}{Table} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblvmode/begin}{Table} +\NewSocketPlug{tagsupport/tbl/vmode/begin}{Table} { - \tag_struct_begin:n {tag=Table} + \tag_struct_begin:n {tag=\l_@@_tabletag_tl} \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} } } % \end{macrocode} @@ -731,7 +751,7 @@ % % \begin{plugdecl}{Table} % \begin{macrocode} -\NewSocketPlug{tagsupport/tblvmode/end}{Table} +\NewSocketPlug{tagsupport/tbl/vmode/end}{Table} { \tag_struct_end: \par @@ -740,30 +760,50 @@ % \end{plugdecl} % % +% \begin{plugdecl}{code} +% This socket takes a number, checks if is larger than one, +% checks if the colspan attribute already exists (we can't predefine an +% arbitrary number), and updates \cs{l_@@_cellattribute_tl}. +% \begin{macrocode} +\NewSocketPlug{tagsupport/tbl/colspan}{code} + { + \int_compare:nNnT {#1}>{1} + { + \prop_get:NeNF \g__tag_attr_entries_prop + {colspan-\int_eval:n{#1}} + \l_@@_tmpa_tl + { + \__tag_attr_new_entry:ee + {colspan-\int_eval:n{#1}} + {/O /Table /ColSpan~\int_eval:n{#1}} + } + \tl_set:Ne \l_@@_cellattribute_tl + {colspan-\int_eval:n{#1}} + } + } +% \end{macrocode} +% TODO: move to tagpdf +% \begin{macrocode} +\tag_if_active:T + { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} } + +% \end{macrocode} +% \end{plugdecl} % % % %\subsection{Environments} % -% Currently only tabular, tabular*, tabularx and longtable. -% We must use the \texttt{before} and \texttt{after} hooks as the \texttt{end} -% hook is executed before the end of the last row and then MC are messed up. -% This means that this sockets should only contain code that doesn't needs to be -% grouped! -% \begin{macrocode} -\AddToHook{env/tabular/before} {\UseSocket{tagsupport/tblhmode/begin}} -\AddToHook{env/tabular/after} {\UseSocket{tagsupport/tblhmode/end}} -\AddToHook{env/tabular*/before} {\UseSocket{tagsupport/tblhmode/begin}} -\AddToHook{env/tabular*/after} {\UseSocket{tagsupport/tblhmode/end}} -\AddToHook{env/tabularx/before} {\UseSocket{tagsupport/tblhmode/begin}} -\AddToHook{env/tabularx/after} {\UseSocket{tagsupport/tblhmode/end}} -\AddToHook{env/longtable/before}{\UseSocket{tagsupport/tblvmode/begin}} -\AddToHook{env/longtable/after} {\UseSocket{tagsupport/tblvmode/end}} -% \end{macrocode} +% Currently we support only tabular, tabular*, tabularx and longtable +% (and possibly environments build directly on top of them). % % The \env{array} environment is math. So we disable table tagging for now. +% We use the command hook to catch also cases where \cs{array} is used directly +% in other environments like matrix environments. +% Perhaps table tagging should be disable for math generally, but then +% we have to handle text insertions. % \begin{macrocode} -\AddToHook{env/array/begin} {\__tag_tbl_disable:} +\AddToHook{cmd/array/before}{\__tag_tbl_disable:} % \end{macrocode} % % @@ -771,34 +811,6 @@ % % \subsubsection{Tagging helper commands} % -% \begin{macro}{\@@_set_colspan:n} -% This commands takes a number, checks if is larger than one, -% checks if the colspan attribute exists (we can't predefine an -% arbitrary number), and updates \cs{l_@@_cellattribute_tl}. -% \begin{macrocode} -\tag_if_active:T - { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} } -\cs_new_protected:Npn \@@_set_colspan:n #1 - { - \tag_if_active:T - { - \int_compare:nNnT {#1}>{1} - { - \prop_get:NeNF \g__tag_attr_entries_prop - {colspan-\int_eval:n{#1}} - \l_@@_tmpa_tl - { - \__tag_attr_new_entry:ee - {colspan-\int_eval:n{#1}} - {/O /Table /ColSpan~\int_eval:n{#1}} - } - \tl_set:Ne \l_@@_cellattribute_tl - {colspan-\int_eval:n{#1}} - } - } - } -% \end{macrocode} -% \end{macro} % % \subsubsection{Disabling/enabling} % @@ -810,17 +822,23 @@ % \begin{macrocode} \cs_new_protected:Npn \__tag_tbl_disable: { - \AssignSocketPlug{tagsupport/tblcell/begin}{noop} - \AssignSocketPlug{tagsupport/tblcell/end}{noop} - \AssignSocketPlug{tagsupport/tblrow/begin}{noop} - \AssignSocketPlug{tagsupport/tblrow/end}{noop} + \AssignSocketPlug{tagsupport/tbl/cell/begin}{noop} + \AssignSocketPlug{tagsupport/tbl/cell/end}{noop} + \AssignSocketPlug{tagsupport/tbl/pcell/begin}{noop} + \AssignSocketPlug{tagsupport/tbl/pcell/end}{noop} + \AssignSocketPlug{tagsupport/tbl/row/begin}{noop} + \AssignSocketPlug{tagsupport/tbl/row/end}{noop} \AssignSocketPlug{tagsupport/tbl/init}{noop} \AssignSocketPlug{tagsupport/tbl/finalize}{noop} - \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{noop} - \AssignSocketPlug{tagsupport/tblhmode/begin}{noop} - \AssignSocketPlug{tagsupport/tblhmode/end}{noop} - \AssignSocketPlug{tagsupport/tblvmode/begin}{noop} - \AssignSocketPlug{tagsupport/tblvmode/end}{noop} + \AssignSocketPlug{tagsupport/tbl/longtable/init}{noop} + \AssignSocketPlug{tagsupport/tbl/longtable/head}{noop} + \AssignSocketPlug{tagsupport/tbl/longtable/foot}{noop} + \AssignSocketPlug{tagsupport/tbl/longtable/finalize}{noop} + \AssignSocketPlug{tagsupport/tbl/hmode/begin}{noop} + \AssignSocketPlug{tagsupport/tbl/hmode/end}{noop} + \AssignSocketPlug{tagsupport/tbl/vmode/begin}{noop} + \AssignSocketPlug{tagsupport/tbl/vmode/end}{noop} + \AssignSocketPlug{tagsupport/tbl/colspan}{noop} } % \end{macrocode} % \end{macro} @@ -831,46 +849,59 @@ % \begin{macrocode} \cs_new_protected:Npn \__tag_tbl_enable: { - \AssignSocketPlug{tagsupport/tblcell/begin}{TD} - \AssignSocketPlug{tagsupport/tblcell/end}{TD} - \AssignSocketPlug{tagsupport/tblrow/begin}{TR} - \AssignSocketPlug{tagsupport/tblrow/end}{TR} + \AssignSocketPlug{tagsupport/tbl/cell/begin}{TD} + \AssignSocketPlug{tagsupport/tbl/cell/end}{TD} + \AssignSocketPlug{tagsupport/tbl/pcell/begin}{TDpbox} + \AssignSocketPlug{tagsupport/tbl/pcell/end}{TDpbox} + \AssignSocketPlug{tagsupport/tbl/row/begin}{TR} + \AssignSocketPlug{tagsupport/tbl/row/end}{TR} \AssignSocketPlug{tagsupport/tbl/init}{Table} \AssignSocketPlug{tagsupport/tbl/finalize}{Table} - \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{Table} - \AssignSocketPlug{tagsupport/tblhmode/begin}{Table} - \AssignSocketPlug{tagsupport/tblhmode/end}{Table} - \AssignSocketPlug{tagsupport/tblvmode/begin}{Table} - \AssignSocketPlug{tagsupport/tblvmode/end}{Table} + \AssignSocketPlug{tagsupport/tbl/longtable/head}{Table} + \AssignSocketPlug{tagsupport/tbl/longtable/foot}{Table} + \AssignSocketPlug{tagsupport/tbl/longtable/init}{Table} + \AssignSocketPlug{tagsupport/tbl/longtable/finalize}{Table} + \AssignSocketPlug{tagsupport/tbl/hmode/begin}{Table} + \AssignSocketPlug{tagsupport/tbl/hmode/end}{Table} + \AssignSocketPlug{tagsupport/tbl/vmode/begin}{Table} + \AssignSocketPlug{tagsupport/tbl/vmode/end}{Table} + \AssignSocketPlug{tagsupport/tbl/colspan}{code} } % \end{macrocode} % \end{macro} % \begin{macrocode} -% TODO decide about key name +% See tagpdfsetup-keys.md in tagpdf/doc for the naming scheme. \keys_define:nn { __tag / setup } { - table-tagging .choices:nn = { true, on } + table/tagging .choices:nn = { true, on } { \__tag_tbl_enable: }, - table-tagging .choices:nn = { false, off } + table/tagging .choices:nn = { false, off } { \__tag_tbl_disable: }, - table-tagging .default:n = true, - table-tagging .initial:n = true + table/tagging .choice:, + table/tagging / presentation .code:n = + { + \__tag_tbl_enable: + \tl_set:Nn\l_@@_rowtag_tl {NonStruct} + \tl_set:Nn\l_@@_pcelltag_tl {NonStruct} + \tl_set:Nn\l_@@_celltag_tl {text} + \tl_set:Nn\l_@@_tabletag_tl {Div} + \clist_clear:N \l_@@_header_rows_clist + }, + table/tagging .default:n = true, + table/tagging .initial:n = true } % \end{macrocode} -% -% Table tagging should be disabled in the head and foot. +% This are the old key names kept for now for +% compability. They will got at some time. % \begin{macrocode} -\AddToHook{begindocument} - { - \cs_if_exist:NT \@kernel@before@head - { - \tl_put_right:Nn \@kernel@before@head {\__tag_tbl_disable:} - \tl_put_right:Nn \@kernel@before@foot {\__tag_tbl_disable:} - } - } +\keys_define:nn { __tag / setup } + { + table-tagging .meta:n = {table/tagging={#1}} + } % \end{macrocode} % +% % \subsubsection{Header support} % % Accessible table must have header cells declaring the meaning of the @@ -900,17 +931,17 @@ { \tagpdfsetup { - newattribute = + role/new-attribute = {TH-col}{/O /Table /Scope /Column}, - newattribute = + role/new-attribute = {TH-row}{/O /Table /Scope /Row}, - newattribute = + role/new-attribute = {TH-both}{/O /Table /Scope /Both}, } % \end{macrocode} % % And we put all three into the class map (perhaps the next tagpdf -% should do that directly with newattribute): +% should do that directly with role/new-attribute): % % \begin{macrocode} \seq_gput_left:Ne\g__tag_attr_class_used_seq @@ -926,28 +957,13 @@ % % \begin{variable}{\l_@@_header_rows_clist} % This holds the numbers of the header rows. Negative numbers are -% possible and count from the back. +% possible and count from the last column backwards. % \begin{macrocode} \clist_new:N \l_@@_header_rows_clist % \end{macrocode} % \end{variable} % % \begin{macro}{\@@_set_header_rows:} -% TEMP: Next tagpdf will have the right command which also updates -% the debug info. -% For now a temporary command: -% \begin{macrocode} -\cs_if_free:NTF \__tag_struct_prop_gput:nnn - { - \cs_new_protected:Npn \@@_struct_prop_gput:nnn #1#2#3 - { \prop_gput:cnn { g__tag_struct_#1_prop }{#2}{#3} } - } - { \cs_new_protected:Npn \@@_struct_prop_gput:nnn #1#2#3 - { \__tag_struct_prop_gput:nnn {#1}{#2}{#3} } - } -\cs_generate_variant:Nn \@@_struct_prop_gput:nnn {nne,Vnn} -% \end{macrocode} -% % \begin{macrocode} \cs_new_protected:Npn \@@_set_header_rows: { @@ -964,7 +980,7 @@ % \begin{macrocode} \prop_if_exist:cT { g__tag_struct_####1_prop } { - \@@_struct_prop_gput:nnn{ ####1 }{S}{/TH} + \__tag_struct_prop_gput:nnn{ ####1 }{S}{/TH} % \end{macrocode} % This need refinement once row headers (and perhaps other attributes) % are used too, but for now it should be ok. @@ -973,8 +989,8 @@ { g__tag_struct_####1_prop } { C } \l_@@_tmpa_tl - {\@@_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} } - {\@@_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}} + {\__tag_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} } + {\__tag_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}} } } } @@ -983,261 +999,68 @@ % \end{macro} % % And some key support: +% (See tagpdfsetup-keys.md for the naming scheme.) % \begin{macrocode} -% TODO decide about key name \keys_define:nn { __tag / setup } { - table-header-rows .clist_set:N = \l_@@_header_rows_clist + table/header-rows .clist_set:N = \l_@@_header_rows_clist, +% \end{macrocode} +% obsolete older name: +% \begin{macrocode} + table-header-rows .meta:n = {table/header-rows={#1}} } % \end{macrocode} % -% \subsection{Changes to \pkg{array} commands} % % +% \subsection{Misc stuff} % % \begin{macro}{\@@_show_curr_cell_data:} % Show the row/column index and span count for current table cell % for debugging. % \begin{macrocode} \cs_new_protected:Npn \@@_show_curr_cell_data: { - \typeout { ==>~ current~cell~data:~ - \int_use:N \g_@@_row_int , - \int_use:N \g_@@_col_int , - \g_@@_span_tl - } -} -% \end{macrocode} -% \end{macro} -% -% -% -% -% \begin{macro}{\insert@column} -% \cs{insert@column} is defined in \pkg{array}, here only the two -% sockets are inserted. -% \begin{macrocode} -\def\insert@column{% - \@@_show_curr_cell_data: - \UseSocket{tagsupport/tblcell/begin}% - \the@toks \the \@tempcnta - \ignorespaces \@sharp \unskip - \the@toks \the \count@ \relax - \UseSocket{tagsupport/tblcell/end}% -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@classz} -% \begin{macrocode} -\def\@classz{\@classx - \@tempcnta \count@ - \prepnext@tok - \@addtopreamble{\ifcase \@chnum - \hfil - \hskip1sp% - \d@llarbegin - \insert@column - \d@llarend \do@row@strut \hfil \or - \hskip1sp\d@llarbegin \insert@column \d@llarend \do@row@strut \hfil \or - \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend \do@row@strut \or - \setbox\ar@mcellbox\vbox - \@startpbox{\@nextchar} - \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} - \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} - \insert@column \@endpbox - \ar@align@mcell - \do@row@strut \or - \vtop \@startpbox{\@nextchar} - \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} - \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} - \insert@column \@endpbox\do@row@strut \or - \vbox \@startpbox{\@nextchar} - \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox} - \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox} - \insert@column \@endpbox\do@row@strut - \fi}\prepnext@tok} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@array,\@@@@array} -% We modificate the \cs{@array} from \pkg{array}. -% \begin{macrocode} -\def\@array[#1]#2{% - \@tempdima \ht \strutbox - \advance \@tempdima by\extrarowheight - \setbox \@arstrutbox \hbox{\vrule - \@height \arraystretch \@tempdima - \@depth \arraystretch \dp \strutbox - \@width \z@}% -% \end{macrocode} -% The total number of table columns of the current table is -% determined in \cs{@@_determine_table_cols:} but this is called in -% a group, so local settings do not survive. Thus, to save away the -% outer value of \cs{g_@@_table_cols_tl} we do it before the group. -% \begin{macrocode} - \tl_set_eq:NN \l_@@_saved_table_cols_tl \g_@@_table_cols_tl -% \end{macrocode} -% -% \begin{macrocode} - \begingroup - \@mkpream{#2} -% \end{macrocode} -% Next call has to happen immediately after \cs{@mkpream} because -% it uses implementation details from that. -% \begin{macrocode} - \@@_determine_table_cols: -% \end{macrocode} -% -% \begin{macrocode} - \xdef\@preamble{% - \noexpand -% \end{macrocode} -% \cs{ialign} in the original definition is replaced by -% \cs{ar@ialign} defined below. -% \begin{macrocode} - \ar@ialign - \@halignto - \bgroup \@arstrut -% \end{macrocode} -% A socket is inserted -% \begin{macrocode} - \UseSocket{tagsupport/tblrow/begin}% -% \end{macrocode} -% At the start of the preamble for the first column we set -% \cs{g_@@_col_int} to \texttt{1} as we are no longer "at" but "in" -% the first column. This is done in \cs{@@_init_cell_data:}. In -% later columns this data is updated via \cs{@@_update_cell_data:}. -% \begin{macrocode} - \@@_init_cell_data: - \@preamble - \tabskip \z@ \cr}% - \endgroup - \@arrayleft -% \end{macrocode} -% Another socket for tagging. TODO: what about \cs{arrayleft}? -% \begin{macrocode} - \UseSocket{tagsupport/tbl/init} - \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi - \bgroup - \let \@sharp ##\let \protect \relax - \lineskip \z@ - \baselineskip \z@ - \m@th - \let\\\@arraycr \let\tabularnewline\\\let\par\@empty -%\show\@preamble - \@preamble} -% \end{macrocode} -% Finally, also set \cs{@@@@array} to the new definition: -% \begin{macrocode} -\let\@@@@array\@array -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_init_cell_data:} -% -% \begin{macrocode} -\cs_new_protected:Npn \@@_init_cell_data: { - \int_gset:Nn \g_@@_col_int {1} - \tl_gset:Nn \g_@@_span_tl {1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_update_cell_data:} -% Updating cell data in columns after the first means we have to -% increment the \cs{g_@@_col_int} by the span count of the previous -% cell (in case it was a \cs{multicolumn} and then reset the -% \cs{g_@@_span_tl} to one (as the default). -% \begin{macrocode} -\cs_new_protected:Npn \@@_update_cell_data: { - \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } - \tl_gset:Nn \g_@@_span_tl {1} + \@@_trace:n { ==>~ current~cell~data:~ + \int_use:N \g_@@_row_int , + \int_use:N \g_@@_col_int , + \g_@@_span_tl + } } % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_determine_table_cols:} -% Current implementation of \cs{@mkpream} uses the scratch counter -% \cs{count@} to keep track of the number of toks registers it needs -% (2 per column), but this can't be used as it counts also -% insertings made with \verb+!{}+ and \verb+@{}+. -% So similar as does longtable for \cs{LT@cols} we count the -% numbers of ambersands instead. -% \begin{macrocode} -\cs_new:Npn \@@_determine_table_cols: { - \seq_set_split:NnV\l_@@_tmpa_seq {&}\@preamble - \tl_gset:Ne \g_@@_table_cols_tl { \seq_count:N \l_@@_tmpa_seq } - \typeout{ ==>~ Table~ has~ \g_@@_table_cols_tl \space columns } -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@arraycr} -% Add code that figures out if the current table row is incomplete -% (not enough \verb=&=s). It can then do extra actions, such as -% inserting missing cell tags. +% \begin{macro}{\@@_add_missing_cells:} +% The storing and use of the number of missing cells must happen at +% different places as the testing happens at the end of the last +% cell of a row, but still inside that cell, so we use two +% commands. The one adding is used in the row/end socket. % \begin{macrocode} -\protected\def\@arraycr{ - \relax - \@@_store_missing_cells:n{@arraycr} - % - \iffalse{\fi\ifnum 0=`}\fi - \@ifstar \@xarraycr \@xarraycr} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{\@@_store_missing_cells:n, -% \__tag_tbl_add_missing_cells:n} -% The storing and use of the number of missing cells -% must happen at different places as the testing happens at -% the end of the last cell of a row, but -% still inside that cell, so we use two commands. The second is used in -% the endrow socket. -% \begin{macrocode} -\cs_new:Npn \@@_store_missing_cells:n #1 { - \int_compare:nNnT \g_@@_col_int > 0 - { - \int_gset:Nn \g_@@_missing_cells_int - { - \g_@@_table_cols_tl - - \g_@@_col_int - - \g_@@_span_tl - + 1 - } - \int_compare:nNnT \g_@@_missing_cells_int < 0 \ERROR % should not happen - \typeout{==>~ - (#1)~ - This~ row~ needs~ - \int_use:N \g_@@_missing_cells_int \space - additional~ cell(s) - } - } -} +\NewSocket{tbl/celldata/missingcount}{1} +\NewSocketPlug{tbl/celldata/missingcount}{code}{\tbl_count_missing_cells:n{#1}} +\AssignSocketPlug{tbl/celldata/missingcount}{code} + % \end{macrocode} % % \begin{macrocode} -\cs_new:Npn \__tag_tbl_add_missing_cells:n #1 +\cs_new:Npn \@@_add_missing_cells: { % \end{macrocode} -% The TD-socket messages are issued after the message about the end-row socket, -% but the structure is ok, so better issue a message for now to avoid confusion: +% The TD-socket messages are issued after the message about the +% end-row socket, but the structure is ok, so better issue a +% message for now to avoid confusion: % \begin{macrocode} - \int_compare:nNnT {#1}>{0} + \int_compare:nNnT \g_@@_missing_cells_int > 0 { - \typeout{==>~ - ~Inserting~\int_eval:n{#1}~additional~cell(s)~into~previous~row:} - } - \int_step_inline:nn { #1 } - { - \UseSocket{tagsupport/tblcell/begin} - \UseSocket{tagsupport/tblcell/end} + \@@_trace:n {==>~ + ~Inserting~\int_use:N \g_@@_missing_cells_int \space + additional~cell(s)~into~previous~row:} + \int_step_inline:nn { \g_@@_missing_cells_int } + { + \UseTaggingSocket{tbl/cell/begin} + \UseTaggingSocket{tbl/cell/end} + } } } % \end{macrocode} @@ -1245,119 +1068,8 @@ % % % -% \begin{macro}{\endarray} -% If tables are nested into another then it is necessary to -% restore information about the cell the inner table started -% in. Otherwise, \cs{g_@@_row_int}, \cs{g_@@_col_int}, and -% \cs{g_@@_span_tl} reflect the status in the outer table as they -% are globally manipulated. We restore in all cases even if we are -% not in a nesting situation as that makes the code simpler (and -% probably faster). -% -% \cs{endtabular} and \cs{endtabular*} inherit from \cs{endarray} -% so we only need to change that. \texttt{tabularx} is handled -% below. -% \begin{macrocode} -\def\endarray{ - \@@_store_missing_cells:n{endarray} - \crcr \egroup - \UseSocket{tagsupport/tbl/finalize} - \int_gset:Nn \g_@@_col_int { \l_@@_saved_col_tl } - \int_gset:Nn \g_@@_row_int { \l_@@_saved_row_tl } - \tl_gset_eq:NN \g_@@_span_tl \l_@@_saved_span_tl - \tl_gset_eq:NN \g_@@_table_cols_tl \l_@@_saved_table_cols_tl - \tl_gset_eq:NN \g_@@_struct_table_tl \l_@@_saved_struct_table_tl - \seq_gset_eq:NN \g_@@_struct_rows_seq \l_@@_saved_struct_rows_seq - \seq_gset_eq:NN \g_@@_struct_cells_seq\l_@@_saved_struct_cells_seq - \seq_gset_eq:NN \g_@@_struct_cur_seq \l_@@_saved_struct_cur_seq - \typeout{==>~ restored~cell~data:~ - \int_use:N \g_@@_row_int, - \int_use:N \g_@@_col_int, - \l_@@_saved_span_tl \space - ( - \int_compare:nNnTF \g_@@_table_cols_tl = 0 - { outer~ level } - { max:~ \g_@@_table_cols_tl } - ) - } - \egroup - \@arrayright \gdef\@preamble{}% -} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@addamp} -% If we are after the first column we have to insert a \verb=&= and -% also update the cell data. -% \begin{macrocode} -\def\@addamp { - \if@firstamp - \@firstampfalse - \else - \edef\@preamble{\@preamble & - \@@_update_cell_data: - } - \fi -} -% \end{macrocode} -% \end{macro} -% -% -% -% \begin{macro}{ -% \g_@@_col_int, -% \g_@@_row_int, -% \g_@@_span_tl, -% \g_@@_table_cols_tl} -% \cs{g_@@_row_int} holds the current row number in the table. The value -% \texttt{0} means we haven't yet processed the table preamble. It -% is incremented by every \cs{cr} including the one ending the -% table preamble. % -% \cs{g_@@_col_int} holds the current column number. The value -% \texttt{0} means we have not yet started the table or just finished a table row -% (with \verb=\\= typically); any other positive value means we -% are currently typesetting a cell in that column in some row -% (denoted by the \cs{g_@@_row_int}. % -% In a \cs{multicolumn} it holds the column number of the first -% spanned column and \cs{g_@@_span_tl} the info how many cells are -% spanned. -% -% \cs{g_@@_span_tl} is normally \texttt{1} except in a -% \cs{multicolumn} cell. -% \begin{macrocode} -\int_new:N \g_@@_col_int -\int_new:N \g_@@_row_int -\tl_new:N \g_@@_span_tl -\tl_new:N \g_@@_table_cols_tl - -\tl_gset:Nn \g_@@_span_tl {1} -\tl_gset:Nn \g_@@_table_cols_tl {0} % indicates outer level -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\l_@@_saved_col_tl,\l_@@_saved_row_tl, -% \l_@@_saved_span_tl,\l_@@_saved_table_cols_tl} -% -% Saving the outer values if we are nesting tables is necessary (as -% the above variables are globally altered. For this we use always -% token lists because they don't change and we do not need to blow -% additional integer registers. -% \begin{macrocode} -\tl_new:N \l_@@_saved_col_tl -\tl_new:N \l_@@_saved_row_tl -\tl_new:N \l_@@_saved_span_tl -\tl_new:N \l_@@_saved_table_cols_tl - -\tl_set:Nn \l_@@_saved_col_tl{0} -\tl_set:Nn \l_@@_saved_row_tl{0} -\tl_set:Nn \l_@@_saved_span_tl{1} -\tl_set:Nn \l_@@_saved_table_cols_tl{0} % indicates outer level -% \end{macrocode} -% \end{macro} % % \begin{macro} % { @@ -1390,474 +1102,53 @@ \seq_new:N \l_@@_saved_struct_cur_seq % \end{macrocode} % \end{macro} + + + +% \begin{macro}{\@@_init_struct_data:} +% Save the global structure data variables locally so the we can +% restore them when the table ends (important in case of nested +% tables). % -% \begin{macro}{\ar@ialign} -% A new command that replaces \cs{ialign} above. \cs{everycr} is -% also applied to the \cs{cr} ending the preamble so we have to -% program around that. +% This is also the right point to initialize +% them. \cs{g_@@_struct_table_tl} is set elsewhere. % \begin{macrocode} -\def\ar@ialign{% -% \end{macrocode} -% Before starting a table we locally stored the information related -% to the current cell (if any) so that we can restore it once the -% table is finished. -% \begin{macrocode} - \tl_set:No \l_@@_saved_col_tl {\int_use:N \g_@@_col_int } - \tl_set:No \l_@@_saved_row_tl {\int_use:N \g_@@_row_int } - \tl_set_eq:NN \l_@@_saved_span_tl \g_@@_span_tl +\cs_new_protected:Npn \@@_init_struct_data: { \tl_set_eq:NN \l_@@_saved_struct_table_tl \g_@@_struct_table_tl \seq_set_eq:NN \l_@@_saved_struct_rows_seq \g_@@_struct_rows_seq \seq_set_eq:NN \l_@@_saved_struct_cells_seq \g_@@_struct_cells_seq \seq_set_eq:NN \l_@@_saved_struct_cur_seq \g_@@_struct_cur_seq % - \typeout{==>~ saved~cell~data:~ - \l_@@_saved_row_tl, - \l_@@_saved_col_tl, - \l_@@_saved_span_tl \space - ( - \int_compare:nNnTF \l_@@_saved_table_cols_tl = 0 - { outer~ level } - { max:~ \l_@@_saved_table_cols_tl } - ) - } -% \end{macrocode} -% These are the initial values when starting a table: -% \begin{macrocode} - \int_gzero:N \g_@@_row_int - \int_gzero:N \g_@@_col_int - \tl_gset:Nn \g_@@_span_tl {1} \seq_gclear:N\g_@@_struct_rows_seq \seq_gclear:N\g_@@_struct_cells_seq \seq_gclear:N\g_@@_struct_cur_seq +} % \end{macrocode} -% -% \begin{macrocode} - \everycr{% - \noalign{% -% \end{macrocode} -% We use \cs{g_@@_col_int} equal zero to indicate that we are just -% after a TR (or at the very beginning of the table). Using the row -% count is not so good as longtable may split the table in chunks. -% \begin{macrocode} - \int_compare:nNnT \g_@@_col_int > 0 - { \UseSocket{tagsupport/tblrow/end} } - \int_gincr:N \g_@@_row_int % this row about to start - \int_gzero:N \g_@@_col_int % we are before first col - }% - }% - \tabskip\z@skip\halign} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\multicolumn} -% -% \cs{multicolumn} is also defined in \pkg{array}. The redefinition -% has to solve two problems: it must handle the row begin if it is -% used there, and it must save the numbers of cells it spans so -% that we can add a suitable ColSpan attribute.\footnote{FMi: This can -% now perhaps cleaned up somewhat} -% \begin{macrocode} -\long\def\multicolumn#1#2#3{% - % alternative: determine first col with vmode test ... - % \ifvmode - % \multispan{#1}\typeout{A==> vmode}% - % \else - % \multispan{#1}\typeout{A==> not vmode} - % \fi - % but this makes the \crcr handling really complicated which would - % then need to become something like - % \ifvmode \expandafter \@gobble - % \else \expandafter \@iden \fi {\cr\noalign{do something}}% - % so not used. - % Instead: - \multispan{#1}\begingroup -% \end{macrocode} -% Insert rowbegin socket only if this multicolumn -% replaces the preamble of the first column. In that case we have -% to set \cs{g_@@_col_int} to 1 since this is no longer done in the -% preamble for the cell. -% \begin{macrocode} - \int_compare:nNnTF \g_@@_col_int = 0 - { - \UseSocket{tagsupport/tblrow/begin} - \int_gset:Nn \g_@@_col_int {1} - } -% \end{macrocode} -% If we are in a later column we use \cs{g_@@_span_tl} from the -% previous column to update. -% \begin{macrocode} - { - \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl } - } -% \end{macrocode} -% Then we set the span value so that it can be use in the next column. +% \end{macro} + + + + +% \begin{macro}{\@@_restore_struct_data:} +% % \begin{macrocode} - \tl_gset:Nn \g_@@_span_tl {#1} +\cs_new_protected:Npn \@@_restore_struct_data: { + \tl_gset_eq:NN \g_@@_struct_table_tl \l_@@_saved_struct_table_tl + \seq_gset_eq:NN \g_@@_struct_rows_seq \l_@@_saved_struct_rows_seq + \seq_gset_eq:NN \g_@@_struct_cells_seq\l_@@_saved_struct_cells_seq + \seq_gset_eq:NN \g_@@_struct_cur_seq \l_@@_saved_struct_cur_seq +} % \end{macrocode} +% \end{macro} + + % -% \begin{macrocode} - \def\@addamp{\if@firstamp\@firstampfalse \else - \@preamerr 5\fi}% - \@mkpream{#2}\@addtopreamble\@empty - \endgroup -% \end{macrocode} -% Now we update the colspan attribute. This needs setting after -% the group as it is hidden inside the plug in \cs{insert@column}. -% \begin{macrocode} - \@@_set_colspan:n {#1} -% \end{macrocode} -% \begin{macrocode} - \def\@sharp{#3}% - \@arstrut \@preamble - \null - \ignorespaces} -% \end{macrocode} -% \end{macro} % % \subsection{longtable} % -% Longtable is complicated. When at the begin the \cs{endhead}, -% \cs{endfirsthead}, \cs{endfoot} and \cs{endlastfoot} are used to -% setup head and foot they create each a structure subtree with one or -% more rows. From this structures we want to keep at most two (head -% and foot) and move the foot to the end of the table. When the head -% and foot boxes are (re)inserted on following pages we want to mark -% them up as artifact with the exception of the head at the begin and -% the foot box at the end. -% -% TODO: When a line is killed the structure subtree is there already -% too and must be removed. -% -% Hyperref patches longtable. This must be disabled and replace with -% genuine code -% \begin{macrocode} -\let\@kernel@refstepcounter\refstepcounter -\def\hyper@nopatch@longtable{} -% \end{macrocode} -% \begin{macrocode} -\def\@@_patch_LT@array[#1]#2{% -% \end{macrocode} -% \cs{LT@array} is executed in a group, so we can disable para-tagging here. -% \begin{macrocode} - \UseSocket{tagsupport/tbl/init}% - \@kernel@refstepcounter{table}\stepcounter{LT@tables}% -% \end{macrocode} -% The target is created rather late and a \cs{label} can come earlier, -% so we have to define \cs{@currentHref} explicitly. We can't currently -% assume that \cs{theHtable} is defined always. -% \begin{macrocode} - \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable} - \int_gzero:N \g_@@_row_int - \seq_gclear:N\g_@@_struct_rows_seq - \seq_gclear:N\g_@@_struct_cells_seq - \seq_gclear:N\g_@@_struct_cur_seq - \seq_gclear:N\g_@@_LT@firsthead_rows_seq - \seq_gclear:N\g_@@_LT@head_rows_seq - \seq_gclear:N\g_@@_LT@lastfoot_rows_seq - \seq_gclear:N\g_@@_LT@foot_rows_seq - \if l#1% - \LTleft\z@ \LTright\fill - \else\if r#1% - \LTleft\fill \LTright\z@ - \else\if c#1% - \LTleft\fill \LTright\fill - \fi\fi\fi - \let\LT@mcol\multicolumn - \let\LT@@@@tabarray\@tabarray - \let\LT@@@@hl\hline - \def\@tabarray{% - \let\hline\LT@@@@hl - \LT@@@@tabarray}% - \let\\\LT@tabularcr - \let\tabularnewline\\% - \def\newpage{\noalign{\break}}% - \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LT@no@pgbk-}4}% - \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LT@no@pgbk4}% - \let\hline\LT@hline \let\kill\LT@kill\let\caption\LT@caption - \@tempdima\ht\strutbox - \let\@endpbox\LT@endpbox - \ifx\extrarowheight\@undefined - \let\@acol\@tabacol - \let\@classz\@tabclassz \let\@classiv\@tabclassiv - \def\@startpbox{\vtop\LT@startpbox}% - \let\@@@@startpbox\@startpbox - \let\@@@@endpbox\@endpbox - \let\LT@LL@FM@cr\@tabularcr - \else - \advance\@tempdima\extrarowheight - \col@sep\tabcolsep - \let\@startpbox\LT@startpbox\let\LT@LL@FM@cr\@arraycr - \fi - \setbox\@arstrutbox\hbox{\vrule - \@height \arraystretch \@tempdima - \@depth \arraystretch \dp \strutbox - \@width \z@}% - \let\@sharp##\let\protect\relax - \begingroup - \@mkpream{#2}% - \@@_determine_table_cols: - \xdef\LT@bchunk{% -% \end{macrocode} -% At the start of a chunk we set \cs{g_@@_col_int} to zero to make -% sure that we aren't generating /TR with the \cs{cr} ending the -% chunk preamble. -% \begin{macrocode} - \int_gzero:N \g_@@_col_int - \global\advance\c@LT@chunks\@ne - \global\LT@rows\z@\setbox\z@\vbox\bgroup - \LT@setprevdepth - \tabskip\LTleft \noexpand\halign to\hsize\bgroup - \tabskip\z@ \@arstrut -% \end{macrocode} -% Insert the socket and the setting of the conditional -% \begin{macrocode} - \UseSocket{tagsupport/tblrow/begin}% - \@@_init_cell_data: -% \end{macrocode} -% \begin{macrocode} - \@preamble \tabskip\LTright \cr}% - \endgroup - \expandafter\LT@nofcols\LT@bchunk&\LT@nofcols - \LT@make@row - \m@th\let\par\@empty -% \end{macrocode} -% Socket and conditional -% \begin{macrocode} - \everycr{% - \noalign{% -% \end{macrocode} -% In \pkg{longtable} we have a bunch of extra \cs{cr}s that are -% executed whenever a chunk ends. In that case they should not -% increment the main row counter, sigh. -% \begin{macrocode} - \typeout{--longtable-->~chunk~row:~ \the\LT@rows \space - row:~ \the\g_@@_row_int \space - column:~ \the\g_@@_col_int - } - \int_compare:nNnT \g_@@_col_int > 0 - { - \UseSocket{tagsupport/tblrow/end} - } -% \end{macrocode} -% This prevents any of the additional \cs{cr}s at the end of the -% chunk to add another /TR. Then once we really start a new chunk -% it gets incremented so\ldots -% \begin{macrocode} - \int_gzero:N \g_@@_col_int % before first col -% \end{macrocode} -% And for the same reason such \cs{cr}s should not increment the -% main row counter (but it has to be incremented after the preamble -% of a chunk), so here we test against \cs{LT@rows} which is -% \cs{LTchunksize} at the end of a chunk. -% \begin{macrocode} - \int_compare:nNnT \LT@rows < \LTchunksize - { \int_gincr:N \g_@@_row_int } % this row about to start - }% - }% -% \end{macrocode} -% \begin{macrocode} - \lineskip\z@\baselineskip\z@ - \LT@bchunk} -% \end{macrocode} -% The end code most stop to insert the endrow too. -% \begin{macrocode} -\def\@@_patch_endlongtable{% - \@@_store_missing_cells:n{endlongtable} - \crcr - \noalign{% - \UseSocket{tagsupport/tbl/finalize/longtable} - \int_gzero:N \g_@@_row_int % this prevents considering the next - % \crcr as another row end. - \let\LT@entry\LT@entry@chop - \xdef\LT@save@row{\LT@save@row}}% - \LT@echunk - \LT@start - \unvbox\z@ - \LT@get@widths - \if@filesw - {\let\LT@entry\LT@entry@write\immediate\write\@auxout{% - \gdef\expandafter\noexpand - \csname LT@\romannumeral\c@LT@tables\endcsname - {\LT@save@row}}}% - \fi - \ifx\LT@save@row\LT@@@@save@row - \else - \LT@warn{Column~\@width s~have~changed\MessageBreak - in~table~\thetable}% - \LT@final@warn - \fi - \endgraf\penalty -\LT@end@pen - \ifvoid\LT@foot\else - \global\advance\vsize\ht\LT@foot - \global\advance\@colroom\ht\LT@foot - \dimen@\pagegoal\advance\dimen@\ht\LT@foot\pagegoal\dimen@ - \fi - \endgroup - \global\@mparbottom\z@ - \endgraf\penalty\z@\addvspace\LTpost - \ifvoid\footins\else\insert\footins{}\fi} -% \end{macrocode} -% -% -% -% \begin{macro}{\@@_patch_LT@t@bularcr} -% -% \begin{macrocode} -\def\@@_patch_LT@t@bularcr{% - \global\advance\LT@rows\@ne - \ifnum\LT@rows=\LTchunksize -% \end{macrocode} -% At the end of the chunk \verb=\\= is doing something special and -% so we loose \cs{@@_store_missing_cells:n}. Below is about the -% right place to add it do this code branch. -% \begin{macrocode} - \@@_store_missing_cells:n{echunk} - \gdef\LT@setprevdepth{% - \prevdepth\z@ - \global\let\LT@setprevdepth\relax}% - \expandafter\LT@xtabularcr - \else - \ifnum0=`{}\fi - \expandafter\LT@LL@FM@cr - \fi} - -% \end{macrocode} -% \end{macro} % % % -% \begin{macro}{\@@_patch_LT@end@hd@ft} -% This command is used to store the head and foot boxes. -% We need to retrieve and store the row so that we can clean -% up the structure in the finalize code. -% \begin{macrocode} -\def\@@_patch_LT@end@hd@ft#1{% -% \end{macrocode} -% To handle missing columns in the header we need this: -% \begin{macrocode} - \__tbl_store_missing_cells:n{head/foot} - \int_step_inline:nn - { \LT@rows + 1 } - { - \seq_gput_left:ce - {g_@@_\cs_to_str:N #1 _rows_seq } - { \int_eval:n {\g_@@_row_int + 1 - ##1 } } - } -% \end{macrocode} -% We also have to set the chunk rows to its max value before -% calling \cs{LTechunk} so that we don't get extra increments of -% the main row counter due to \cs{everycr}. -% \begin{macrocode} - \int_gset:Nn \LT@rows { \LTchunksize } - \LT@echunk - \ifx\LT@start\endgraf - \LT@err - {Longtable head or foot not at start of table}% - {Increase LTchunksize}% - \fi - \setbox#1\box\z@ - \LT@get@widths - \LT@bchunk} -% \end{macrocode} -% \end{macro} - -% \begin{macro}{\@@_patch_LT@start} -% \begin{macrocode} -\def\@@_patch_LT@start{% - \let\LT@start\endgraf - \endgraf\penalty\z@\vskip\LTpre\endgraf - \ifdim \pagetotal<\pagegoal \else - \dimen@=\pageshrink - \advance \dimen@ 1sp % - \kern\dimen@\penalty 9999\endgraf \kern-\dimen@ - \fi - \dimen@\pagetotal - \advance\dimen@ \ht\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi - \advance\dimen@ \dp\ifvoid\LT@firsthead\LT@head\else\LT@firsthead\fi - \advance\dimen@ \ht\LT@foot - \edef\LT@reset@vfuzz{\vfuzz\the\vfuzz\vbadness\the\vbadness\relax}% - \vfuzz\maxdimen - \vbadness\@M - \setbox\tw@\copy\z@ - \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox - \setbox\tw@\vbox{\unvbox\tw@}% - \LT@reset@vfuzz - \advance\dimen@ \ht - \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi - \advance\dimen@\dp - \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi - \advance\dimen@ -\pagegoal - \ifdim \dimen@>\z@ - \vfil\break - \else - \ifdim\pageshrink>\z@\pageshrink\z@\fi - \fi - \global\@colroom\@colht - \ifvoid\LT@foot\else - \global\advance\vsize-\ht\LT@foot - \global\advance\@colroom-\ht\LT@foot - \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@ - \maxdepth\z@ - \fi - \MakeLinkTarget{table} - \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak -% \end{macrocode} -% Avoid that following uses of the box add content: -% \begin{macrocode} - \tagmcbegin{artifact} - \tag_mc_reset_box:N\LT@head - \tagmcend - \output{\LT@output}} -% \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\@@_patch_LT@output} -% We must also avoid that the reuse of the foot box leads to -% duplicated content: -% \begin{macrocode} -\def\@@_patch_LT@output{% - \ifnum\outputpenalty <-\@Mi - \ifnum\outputpenalty > -\LT@end@pen - \LT@err{floats and marginpars not allowed in a longtable}\@ehc - \else - \setbox\z@\vbox{\unvbox\@cclv}% - \ifdim \ht\LT@lastfoot>\ht\LT@foot - \dimen@\pagegoal - \advance\dimen@\ht\LT@foot - \advance\dimen@-\ht\LT@lastfoot - \ifdim\dimen@<\ht\z@ - \setbox\@cclv\vbox{\unvbox\z@\copy\LT@foot\vss}% - \@makecol - \@outputpage - \global\vsize\@colroom - \setbox\z@\vbox{\box\LT@head}% - \fi - \fi - \unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi -% \end{macrocode} -% Reset attribute of foot box: -% \begin{macrocode} - \tagmcbegin{artifact} - \tag_mc_reset_box:N \LT@foot - \tagmcend - \fi - \else - \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% -% \end{macrocode} -% Reset attribute of foot box: -% \begin{macrocode} - \tagmcbegin{artifact} - \tag_mc_reset_box:N \LT@foot - \tagmcend - \@makecol - \@outputpage - \global\vsize\@colroom - \copy\LT@head\nobreak - \fi} -% \end{macrocode} -% \end{macro} % % \begin{macro}{\@@_patch_\LT@makecaption} % This patch is quite similar to the one for LaTeX's \cs{@makecaption} @@ -1893,74 +1184,11 @@ % \begin{macrocode} \AddToHook{package/longtable/after} { - \seq_new:N \g_@@_LT@firsthead_rows_seq - \seq_new:N \g_@@_LT@head_rows_seq - \seq_new:N \g_@@_LT@lastfoot_rows_seq - \seq_new:N \g_@@_LT@foot_rows_seq - \cs_set_eq:NN \LT@array\@@_patch_LT@array - \cs_set_eq:NN \endlongtable\@@_patch_endlongtable - \cs_set_eq:NN \LT@start\@@_patch_LT@start - \cs_set_eq:NN \LT@output\@@_patch_LT@output - \cs_set_eq:NN \LT@t@bularcr\@@_patch_LT@t@bularcr - \cs_set_eq:NN \LT@end@hd@ft\@@_patch_LT@end@hd@ft \cs_set_eq:NN \LT@makecaption\@@_patch_LT@makecaption } % \end{macrocode} - - - -% \subsection{tabularx} -% -% In tabularx we mainly need to ensure that no tagging is done during -% the trial. -% -% \begin{macrocode} -\def\@@_patch_TX@endtabularx{% - \expandafter\expandafter\expandafter - \TX@find@endtabularxa\csname end\TX@\endcsname - \endtabularx\TX@\endtabularx\TX@find@endtabularxa - \expandafter\TX@newcol\expandafter{\tabularxcolumn{\TX@col@width}}% - \let\verb\TX@verb - \def\@elt##1{\global\value{##1}\the\value{##1}\relax}% - \edef\TX@ckpt{\cl@@@@ckpt}% - \let\@elt\relax - \TX@old@table\maxdimen - \TX@col@width\TX@target - \global\TX@cols\@ne - \TX@typeout@ - {\@spaces Table Width\@spaces Column Width\@spaces X Columns}% -% \end{macrocode} -% Here we stop tagging: -% \begin{macrocode} - \tag_stop:n{tabularx} - \TX@trial{\def\NC@rewrite@X{% - \global\advance\TX@cols\@ne\NC@find p{\TX@col@width}}}% - \loop - \TX@arith - \ifTX@ - \TX@trial{}% - \repeat -% \end{macrocode} -% And now we restart it again. -% \begin{macrocode} - \tag_start:n{tabularx} - {\let\@footnotetext\TX@ftntext\let\@xfootnotenext\TX@xftntext - \csname tabular*\expandafter\endcsname\expandafter\TX@target - \the\toks@ - \csname endtabular*\endcsname}% - \global\TX@ftn\expandafter{\expandafter}\the\TX@ftn - \ifnum0=`{\fi}% - \expandafter\expandafter\expandafter - \TX@find@endtabularxbb - \expandafter\end\expandafter{\TX@}% - \endtabularx\TX@\endtabularx\TX@find@endtabularxb -} - -\AddToHook{package/tabularx/after} - {\cs_set_eq:NN \TX@endtabularx\@@_patch_TX@endtabularx } -% \end{macrocode} % \begin{macrocode} % % \end{macrocode} @@ -1973,3 +1201,11 @@ \RequirePackage{latex-lab-testphase-table} % % \end{macrocode} + +% \begin{macrocode} +%<*latex-lab-alias> +\ProvidesFile{tabular-latex-lab-testphase.ltx} + [\ltlabtbldate\space v\ltlabtblversion\space latex-lab wrapper tabular] +\RequirePackage{latex-lab-testphase-table} +% +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx index b2ed5ecf8a4..f0a6fe65d0c 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % %% File: latex-lab-testphase.dtx -% Copyright (C) 2021-2023 The LaTeX Project +% Copyright (C) 2021-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -79,7 +79,7 @@ % \begin{macrocode} %<*phase-III> \ProvidesFile{phase-III-latex-lab-testphase.ltx} - [2023-07-20 v0.1b latex-lab wrapper phase-III] + [2024-02-12 v0.1c latex-lab wrapper phase-III] \input{phase-II-latex-lab-testphase.ltx} \IfFormatAtLeastTF{2023-06-01} { @@ -91,6 +91,7 @@ \RequirePackage{latex-lab-testphase-float} \RequirePackage{latex-lab-testphase-bib} \RequirePackage{latex-lab-testphase-text} + \RequirePackage{latex-lab-testphase-marginpar} } {\PackageWarning{latex-lab}{Testphase III needs newer format}{}} % @@ -122,9 +123,9 @@ \RequirePackage{tagpdf} \AddToDocumentProperties [document]{testphase/tagpdf}{loaded} % -%\tagpdfsetup{activate,paratagging,interwordspace} +%\tagpdfsetup{activate,para/tagging,activate/spaces} %\AddToDocumentProperties [document]{tagging/para}{active} -%\tagpdfsetup{activate,interwordspace} +%\tagpdfsetup{activate,activate/spaces} %<*tagpdf|phase-I|phase-II> \AddToDocumentProperties [document]{tagging}{active} \AddToDocumentProperties [document]{tagging/interwordspace}{active} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx index 4041336ecbf..fe9b6ababc7 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-text.dtx (C) Copyright 2023 LaTeX Project +%% File: latex-lab-text.dtx (C) Copyright 2023-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx new file mode 100644 index 00000000000..757bb284a45 --- /dev/null +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx @@ -0,0 +1,518 @@ +% \iffalse meta-comment +% +%% File: latex-lab-title.dtx (C) Copyright 2023-2024 LaTeX Project +% +% It may be distributed and/or modified under the conditions of the +% LaTeX Project Public License (LPPL), either version 1.3c of this +% 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 +% +% +% The development version of the bundle can be found below +% +% https://github.com/latex3/latex2e/required/latex-lab +% +% for those people who are interested or want to report an issue. +% +\def\ltlabtitledate{2024-02-09} +\def\ltlabtitleversion{0.85c} + +%<*driver> +\documentclass{l3doc} +\EnableCrossrefs +\CodelineIndex +\begin{document} + \DocInput{latex-lab-title.dtx} +\end{document} +% +% +% \fi +% +% \title{The \textsf{latex-lab-title} package\\ +% Changes related to the tagging of the title} +% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} +% \date{v\ltlabtitleversion\ \ltlabtitledate} +% +% \maketitle +% +% \newcommand{\xt}[1]{\textsl{\textsf{#1}}} +% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} +% \newcommand{\docclass}{document class \marginpar{\raggedright document class +% customizations}} +% +% \providecommand\hook[1]{\texttt{#1}} +% +% \begin{abstract} +% \end{abstract} +% +% \section{Introduction} +% +% This module contains changes to improve the tagging (in the standard classes) of +% the title created with the \cs{maketitle} command. It also improves the +% setting of the metadata related to the title and the author. +% +% For basic tagging of the printed title there are basically three things to do: +% +% \begin{itemize} +% \item The actual title should be tagged with the \texttt{Title} tag. +% \item The tabular used to format the author list should \emph{not} be tagged as a tabular. +% \item \cs{maketitle} redefines footnote internals. These must be made tagging aware. +% \end{itemize} +% +% A second task related to title is to store the authors and the title text +% (or a shorter version) inside the XMP-metadata and (in PDF 1.7 or lower) in +% the Info dictionary. Currently this can only be set if hyperref +% is loaded and requires the use of the \texttt{pdftitle} and \texttt{pdfauthor} keys. +% The new code therefore extends the \cs{title} and \cs{author} commands: They +% stores their argument and use them at the end of the document +% for the PDF metadata if the data hasn't been given in another way. +% The code also gives \cs{title} and \cs{author} +% an optional argument where the PDF title or author can be given with +% in a key-value syntax. As with hyperref it is possible to store titles +% in more than one language: +% +% \begin{verbatim} +% \title +% [pdftitle = +% {[en]English Title,[de] Deutscher Titel,[fr]{titre français, avec comma}}] +% {Document title} +% \end{verbatim} +% +% It is also possible to set a subtitle which is then stored in the XMP-metadata: +% +% \begin{verbatim} +% \title +% [pdfsubtitle = +% {[en]English Subtitle,[de] Deutscher Subtitel,[fr]{subtitre français, avec comma}}] +% {Document title} +% \end{verbatim} + +% +% If using the \texttt{pdfauthor} key authors should be separated +% by commas, and to hide commas in a name inside braces if needed: +% +% \begin{verbatim} +% \author[pdfauthor = {Bär, Peter Anteater, {Riley, the sloth}}]{\ldots} +% \end{verbatim} +% +% If hyperref is loaded there is no difference to the \texttt{pdftitle} and +% \texttt{pdfauthor} key used in \cs{hypersetup}. Both can be used (and the last +% key used will win). +% +% \subsection{Open questions and TODOs} +% +% \begin{itemize} +% \item Writing into the Info dictionary needs to convert the input into a PDF string. +% This is here done with a simple version of hyperref's \cs{pdfstringdef}, similar code +% exist also in in the generic hyperref driver. This should be moved into a better place +% module. +% +% \item Is it sensible to enhance \cs{author} and \cs{title} with an optional argument as done here? +% An advantage is that it is rather light-weight and +% doesn't require to decide how this values should be set in \cs{DocumentMetadata} (and would also work +% without \cs{DocumentMetadata}. But a problem could be that various classes and packages already +% extend this commands with other optional arguments. +% +% \item Some of the definitions related to metadata should perhaps be moved into l3pdfmeta. +% +% \item Are the names \texttt{pdftitle} and \texttt{pdfauthor} ok? +% +% \item The patch for \cs{thanks} to get a rlap-footnotemarker looks wrong. This +% probably means that some configuration option is missing in the footnote code. +% \end{itemize} +% +% +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +%<@@=tag> +% \end{macrocode} +% \begin{macrocode} +\ProvidesExplPackage {latex-lab-testphase-title} {\ltlabtitledate} {\ltlabtitleversion} + {Changes related to the tagging of the title} +% \end{macrocode} +% +% \subsection{\cs{maketitle} in article class} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_thanks:n #1 + { + \rlap{\footnotemark} + \protected@xdef\@thanks{\@thanks + \protect\footnotetext[\the\c@footnote]{#1}} + } +% \end{macrocode} +% The no-titlepage version of article, report and book +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_maketitle: + { + \par + \begingroup +% \end{macrocode} +% Disable table tagging +% \begin{macrocode} + \cs_if_exist_use:N\__tag_tbl_disable: + \renewcommand\thefootnote{\@fnsymbol\c@footnote}% +% \end{macrocode} +% the original definition redefines \cs{@makefnmark} and +% \cs{@makefntext} to get an rlap-mark in the text without +% affecting the mark in the note (which gives by the way +% a wrong link area with hyperref). There seem to be currently +% no good way in the footnote to configure this, so we redefine +% \cs{thanks} instead +% \begin{macrocode} + \cs_set_eq:NN \thanks \@@_patch_thanks:n + \if@twocolumn + \ifnum \col@number=\@ne + \@maketitle + \else + \twocolumn[\@maketitle]% + \fi + \else + \newpage + \global\@topnum\z@ % Prevents figures from going at top of page. + \@maketitle + \fi + \thispagestyle{plain}\@thanks + \endgroup + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\@title\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax + } +% \end{macrocode} +% We must also change \cs{@maketitle} to insert a Title tag +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_@maketitle: + { + \newpage + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks +% \end{macrocode} +% use Title around the title. As in PDF 1.7 this is +% rolemapped to P we change the text-unit tag there. +% \begin{macrocode} + \pdf_version_compare:NnTF > {1.7} + {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}} + {{\LARGE \tagtool{paratag=Title}\@title \par}}% + \vskip 1.5em% + {\large + \lineskip .5em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1em% + {\large \@date}% + \end{center}% + \par + \vskip 1.5em + } + +% \end{macrocode} +% The titlepage variant +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_maketitle_page: + {\begin{titlepage}% +% \end{macrocode} +% disable table tagging +% \begin{macrocode} + \cs_if_exist_use:N\__tag_tbl_disable: + \let\footnotesize\small + \let\footnoterule\relax + \let \footnote \thanks + \null\vfil + \vskip 60\p@ +% \end{macrocode} +% use Title around the title. As in PDF 1.7 this is +% rolemapped to P we change the text-unit tag there. +% \begin{macrocode} + \begin{center}% + \pdf_version_compare:NnTF > {1.7} + {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}} + {{\LARGE \tagtool{paratag=Title}\@title \par}}% + \vskip 3em% + {\large + \lineskip .75em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1.5em% + {\large \@date \par}% % Set date in \large size. + \end{center}\par + \@thanks + \vfil\null + \end{titlepage}% + \setcounter{footnote}{0}% + \global\let\thanks\relax + \global\let\maketitle\relax + \global\let\@thanks\@empty + \global\let\@author\@empty + \global\let\@date\@empty + \global\let\@title\@empty + \global\let\title\relax + \global\let\author\relax + \global\let\date\relax + \global\let\and\relax + } + +% \end{macrocode} +% Map the new commands onto \cs{maketitle}: +% \begin{macrocode} +\AddToHook{class/article/after} + { + \if@titlepage + \cs_set_eq:NN \maketitle \@@_patch_maketitle_page: + \else + \cs_set_eq:NN \maketitle \@@_patch_maketitle: + \cs_set_eq:NN \@maketitle \@@_patch_@maketitle: + \fi + } +\AddToHook{class/report/after} + { + \if@titlepage + \cs_set_eq:NN \maketitle \@@_patch_maketitle_page: + \else + \cs_set_eq:NN \maketitle \@@_patch_maketitle: + \cs_set_eq:NN \@maketitle \@@_patch_@maketitle: + \fi + } +\AddToHook{class/book/after} + { + \if@titlepage + \cs_set_eq:NN \maketitle \@@_patch_maketitle_page: + \else + \cs_set_eq:NN \maketitle \@@_patch_maketitle: + \cs_set_eq:NN \@maketitle \@@_patch_@maketitle: + \fi + } +% \end{macrocode} +% +% \subsection{Helper commands to set metadata} +% +% Some temp variables +% \begin{macrocode} +\str_new:N \g_@@_title_tmpa_str +\str_new:N \l_@@_title_tmpa_str +\tl_new:N \l_@@_title_tmpa_tl +\seq_new:N \l_@@_title_tmpa_seq +% \end{macrocode} +% Support for \cs{texorpdfstring} +% \begin{macrocode} +\providecommand\texorpdfstring[2]{#1}% +% \end{macrocode} +% +% A helper command to convert the title into a pdfstring similar to +% \cs{pdfstringdef}. +% As we use \cs{text_purify} we must ensure that the default definitions +% of \cs{@title} and \cs{@author} are robust: +% \begin{macrocode} +\protected\def\@title{\@latex@error{No \noexpand\title given}\@ehc} +\protected\def\@author{\@latex@warning@no@line{No \noexpand\author given}} +% \end{macrocode} +% TODO: This should be improved and moved into the pdf module so that +% it is generally available. +% \begin{macrocode} +\cs_new_protected:Npn \@@_title_pdfstring:nnN #1 #2 #3 % #1 text, #2 e.g. utf16/hex + { + \group_begin: +% \end{macrocode} +% TODO: we need probably a common boolean to handle +% \cs{texorpdfstring} also without hyperref. +% \begin{macrocode} + \cs_set_eq:NN\texorpdfstring\use_ii:nn + \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { #1 } } + \pdf_string_from_unicode:nVN { #2 } \l_@@_title_tmpa_str \l_@@_title_tmpa_str + \str_gset_eq:NN \g_@@_title_tmpa_str\l_@@_title_tmpa_str + \group_end: + \str_set_eq:NN #3 \g_@@_title_tmpa_str + } +\cs_generate_variant:Nn\@@_title_pdfstring:nnN {e} +% \end{macrocode} + +% \subsection{Extend title to set metadata} +% At first a variable to store the title, as \cs{@title} is emptied by \LaTeX. +% \begin{macrocode} +\tl_new:N \g_@@_title_title_tl +% \end{macrocode} +% Now we redefine \cs{title} so that it stores the title, and processes +% keys in the optional argument. We use \texttt{hyp} as module +% name for the key as this means that if hyperref is loaded its definition +% of \texttt{pdftitle} will be used -- at some time probably this +% should be moved out of hyperref so that we have only one definition. +% +% \begin{macrocode} +\RenewDocumentCommand\title{O{}m} + { + \gdef\@title{#2} + \tl_gset_eq:NN\g_@@_title_title_tl\@title + \keys_set:nn {hyp}{#1} + } +% \end{macrocode} +% Now we define the \texttt{pdftitle} key. This is more or less +% the same definition as in the generic hyperref driver. +% \begin{macrocode} +\regex_new:N\l_@@_title_optlang_regex +\regex_set:Nn\l_@@_title_optlang_regex {\A\[([A-Za-z\-]+)\](.*)} +\cs_generate_variant:Nn \regex_extract_once:NnN{NVN} +\cs_generate_variant:Nn \clist_item:nn {on} +% \end{macrocode} +% and now the keys. +% \begin{macrocode} +\keys_define:nn { hyp } + { + pdftitle .code:n = + { + \tl_if_blank:nTF {#1} + { + \pdfmanagement_remove:nn {Info}{Title} + } + { + \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}} + \regex_extract_once:NVN + \l_@@_title_optlang_regex + \l_@@_title_tmpa_tl + \l_@@_title_tmpa_seq + \seq_if_empty:NTF\l_@@_title_tmpa_seq + { + \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str + } + { + \@@_title_pdfstring:enN + {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str + } + \str_if_eq:VnF\l_@@_title_tmpa_str{} + { + \pdfmanagement_add:nne {Info}{Title}{\l_@@_title_tmpa_str} + } + } + \AddToDocumentProperties[hyperref]{pdftitle}{#1} + } + ,pdfsubtitle .code:n = { \AddToDocumentProperties[hyperref]{pdfsubtitle}{#1} } + } +% \end{macrocode} +% +% \subsection{Extend \cs{author} to set metadata} +% +% At first a variable to store the authors, as \cs{@author} is emptied by \LaTeX. +% \begin{macrocode} +\tl_new:N \g_@@_title_author_tl +% \end{macrocode} +% Now we redefine \cs{author} so that it stores the authors, and processes +% keys in the optional argument. We use \texttt{hyp} as module +% name for the key as this means that if hyperref is loaded its definition +% of \texttt{pdfauthor} will be used -- at some time probably this +% should be moved out of hyperref so that we have only one definition. +% +% \begin{macrocode} +\RenewDocumentCommand\author{O{}m} + { + \gdef\@author{#2} + \tl_gset_eq:NN\g_@@_title_author_tl\@author + \keys_set:nn {hyp}{#1} + } +% \end{macrocode} +% +% Now we define the \texttt{pdfauthor} key. This is more or less +% the same definition as in the generic hyperref driver. + +% \begin{macrocode} +\keys_define:nn { hyp } + { + pdfauthor .code:n = + { + \tl_if_blank:nTF {#1} + { + \pdfmanagement_remove:nn {Info}{Author} + } + { + \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}} + \regex_extract_once:NVN + \l_@@_title_optlang_regex + \l_@@_title_tmpa_tl + \l_@@_title_tmpa_seq + \seq_if_empty:NTF\l_@@_title_tmpa_seq + { + \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str + } + { + \@@_title_pdfstring:enN + {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str + } + \str_if_eq:VnF\l_@@_title_tmpa_str{} + { + \pdfmanagement_add:nne {Info}{Author}{\l_@@_title_tmpa_str} + } + } + \AddToDocumentProperties[hyperref]{pdfauthor}{#1} + } + } +% \end{macrocode} +% \subsection{Fallback for classes and packages that redefine \cs{title} or \cs{author}} +% If a class redefines \cs{author} and \cs{title} again, we try to retrieve at +% least the values. +% \begin{macrocode} +\AddToHook{cmd/maketitle/before} + { + \tl_gset_eq:NN \g_@@_title_author_tl\@author + \tl_gset_eq:NN \g_@@_title_title_tl\@title + } +% \end{macrocode} +% +% \subsection{Finalize document} +% At last we set the title and the author at the end of document +% if that hasn't happened yet: +% \begin{macrocode} +\AddToHook{shipout/lastpage} + { + \tl_if_empty:eT{\GetDocumentProperties{hyperref/pdftitle}} + { + \group_begin: + \cs_set_eq:NN\thanks \use_none:n + \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_title_tl } } + \keys_set:ne{hyp}{pdftitle={\exp_not:V\l_@@_title_tmpa_str}} + \group_end: + } + \tl_if_empty:eT{\GetDocumentProperties{hyperref/pdfauthor}} + { + \group_begin: + \cs_set_eq:NN\thanks \use_none:n + \cs_set:Npn \and {,} + \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_author_tl } } + \keys_set:ne{hyp}{pdfauthor={\exp_not:V\l_@@_title_tmpa_str}} + \group_end: + } +% \end{macrocode} +% force display title, if an UA-standard is detected. +% \begin{macrocode} + \tl_if_empty:eF{\GetDocumentProperties{document/pdfstandard-UA}} + { + \pdfmanagement_add:nnn {Catalog / ViewerPreferences } { DisplayDocTitle } { true } + } + } +\DeclareHookRule{shipout/lastpage}{latex-lab-testphase-title}{before}{pdfmanagement-testphase} +% +% \end{macrocode} + +% \begin{macrocode} +%<*latex-lab> +\ProvidesFile{title-latex-lab-testphase.ltx} + [\ltlabtitledate\space v\ltlabtitleversion\space + Changes related to the tagging of the title] + +\RequirePackage{latex-lab-testphase-title} + +% +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx index 2f00b83c059..ff9dd950b76 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-toc-hyperref-changes.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-toc-hyperref-changes.dtx (C) Copyright 2022-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx index 81c9edfe4dc..bb88ffdcb03 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-toc-kernel-changes.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-toc-kernel-changes.dtx (C) Copyright 2022-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -17,8 +17,8 @@ % for those people who are interested or want to report an issue. % % dates for latex-lab-kernel-changes.sty (pulled from various sources, see ins) -\def\ltlabkerneldate{2023-10-16} -\def\ltlabkernelversion{0.85b} +\def\ltlabkerneldate{2024-02-12} +\def\ltlabkernelversion{0.85c} %<*driver> \documentclass{l3doc} \EnableCrossrefs @@ -235,7 +235,7 @@ \makeatletter \@starttoc@cfgpoint@before{#1}% \@input{\jobname.#1}% - \@starttoc@cfgpoint@after{#1} + \@starttoc@cfgpoint@after{#1}% \if@filesw \expandafter\newwrite\csname tf@#1\endcsname \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx index 6def505e113..7235eb9ed95 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: latex-lab-toc.dtx (C) Copyright 2022-2023 LaTeX Project +%% File: latex-lab-toc.dtx (C) Copyright 2022-2024 LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -271,7 +271,7 @@ { \int_compare_p:nNn { \g_@@_toc_level_int } > {-100} } { \int_compare_p:nNn { \use:c{toclevel@#1} } > { \g_@@_toc_level_int } } { - \seq_gpush:Nx \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}} + \seq_gpush:Ne \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}} \tag_struct_begin:n{tag=TOC} } % \end{macrocode} @@ -298,7 +298,7 @@ % \begin{macrocode} \group_begin: \text_declare_expand_equivalent:Nn \numberline \use_none:n - \exp_args:Nx \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}} + \exp_args:Ne \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}} % \end{macrocode} % The TOCI structure should get a /Ref, so we put a request with its destination % name into the prop. @@ -307,9 +307,9 @@ % need to store fake names. % \end{NOTE} % \begin{macrocode} - \prop_gput:Nxx \g_@@_struct_ref_by_dest_prop + \prop_gput:Nee \g_@@_struct_ref_by_dest_prop { \tag_get:n {struct_num} }{#3} - \seq_gpush:Nx \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}} + \seq_gpush:Ne \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}} \group_end: } } diff --git a/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins b/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins index 548f18a6fa7..7071ed6e3dc 100644 --- a/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins +++ b/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins @@ -154,8 +154,16 @@ where one can also log issues in case there are any. %table \generate{\file{table-latex-lab-testphase.ltx}{\from{latex-lab-table.dtx}{latex-lab}}} +\generate{\file{tabular-latex-lab-testphase.ltx}{\from{latex-lab-table.dtx}{latex-lab-alias}}} \generate{\file{latex-lab-testphase-table.sty}{\from{latex-lab-table.dtx}{package}}} +%title +\generate{\file{title-latex-lab-testphase.ltx}{\from{latex-lab-title.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-title.sty}{\from{latex-lab-title.dtx}{package}}} + +%marginpar +\generate{\file{marginpar-latex-lab-testphase.ltx}{\from{latex-lab-marginpar.dtx}{latex-lab}}} +\generate{\file{latex-lab-testphase-marginpar.sty}{\from{latex-lab-marginpar.dtx}{package}}} % stop docstrip adding \endinput \preamble diff --git a/Master/texmf-dist/source/latex/tools/afterpage.dtx b/Master/texmf-dist/source/latex/tools/afterpage.dtx index 518b70761d9..72df39402c9 100644 --- a/Master/texmf-dist/source/latex/tools/afterpage.dtx +++ b/Master/texmf-dist/source/latex/tools/afterpage.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/afterpage.ins b/Master/texmf-dist/source/latex/tools/afterpage.ins index 6fec5edc6f6..17792ddfa13 100644 --- a/Master/texmf-dist/source/latex/tools/afterpage.ins +++ b/Master/texmf-dist/source/latex/tools/afterpage.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/array.dtx b/Master/texmf-dist/source/latex/tools/array.dtx index 6e4e34ea260..e77ef0a3bf1 100644 --- a/Master/texmf-dist/source/latex/tools/array.dtx +++ b/Master/texmf-dist/source/latex/tools/array.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -25,15 +25,21 @@ %% Package `array' to use with LaTeX 2e %% Copyright (C) 1989-1998 Frank Mittelbach, all rights reserved. %<+package>\NeedsTeXFormat{LaTeX2e}[1995/06/01] -%<+package>\providecommand\DeclareRelease[3]{} -%<+package>\providecommand\DeclareCurrentRelease[2]{} %<+package> +% For anything before 2016-10-06 we load the 2016 version and hope for the best: +%<+package>\DeclareRelease{}{1994-06-01}{array-2016-10-06.sty} +% %<+package>\DeclareRelease{}{2016-10-06}{array-2016-10-06.sty} %<+package>\DeclareRelease{v2.4}{2020-02-10}{array-2020-02-10.sty} -%<+package>\DeclareCurrentRelease{}{2020-10-01} +%<+package>\DeclareRelease{v2.5}{2023-11-01}{array-2023-11-01.sty} +%<+package>\DeclareCurrentRelease{}{2024-06-01} %<+package> +% \end{macrocode} +% Current version needs a new kernel. +% \begin{macrocode} +%<+package>\NeedsTeXFormat{LaTeX2e}[2024/06/01] %<+package>\ProvidesPackage{array} -%<+package> [2023/10/16 v2.5g Tabular extension package (FMi)] +%<+package> [2024/05/23 v2.6c Tabular extension package (FMi)] % % \fi % @@ -177,6 +183,18 @@ % \DoNotIndex{\xdef} % \DoNotIndex{\z@} % +% +% \providecommand\env[1]{\texttt{#1}} +% +% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}} +% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}} +% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}} +% +% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl} +% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl} +% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl} +% +% % \GetFileInfo{array.sty} % % \title{A new implementation of \LaTeX's \textsf{tabular} @@ -195,6 +213,8 @@ % \MaintainedByLaTeXTeam{tools} % \maketitle % +% +% % \MakeShortVerb{\=} % % \begin{abstract} @@ -750,12 +770,29 @@ % \end{itemize} % % +% \section{Support for tagged PDF} % -% \changes{v2.2b}{1994/02/04}{Removed interactive prompt} +% With version 2.6a the package is made tagging aware, which means that +% it will automatically produce tagged tables (necessary, for example, for +% accessibility) if tagging is requested via \cs{DocumentMetadata}. % -% \MaybeStop{ +% More granular control, e.g., explicitly deciding which cells are +% header cells, etc., is currently under development, but syntax for +% this will not appear in this package. Instead it will become +% available across all tabular-generating packages and then +% automatically apply here as well. +% +% Enabling \LaTeX{} to automatically produce tagged PDF is a long-term +% project and this is a tiny step in this puzzle. For more information +% on the project and already available functionality, see +% \url{https://latex-project.org/publications/indexbytopic/pdf} and +% \url{https://github.com/latex3/tagging-project}. % % +% +% \changes{v2.2b}{1994/02/04}{Removed interactive prompt} +% +% \MaybeStop{ % \begin{thebibliography}{1} % \bibitem{bk:GMS94} \textsc{M.~Goossens}, \textsc{F.~Mittelbach} % and \textsc{A.~Samarin}. @@ -772,7 +809,6 @@ % \newblock % Addison-Wesley, Reading, Massachusetts, 1986. % \end{thebibliography} -% % } ^^A end of \MaybeStop % % @@ -786,8 +822,49 @@ % \texttt{docstrip} program. % \begin{macrocode} %<*driver> -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\documentclass{ltxdoc} +\NeedsTeXFormat{LaTeX2e}[2024/06/01] +% \end{macrocode} +% +% We switched from \cls{ltxdoc} to \cls{l3doc} to get support for +% code written in the L3 programming layer. The first is that we +% are currently missing \cs{MaintainedByLaTeXTeam}, so we have to +% provide that for now. +% \begin{macrocode} +\documentclass{l3doc} + +% currently missing in l3doc +\makeatletter +\def\MaintainedBy#1{\gdef\@maintainedby{#1}} +\let\@maintainedby\@empty +\def\MaintainedByLaTeXTeam#1{% +{\gdef\@maintainedby{% +This file is maintained by the \LaTeX{} Project team.\\% +Bug reports can be opened (category \texttt{#1}) at\\% +\url{https://latex-project.org/bugs.html}.}}} +\def\@maketitle{% + \newpage + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks + {\LARGE \@title \par}% + \vskip 1.5em% + {\large + \lineskip .5em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1em% + {\large \@date}% + \ifx\@maintainedby\@empty + \else + \vskip 1em% + \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}% + \fi + \end{center}% + \par + \vskip 1.5em} +\makeatother % undo the default is not used: @@ -817,6 +894,29 @@ % \end{macrocode} % % +% \section{A note on the updates done December 2023} +% +% We introduced support for tagged PDf and at the same time we added +% code to determine row and column numbers for each cell in +% preparation for supporting formatting or type specifications for individual +% cells (or group of cells) from the outside, e.g., \enquote{rows 1, +% 2, and 10 are header rows} (syntax to be decided). +% +% This new code is already written with L3 programming layer conventions +% while most of the legay code is still as it was before. This make the code +% currently somewhat clattered, unfortunately. Eventually this will all move to L3 +% programming layer but this will take time. +% +% +% \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn +% \end{macrocode} +% +% +% +% +% % \section{The construction of the preamble} % % \DeleteShortVerb{\"} @@ -972,6 +1072,7 @@ % =\@chclass= and =\@chnum=. % \changes{v2.0f}{1992/02/29}{Argument removed since implicitly known} % \begin{macrocode} +\ExplSyntaxOff \def\@testpach{\@chclass % \end{macrocode} % First we deal with the cases in which the \textsf{token} @@ -981,7 +1082,7 @@ \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else \ifnum \@lastchclass=7 5 \else \ifnum \@lastchclass=8 \tw@ \else - \ifnum \@lastchclass=9 \thr@@ + \ifnum \@lastchclass=9 \thr@@@@ % \end{macrocode} % Otherwise we will assume that the \textsf{token} belongs to the % class $0$ @@ -1032,7 +1133,7 @@ % \begin{macrocode} 10 \@chnum - \if \@nextchar m\thr@@\else + \if \@nextchar m\thr@@@@ \else \if \@nextchar p4 \else \if \@nextchar b5 \else % \end{macrocode} @@ -1042,6 +1143,7 @@ % \begin{macrocode} \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi} +\ExplSyntaxOn % \end{macrocode} % \end{macro} % @@ -1062,10 +1164,10 @@ % they are in explicit braces, as in =@{*}=. % % This macro is called via -% =\@xexpast=\meta{preamble}=*0x\@@=. +% =\@xexpast=\meta{preamble}=*0x\@@@@=. % The $*$--expression =*0x= is being used to terminate the % recursion, -% as we shall see later, and =\@@= serves as an argument +% as we shall see later, and =\@@@@= serves as an argument % delimiter. =\@xexpast= has four arguments. The first % one is the part of the % user preamble before the first $*$--expression while the second @@ -1074,7 +1176,7 @@ % above). % The fourth argument is the rest of the preamble. % \begin{macrocode} -\def\@xexpast#1*#2#3#4\@@{% +\def\@xexpast#1*#2#3#4\@@@@{% % \end{macrocode} % The number of copies of \textit{String} (=#2=) that are to be % produced will be saved in a \textsf{count} register. @@ -1111,7 +1213,7 @@ % \end{macrocode} % If \textit{N\/} was greater than zero we prepare for another call % of =\@xexpast=. Otherwise we assume we have reached the end of -% the user preamble, because we had appended =*0x\@@= when we first +% the user preamble, because we had appended =*0x\@@@@= when we first % called =\@xexpast=. In other words: if the user inserts % =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it. % \begin{macrocode} @@ -1133,7 +1235,7 @@ % $*$--expression is handled, or to the macro =\@xexnoop=, % which only ends the recursion by deleting its argument. % \begin{macrocode} - \expandafter \@tempb \@tempa #4\@@} + \expandafter \@tempb \@tempa #4\@@@@} % \end{macrocode} % \end{macro} % \end{macro} @@ -1142,10 +1244,10 @@ % \begin{macro}{\@xexnoop} % So the first big problem is solved. Now it is easy to % specify =\@xexnoop=. -% Its argument is delimited by =\@@= and it simply expands to +% Its argument is delimited by =\@@@@= and it simply expands to % nothing. % \begin{macrocode} -% \def\@xexnoop#1\@@{} +% \def\@xexnoop#1\@@@@{} % \end{macrocode} % \end{macro} % @@ -1270,11 +1372,19 @@ % % \begin{macro}{\insert@column} % \begin{macro}{\@sharp} +% \begin{macro}{\textonly@unskip} % We now define the macro =\insert@column= which will do % this work for us. % \begin{macrocode} \def\insert@column{% % \end{macrocode} +% +% For tagging we insert as special socket, that adds the necessary +% PDF tag at the beginning of the cell if tagging is enabled. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/cell/begin}% +% \end{macrocode} % Here, we assume that the \textsf{count} register % =\@tempcnta= has saved the value $=\count@= - 1$. % \begin{macrocode} @@ -1291,8 +1401,9 @@ % \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel} % \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of % \cs{d@llarbegin}} +% \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)} % \begin{macrocode} - \ignorespaces \@sharp \unskip + \ignorespaces \@sharp \textonly@unskip % \end{macrocode} % Then the second \textsf{token} register follows whose number should % be saved in =\count@=. @@ -1302,12 +1413,42 @@ % \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem % \cs{the}\cs{toks0}\cs{the}\cs{toks1}.} % \begin{macrocode} - \the@toks \the \count@ \relax} + \the@toks \the \count@ \relax % \end{macrocode} +% +% And another socket for tagging that adds the necessary closing tag +% if enabled. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/cell/end}% +} +% \end{macrocode} +% Do the unskip only if we are in hmode: +% \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)} +% \begin{macrocode} +\protected\def\textonly@unskip{\ifhmode\unskip\fi} +% \end{macrocode} +% \end{macro} % \end{macro} % \end{macro} % % +% \begin{macro}{\insert@pcolumn} +% Handling pcolumn-cells needs slightly different handling when +% doing tagging. Rather than changing the plugs in +% \cs{insert@column} back and forth, we simply use a different +% version of \cs{insert@column} that has its own sockets. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} +\def\insert@pcolumn{% + \UseTaggingSocket{tbl/pcell/begin}% + \the@toks \the \@tempcnta + \ignorespaces \@sharp \unskip + \the@toks \the \count@ \relax + \UseTaggingSocket{tbl/pcell/end}% +} +% \end{macrocode} +% \end{macro} % % % \subsection{The separation of columns} @@ -1321,11 +1462,24 @@ % =\@addamp=, the macro that inserts the =&=. % \begin{macrocode} % \newif \@iffirstamp -% \def\@addamp{\if@firstamp \@firstampfalse -% \else \@addtopreamble &\fi} +\def\@addamp { + \if@firstamp + \@firstampfalse + \else +% \end{macrocode} +% If we are after the first column we have to insert a \verb=&= and +% also update the cell data. +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \edef\@preamble{\@preamble & + \noexpand\tbl_update_cell_data: } + \fi +} % \end{macrocode} % \end{macro} % +% +% % \begin{macro}{\@acol} % \begin{macro}{\@acolampacol} % \begin{macro}{\col@sep} @@ -1393,7 +1547,7 @@ % command =\@xexpast=. As we already know, this command saves % its result in the macro =\@tempa=. % \begin{macrocode} -% \@xexpast #1*0x\@@ +% \@xexpast #1*0x\@@@@ % \end{macrocode} % Afterwards we initialize all registers and macros, that we need % for the build-up of the preamble. @@ -1477,7 +1631,7 @@ % \texttt{r}, \texttt{p},\texttt{m} or \texttt{b}. We report an % error and ignore the declaration given by ={..}=. % \begin{macrocode} -% \@preamerr \thr@@ \or +% \@preamerr \thr@@@@ \or % \end{macrocode} % If =\@lastchclass= is $4$ the user preamble has been empty. % To continue, we insert a =#= in the preamble. @@ -1671,18 +1825,17 @@ \setbox\ar@mcellbox\vbox % \end{macrocode} % The part of the templates which is the same in all three cases -% (\texttt{p}, \texttt{m} and \texttt{b}) -% is built by the macros =\@startpbox= and -% =\@endpbox=. =\@startpbox= has an argument: -% the width of the column which is stored in the current -% \textsf{token} (i.e.\ =\@nextchar=). -% Between these two macros we find the well known -% =\insert@column=. -% The strut is places after the box +% (\texttt{p}, \texttt{m} and \texttt{b}) is built by the macros +% =\@startpbox= and =\@endpbox=. =\@startpbox= has an argument: the +% width of the column which is stored in the current \textsf{token} +% (i.e.\ =\@nextchar=). Between these two macros we find the well +% known =\insert@column= or rather the variant for tagging: +% \cs{insert@pcolumn}. The strut is placed after the box. % \changes{v2.4e}{2016/10/07}{Fixing SX68732} % \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}} +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} % \begin{macrocode} - \@startpbox{\@nextchar}\insert@column \@endpbox + \@startpbox{\@nextchar}\insert@pcolumn \@endpbox \ar@align@mcell \do@row@strut \or % \end{macrocode} @@ -1690,9 +1843,10 @@ % same way though we do not need the =$= characters because we use % =\vtop= or =\vbox=. % \changes{v2.4e}{2016/10/07}{Fixing SX68732} +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} % \begin{macrocode} - \vtop \@startpbox{\@nextchar}\insert@column \@endpbox\do@row@strut \or - \vbox \@startpbox{\@nextchar}\insert@column \@endpbox\do@row@strut + \vtop \@startpbox{\@nextchar}\insert@pcolumn \@endpbox\do@row@strut \or + \vbox \@startpbox{\@nextchar}\insert@pcolumn \@endpbox\do@row@strut % \end{macrocode} % Other values for =\@chnum= are impossible. Therefore we % end the arguments to =\@addtopreamble= and =\ifcase=. @@ -1783,8 +1937,8 @@ % So the declarations defined by the first =>{...}= % are ignored. % \begin{macrocode} -%\def\@classix{\ifnum \@lastchclass = \thr@@ -% \@preamerr \thr@@ \fi +%\def\@classix{\ifnum \@lastchclass = \thr@@@@ +% \@preamerr \thr@@@@ \fi % \end{macrocode} % Furthermore, we call up =\@class10= because afterwards always a % new column is started by \texttt{c}, \texttt{l}, \texttt{r}, @@ -1836,14 +1990,14 @@ % We only check if the last \textsf{token} was of class $3$ which is % forbidden. % \begin{macrocode} -\def\@classvii{\ifnum \@lastchclass = \thr@@ +\def\@classvii{\ifnum \@lastchclass = \thr@@@@ % \end{macrocode} % If this is true we output an error message and % ignore the declarations stored % by the last =>{...}=, because these are overwritten % by the argument of \texttt{@}. % \begin{macrocode} - \@preamerr \thr@@ \fi} + \@preamerr \thr@@@@ \fi} % \end{macrocode} % \end{macro} % @@ -2032,7 +2186,7 @@ % second one describes the wanted preamble, % e.g.\ it has the form =|c|c|c|=. % \begin{macrocode} -\def\@array[#1]#2{% +\def\@array[#1]#2{ % \end{macrocode} % First we define a \textsf{strut} whose size basically corresponds % to a normal \textsf{strut} multiplied by the factor @@ -2051,6 +2205,14 @@ \@depth \arraystretch \dp \strutbox \@width \z@}% % \end{macrocode} +% The total number of table columns of the current table is +% determined in \cs{tbl_count_table_cols:} but this is called in +% a group, so local settings do not survive. Thus, to save away the +% outer value of \cs{g_@@_table_cols_tl} we do it before the group. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \tbl_save_outer_table_cols: +% \end{macrocode} % Then we open a group, in which the user preamble is evaluated by % the macro =\@mkpream=. As we know this must happen locally. % This macro creates a preamble for a =\halign= and saves @@ -2059,6 +2221,11 @@ \begingroup \@mkpream{#2}% % \end{macrocode} +% Figure out how many columns this table has: +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_count_table_cols: +% \end{macrocode} % We again redefine =\@preamble= so that a call up of =\@preamble= % now starts the =\halign=. Thus also the arguments of \texttt{>}, % \texttt{<}, \texttt{@} and \texttt{!}, saved in the @@ -2085,13 +2252,38 @@ % unsupported redefinition of a \TeX{} primitive for the moment (as people rely % on that experimental code). % \begin{macrocode} - \xdef\@preamble{\noexpand \ialign \@halignto - \bgroup \@arstrut \@preamble - \tabskip \z@ \cr}% + \xdef\@preamble{ +% \end{macrocode} +% \cs{ialign} in the original definition is replaced by +% \cs{ar@ialign} defined below. This does what \cs{ialign} does but +% additionally handles the tagging structure for the whole table if necessary. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \noexpand \ar@ialign + \@halignto + \bgroup \@arstrut % \end{macrocode} % What we have not explained yet is the macro =\@halignto= % that was just used. Depending on its replacement text the % =\halign= becomes a =\halign= \texttt{to} \meta{dimen}. +% +% Next, a tagging support socket is inserted adding the start row tag. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/row/begin} +% \end{macrocode} +% At the start of the preamble for the first column we call +% \cs{tbl_init_cell_data_for_row:} to initialize the cell index data. In +% later columns this data is updated via \cs{tbl_update_cell_data:}. +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_init_cell_data_for_row: +% \end{macrocode} +% +% \begin{macrocode} + \@preamble + \tabskip \z@ \cr} +% \end{macrocode} % Now we close the group again. Thus % =\@startpbox= and =\@endpbox= as well as all % \textsf{token} registers get their former meaning back. @@ -2128,12 +2320,16 @@ % around every column in the \textsf{array}--environment % the parameter =\mathsurround= should % also be set to \textsf{0pt}. This prevents additional space between -% the rows. The -% \PlainTeX--macro =\m@th= does this. +% the rows. % \begin{macrocode} \lineskip \z@ \baselineskip \z@ - \m@th +% \end{macrocode} +% Don't use \cs{m@th} here as that signals to the math taggingg +% code that this is fake math that should not be tagged. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \mathsurround \z@ % \end{macrocode} % Beside, we have to assign a special meaning (which we still have % to specify) to the line separator =\\=. We also have to @@ -2144,10 +2340,61 @@ % start the wanted =\halign=. % \changes{1994/12/08}{v2.3b}{add \cs{tabularnewline}} % \begin{macrocode} - \let\\\@arraycr \let\tabularnewline\\\let\par\@empty \@preamble} + \let\\\@arraycr \let\tabularnewline\\\let\par\@empty +% \end{macrocode} +% Another socket for tagging. TODO: what about \cs{arrayleft} above? +% \begin{macrocode} + \UseTaggingSocket{tbl/init} +% \end{macrocode} +% +% \begin{macrocode} + \@preamble +} % \end{macrocode} % \end{macro} % +% +% +% \begin{macro}{\ar@ialign} +% A new command that replaces \cs{ialign} used previously. \cs{everycr} is +% also applied to the \cs{cr} ending the preamble so we have to +% program around that. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} +\def\ar@ialign{% +% \end{macrocode} +% Before starting a table we have to initialize the variables +% holding row and column information for cells. We also have +% locally store the information related to the current cell (if we +% are already inside a table) so that we can restore it once the +% inner table is finished. +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_init_cell_data_for_table: +% \end{macrocode} +% +% \begin{macrocode} + \everycr{% + \noalign{% +% \end{macrocode} +% If this \cs{cr} was at the end of a real row (e.g., not at the +% end of the table preamble) we have add a row end tag. +% \begin{macrocode} + \tbl_if_row_was_started:T { \UseTaggingSocket{tbl/row/end} } +% \end{macrocode} +% The we prepare for the next row. +% \begin{macrocode} + \tbl_update_cell_data_for_next_row: + }% + }% + \tabskip\z@skip\halign} +% \end{macrocode} +% \end{macro} +% +% +% +% +% % \begin{macro}{\arraybackslash} % \changes{v2.4a}{2003/12/17}{(DPC) Macro added (from tabularx)} % Restore =\\= for use in array and tabular environment (after @@ -2182,7 +2429,27 @@ % \begin{macro}{\@arraycr} % In the macro =\@array= the line separator =\\= is % =\let= to the command =\@arraycr=. -% Its definition starts with a special brace which I have directly +% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math} +% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} +% \begin{macrocode} +\protected\def\@arraycr { +% \end{macrocode} +% Add code that figures out if the current table row is incomplete +% (not enough \verb=&=s). It can then do extra actions, such as +% inserting missing cell tags. +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_count_missing_cells:n {@arraycr} +% \end{macrocode} +% TODO: maybe this is also the right place to add a socket that +% could be used to actually enter missing cells instead of just +% adding tagging structures for them later. This would be optional +% but in many cases it would be the right thing to do (for example +% if tables contain vertical lines or similar visual structures +% that require fully specified rows. +% +% +% We then start a special brace which I have directly % copied from the original definition. It is % necessary, because the =\futurlet= in =\@ifnextchar= % might @@ -2198,10 +2465,8 @@ % =\halign= while we are looking for a =*= or =[=. % For further information see % \cite[Appendix D]{bk:knuth}. -% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math} -% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)} % \begin{macrocode} -\protected\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi + \iffalse{\fi\ifnum 0=`}\fi % \end{macrocode} % Then we test whether the user is using the star form and ignore % a possible star (I also disagree with this procedure, because a @@ -2210,6 +2475,11 @@ \@ifstar \@xarraycr \@xarraycr} % \end{macrocode} % \end{macro} + + + + + % % \begin{macro}{\@xarraycr} % In the command =\@xarraycr= we test if an optional argument @@ -2301,6 +2571,7 @@ % the result column and the actual column entry. % \changes{v2.3j}{1998/01/29}{Command made \cs{long} to match % kernel change for pr/2180} +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} % \begin{macrocode} \long\def\multicolumn#1#2#3{% % \end{macrocode} @@ -2310,6 +2581,16 @@ % \begin{macrocode} \multispan{#1}\begingroup % \end{macrocode} +% For tagging support we have to solve two problems: +% \cs{multicolumn} must handle the row begin if it is used there, +% and it must save the numbers of cells it spans so that we can add +% a suitable ColSpan attribute. We do this in the next macro +% (which in turn calls the \texttt{tbl/row/begin} socket, if +% necessary). +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_update_multicolumn_cell_data:n {#1} +% \end{macrocode} % Since a =\multicolumn= should only describe the format of a % result column, we redefine =\@addamp= in such a way that one gets % an error message if one uses more than one \texttt{c}, @@ -2336,6 +2617,12 @@ % \begin{macrocode} \endgroup % \end{macrocode} +% Now we update the colspan attribute. This needs setting after +% the group as it is hidden inside the plug in \cs{insert@column}. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/colspan}{#1}% +% \end{macrocode} % In the special situation of =\multicolumn= =\@preamble= % is not needed as preamble for a =\halign= but it is directly % inserted into our table. Thus instead of =\sharp= @@ -2458,6 +2745,12 @@ % \begin{macrocode} \leavevmode % \end{macrocode} +% Now that we know we are in hmode we can add the start tag for the +% whole table. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/hmode/begin}% +% \end{macrocode} % It should be taken into consideration that the macro =\@array= % must be called in math mode. Therefore we open a \textsf{box}, % insert a =$= and then assign the correct values to =\col@sep= and @@ -2486,11 +2779,41 @@ % =\@array=. To save \textsf{token} space we then redefine % =\@preamble= % because its replacement text isn't longer needed. +% +% To handle cell indexes, we do not use \cs{crcr} but a variant +% that also handles missing cells as necessary. +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} % \begin{macrocode} -%\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}} +\def\endarray { + \tbl_crcr:n{endarray} \egroup + \UseTaggingSocket{tbl/finalize} +% \end{macrocode} +% +% If tables are nested into another then it is necessary to +% restore information about the cell the inner table started +% in. Otherwise, the cell index data structures reflect the +% status in the outer table as they +% are globally manipulated. We restore in all cases even if we are +% not in a nesting situation as that makes the code simpler (and +% probably faster). +% +% \cs{endtabular} and \cs{endtabular*} inherit from \cs{endarray} +% so we only need to change that. \texttt{tabularx} uses a similar method. +% \changes{v2.6a}{2023/12/11}{Managing cell indexes} +% \begin{macrocode} + \tbl_restore_outer_cell_data: +% \end{macrocode} +% +% \begin{macrocode} + \egroup + \@arrayright \gdef\@preamble{}% +} % \end{macrocode} % \end{macro} % +% +% +% % \begin{macro}{\endtabular} % \begin{macro}{\endtabular*} % To end a \textsf{tabular} or \textsf{tabular$*$} environment we @@ -2499,7 +2822,13 @@ % any =\mathsurround= so we cancel that with =\m@th=. % \changes{v2.5f}{2021/07/12}{Cancel any outside \cs{mathsurround} (gh/614)} % \begin{macrocode} -\def\endtabular{\endarray\m@th $\egroup} +\def\endtabular{\endarray\m@th $\egroup +% \end{macrocode} +% +% \changes{v2.6a}{2023/12/11}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/hmode/end}% +} \expandafter\let\csname endtabular*\endcsname=\endtabular % \end{macrocode} % \end{macro} @@ -2518,7 +2847,7 @@ \let\@arrayclassiv=\relax \let\@arrayclassz=\relax \let\@tabclassiv=\relax \let\@tabclassz=\relax \let\@arrayacol=\relax \let\@tabacol=\relax -\let\@tabularcr=\relax \let\@@endpbox=\relax +\let\@tabularcr=\relax \let\@@@@endpbox=\relax \let\@argtabularcr=\relax \let\@xtabularcr=\relax % \end{macrocode} % @@ -2576,6 +2905,7 @@ % to define letters, to be used in the same way as the primitive % column specifiers, `c' `p' etc. % \begin{macrocode} +\ExplSyntaxOff % this is really oldstyle using \@tfor := \def\newcolumntype#1{% % \end{macrocode} % "\NC@char" was added in V2.01 so that active characters, like "@" in @@ -2615,6 +2945,7 @@ % If an optional argument was not given, give a default argument of 0. % \begin{macrocode} \@ifnextchar[{\newcol@{\NC@char}}{\newcol@{\NC@char}[0]}} +\ExplSyntaxOn % \end{macrocode} % \end{macro} % \begin{macro}{\newcol@} @@ -2710,16 +3041,18 @@ % produced and then "\typeout" the required string. % \begin{macrocode} \def\NC@show#1{% - \typeout{Column #1\expandafter\expandafter\expandafter\NC@strip - \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@}} + \typeout{Column~ #1\expandafter\expandafter\expandafter\NC@strip + \expandafter\meaning\csname NC@rewrite@#1\endcsname\@@@@}} % \end{macrocode} % \end{macro} % \begin{macro}{\NC@strip} % Delimit the arguments to "\NC@strip" with `\texttt{:}', `\texttt{->}', -% a space, and "\@@" to pull out the required parts of the output from +% a space, and "\@@@@" to pull out the required parts of the output from % "\meaning". % \begin{macrocode} -\def\NC@strip#1:#2->#3 #4\@@{#2 -> #4} +\ExplSyntaxOff +\def\NC@strip#1:#2->#3 #4\@@@@{#2 -> #4} +\ExplSyntaxOn % \end{macrocode} % \end{macro} % \begin{macro}{\NC@list} @@ -2807,6 +3140,7 @@ % \changes{v2.4e}{2016/10/07}{Fixing SX68732} % \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}} % \begin{macrocode} +\ExplSyntaxOff % really oldstyle using \@tfor := \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue \let\@sharp\relax % \end{macrocode} @@ -2869,11 +3203,12 @@ \@acol \or \or \@acol \or - \@preamerr \thr@@ \or + \@preamerr \thr@@@@ \or \@preamerr \tw@ \@addtopreamble\@sharp \or \or \else \@preamerr \@ne \fi \def\the@toks{\the\toks}} +\ExplSyntaxOn % \end{macrocode} % \end{macro} % @@ -2908,7 +3243,7 @@ % \texttt{array.sty} 2.0h. % \begin{macrocode} \def\@classv{\save@decl - \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@ + \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@@@@ \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}% \prepnext@tok} % \end{macrocode} @@ -2920,7 +3255,7 @@ % second "\extracolsep", there is no point in the user entering two of % these commands anyway, so this is not really a restriction. % \begin{macrocode} -\def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}% +\def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@@@@{\def\@tempa{#2}% \ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi} % % \end{macrocode} @@ -2936,28 +3271,27 @@ % % \begin{macro}{\@tabarray} % This macro tests for an optional bracket and then calls up -% "\@@array" or "\@@array[c]" (as default). +% "\@@@@array" or "\@@@@array[c]" (as default). % \begin{macrocode} %<*package> -\def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}} +\def\@tabarray{\@ifnextchar[{\@@@@array}{\@@@@array[c]}} % \end{macrocode} % \end{macro} -% \begin{macro}{\@@array} +% \begin{macro}{\@@@@array} % This macro tests could then test an optional delimiter before the % left brace of the main preamble argument. Here in the main package % it simply is let to be "\@array". % \begin{macrocode} -\let\@@array\@array +\let\@@@@array\@array % \end{macrocode} % \end{macro} % -% \begin{macro}{\endarray} +% \begin{macro}{\@arrrayleft} % \begin{macro}{\@arrayright} % We have to declare the hook we put into "\@array" above. -% A similar hook `"\@arrayright"' will be inserted into the +% A similar hook \cs{@arrayright} will be inserted into the % "\endarray" to gain control. Both defaults to empty. % \begin{macrocode} -\def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}} \let\@arrayleft\@empty \let\@arrayright\@empty % \end{macrocode} @@ -3182,6 +3516,14 @@ % \end{macro} % % +% +% +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% % \PrintIndex % \PrintChanges % diff --git a/Master/texmf-dist/source/latex/tools/bm.dtx b/Master/texmf-dist/source/latex/tools/bm.dtx index a608c6aeb58..d7d6eb54ee2 100644 --- a/Master/texmf-dist/source/latex/tools/bm.dtx +++ b/Master/texmf-dist/source/latex/tools/bm.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -22,7 +22,7 @@ % \fi % % \iffalse -%% Copyright 1996 1997 1998 1999 2002 2003 2004 2016 2017 2019 2021 2022 +%% Copyright 1996 1997 1998 1999 2002 2003 2004 2016 2017 2019 2021 2022 2023 %% David Carlisle Frank Mittelbach %% %% Development of this package was commissioned by Y&Y Inc. @@ -36,7 +36,7 @@ %\ProvidesFile{bm.drv} % \fi % \ProvidesFile{bm.dtx} - [2023/07/08 v1.2f Bold Symbol Support (DPC/FMi)] + [2023/12/19 v1.2f Bold Symbol Support (DPC/FMi)] % % \iffalse %<*driver> @@ -178,14 +178,14 @@ % spacing). So the third example produces identical output to the first % (but \TeX\ takes more time producing it). % -% In the fourth example the |\mathrm{\bm{g}}| is essentially +% In the fourth example the |\mathrm{\bm{{g}}}| is essentially % equivalent to |\mathrm{\mbox{\boldmath$g$}}|. Currently math alphabet % settings are not passed down to `nested' math lists, and so in this % example, the |\mathrm| has no effect, and a bold math italic $\bm g$ % is obtained. % % Similarly the last example is equivalent to -% |$\mbox{\boldmath$\mathrm{g}$}}| and so in this case, one obtains a +% |$\mbox{\boldmath$\mathrm{g}$}$| and so in this case, one obtains a % bold roman \textbf{g}. % % \subsection{Delimiters} diff --git a/Master/texmf-dist/source/latex/tools/bm.ins b/Master/texmf-dist/source/latex/tools/bm.ins index a7424a0e675..c0c8125d101 100644 --- a/Master/texmf-dist/source/latex/tools/bm.ins +++ b/Master/texmf-dist/source/latex/tools/bm.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/calc.dtx b/Master/texmf-dist/source/latex/tools/calc.dtx index 2c4cecbf038..154c6ba26a8 100644 --- a/Master/texmf-dist/source/latex/tools/calc.dtx +++ b/Master/texmf-dist/source/latex/tools/calc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/dcolumn.dtx b/Master/texmf-dist/source/latex/tools/dcolumn.dtx index c8ddaf4ce6b..feb3096ccec 100644 --- a/Master/texmf-dist/source/latex/tools/dcolumn.dtx +++ b/Master/texmf-dist/source/latex/tools/dcolumn.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/delarray.dtx b/Master/texmf-dist/source/latex/tools/delarray.dtx index 86a1a6203f6..61d40b5c744 100644 --- a/Master/texmf-dist/source/latex/tools/delarray.dtx +++ b/Master/texmf-dist/source/latex/tools/delarray.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/enumerate.dtx b/Master/texmf-dist/source/latex/tools/enumerate.dtx index 2818a73a09b..c3889a9157a 100644 --- a/Master/texmf-dist/source/latex/tools/enumerate.dtx +++ b/Master/texmf-dist/source/latex/tools/enumerate.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/fileerr.dtx b/Master/texmf-dist/source/latex/tools/fileerr.dtx index eef222bb6eb..0e8eeb1ffb1 100644 --- a/Master/texmf-dist/source/latex/tools/fileerr.dtx +++ b/Master/texmf-dist/source/latex/tools/fileerr.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/fontsmpl.dtx b/Master/texmf-dist/source/latex/tools/fontsmpl.dtx index 525065cde5f..6e9835e20eb 100644 --- a/Master/texmf-dist/source/latex/tools/fontsmpl.dtx +++ b/Master/texmf-dist/source/latex/tools/fontsmpl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/ftnright.dtx b/Master/texmf-dist/source/latex/tools/ftnright.dtx index 663fa304a94..a3826376dbb 100644 --- a/Master/texmf-dist/source/latex/tools/ftnright.dtx +++ b/Master/texmf-dist/source/latex/tools/ftnright.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/hhline.dtx b/Master/texmf-dist/source/latex/tools/hhline.dtx index 49ac1ae2082..b2d833d965d 100644 --- a/Master/texmf-dist/source/latex/tools/hhline.dtx +++ b/Master/texmf-dist/source/latex/tools/hhline.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/indentfirst.dtx b/Master/texmf-dist/source/latex/tools/indentfirst.dtx index 2314db1c70c..9bbe1871e15 100644 --- a/Master/texmf-dist/source/latex/tools/indentfirst.dtx +++ b/Master/texmf-dist/source/latex/tools/indentfirst.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/l3sys-query.dtx b/Master/texmf-dist/source/latex/tools/l3sys-query.dtx new file mode 100644 index 00000000000..3cba5da4a62 --- /dev/null +++ b/Master/texmf-dist/source/latex/tools/l3sys-query.dtx @@ -0,0 +1,545 @@ +% \iffalse +%% Source File: l3sys-query.dtx +%% Copyright (C) 2024 +%% +%% The LaTeX Project and any individual authors listed elsewhere +%% in this file. +%% +%% This file may be distributed under the terms of the LPPL. +%% See README for details. +% +%<*dtx> + \ProvidesFile{l3sys-query.dtx} +% +%\ProvidesPackage{l3sys-query} +% \ProvidesFile{l3sys-query.drv} +% \fi +% \ProvidesFile{l3sys-query.dtx} + [2024-03-28 v1.0a LaTeX2e interface for l3sys file queries] +% +% \iffalse +%<*driver> +\documentclass{l3doc}%{ltxdoc} +\begin{document} +\DocInput{l3sys-query.dtx} +\end{document} +% +% \fi +% +% \GetFileInfo{l3sys-query.dtx} +% +% \title{\LaTeX\ document interface to the \pkg{l3sys-query} script: +% System queries for LaTeX using Lua\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{\LaTeX\ project} +% \date{\filedate} +% +% +% \maketitle +% +% \tableofcontents +% +% \section{Introduction} +% +% \TeX{} engines provide only very limited access to information about the system +% they are used on: using primitives, one can for example get the size of a single +% file, but not a list of files in a given location. For most documents, this is +% not an issue as they are self-contained. However, for cases where +% \enquote{dynamic} construction of parts of a document is needed based on file +% lists or other system-dependent data, methods to obtain this from (restricted) +% shell escape are desirable. +% +% Security considerations mean that directly querying the system shell is +% problematic for general use. Instead, \emph{restricted} shell escape may be used +% to get many details, provided a suitable tool is available to provide the +% information in a platform-neutral and security-conscious way. The Java program +% \texttt{texosquery}, written by Nicola Talbot, has been available for a number +% of years to provide this facility. As well as file system insight, +% \texttt{texosquery} also provides for example locale data and other system +% information. However, the requirement for Java means that the script is not +% automatically usable when a \TeX{} system is installed. +% +% The \LaTeX{} team have therefore provided a Lua-based script, +% \texttt{l3sys-query}, which conforms to the security requirements of \TeX{} Live +% using Lua to obtain the system information. This means that it can be used +% \enquote{out of the box} across platforms. The facilities provided by +% \texttt{l3sys-query} are more limited than \texttt{texosquery}, partly as some +% information is available in modern \TeX{} systems using primitives, and partly +% as the aim of \texttt{l3sys-query} is to provide information where there are +% defined use cases. Requests for additional data interfaces are welcome. +% +% This package provides a document level \textit{Key-Value} interface +% to The \texttt{l3sys-query} functionality, although as a convenience +% it also summarizes the documentation for the L3 programming +% interface layer (prvided by the \pkg{l3sys} module of +% \pkg{l3kernel}, and of the command line Lua script +% \texttt{l3sys-query} which is distributed separately and provides +% the underlying functionality. +% +% +% +% \section{The document level key-value interface\label{sec:kv}} +% +% This provides an interface to \texttt{l3sys-query} based on +% \pkg{l3keys} that allows the options to be specified and checked +% individually. Internally the supplied key values are used to build +% up the arguments to the commands described above in the L3 +% programming layer commands described in section~\ref{sec:expl3} +% +% Results containing path separators \emph{always} +% use~|/|, irrespective of the platform in use. +% +% +% \begin{function} +% {\QueryWorkingDirectory} +% \begin{syntax} +% \cs{QueryWorkingDirectory} \Arg{result cmd} +% \end{syntax} +% Defines supplied command \meta{result cmd} to hold +% the absolute path to the current working directory of the +% \TeX\ system. +% This is the directory (folder) from which \TeX\ was started, so usually +% the location of the main document file. +% \end{function} +% +% \begin{function} +% {\QueryFiles, \QueryFilesTF} +% \begin{syntax} +% \cs{QueryFiles} \oarg{options} \Arg{spec} \Arg{function} +% \cs{QueryFilesTF} \oarg{options} \Arg{spec} \Arg{function} \Arg{pre code} \Arg{empty list code} +% \end{syntax} +% This generates a file list based on the \meta{spec} and \meta{options}. +% The command then applies \meta{function} to each item in the sequence of filenames. +% The \meta{function} should be a macro body which will be passed the file path as |#1|. +% +% The TF version executes the T (\meta{pre code}) argument before iterating over the list +% and the F (\meta{empty list code}) argument if the list is empty. +% \end{function} +% +% Note that this interface in mapping directly over the sequence of +% filenames does not allow some uses which are provided by the +% programming interface described in the following section, which allows +% the sequence to be manipulated before being used. +% +% The defined keys map very closely to the options of the +% \texttt{l3sys-query} command which is described in +% section~\ref{sec:lua}. +% +% \begin{itemize} +% \item +% The keys \texttt{recursive}, \texttt{ignore-case}, \texttt{reverse}, \texttt{pattern} +% take no values and map directly to the command line options of the same name. +% +% \item +% The key \texttt{sort} accepts the values \texttt{date} and \texttt{name}. +% +% \item +% The key \texttt{type} accepts \texttt{d} or \texttt{f}. +% +% \item +% The key \texttt{exclude} accepts a glob (or Lua pattern) matching +% files to be excluded. The package arranges that the quoting of the +% argument is automatically added if unrestricted shell escape is +% enabled. +% +% \end{itemize} +% +% Within the main \meta{spec} argument, and the value of the \texttt{exclude} key, +% the following characters may need special handling. +% |~| may be used (which \texttt{kpathsea} uses to denote the users home directory). +% |\%|, or at the top level |%|, may be used to produce a literal |%| +% which may be especially useful if the \texttt{pattern} key is used +% as \% is the escape character in Lua patterns. +% +% \subsection{Examples\label{sec:examples2e}} +% +% \begin{itemize} +% \item +% Include every |png| file in the current directory. +% \begin{verbatim} +% \QueryFiles{*.png}{\includegraphics{#1}\par} +% \end{verbatim} +% +% \item +% Input every \TeX\ file with a filename matching \texttt{chapter[0-9].tex}. +% \begin{verbatim} +% \QueryFiles[pattern]{chapter%d.*%.tex}{\input{#1}} +% \end{verbatim} +% \end{itemize} +% +% \section{The L3 programming layer interface\label{sec:expl3}} +% +% \begin{function} +% {\sys_get_query:nN, \sys_get_query:nnN, \sys_get_query:nnnN} +% \begin{syntax} +% \cs{sys_get_query:nN} \Arg{cmd} \Arg{tl var} +% \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \Arg{tl var} +% \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{tl var} +% \end{syntax} +% Sets the \meta{tl var} to the information returned by the +% \texttt{l3sys-query} \meta{cmd}, potentially supplying the \meta{options} +% and \meta{spec} to the query call. The valid \meta{cmd} names are at present +% \begin{itemize} +% \item \texttt{pwd} Returns the absolute path to the current working directory +% \item \texttt{ls} Returns a directory listing, using the \meta{spec} to +% select files and applying the \meta{options} if given +% \end{itemize} +% The \meta{spec} should be a file glob and will automatically be passed to +% the script without shell expansion. +% \end{function} +% +% \begin{function} +% {\sys_split_query:nN, \sys_split_query:nnN, \sys_split_query:nnnN} +% \begin{syntax} +% \cs{sys_split_query:nN} \Arg{cmd} \Arg{seq} +% \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \Arg{seq} +% \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{seq} +% \end{syntax} +% Works as described for \cs{sys_get_query:nnnN}, but sets the \meta{seq} +% to contain one entry for each line returned by \texttt{l3sys-query}. +% \end{function} +% +% \section{The \texttt{l3sys-query} Lua script\label{sec:lua}} +% \subsection{The command line interface} +% +% The command line interface to +% \begin{center} +% \ttfamily +% l3sys-query \meta{cmd} [\meta{option(s)}] [\meta{args}] +% \end{center} +% where \texttt{\meta{cmd}} can be one of the following: +% \begin{itemize}[noitemsep]\ttfamily +% \item ls +% \item ls \meta{args} +% \item pwd +% \end{itemize} +% The \meta{cmd} are described below. The result of the \meta{cmd} will be printed +% to the terminal in an interactive run; in normal usage, this will be piped to +% the calling \TeX{} process. Results containing path separators \emph{always} +% use~|/|, irrespective of the platform in use. +% +% As well as these targets, the script recognizes the options +% \begin{itemize} +% \item |--exclude| Specification for directory entries to exclude +% \item |--ignore-case| Ignores case when sorting directory listings +% \item |--pattern| (|-p|) Treat the \meta{args} as Lua patterns rather +% than converting from wildcards +% \item |--recursive| (|-r|) Enables recursive searching during directory +% listings +% \item |--reverse| Causes sorting to go from highest to lowest rather +% than lowest to highest +% \item |--sort| Sets the method used to sort entries returned by |ls| +% \item |--type| Selects the type of entry returned by |ls| +% \end{itemize} +% The action of these options on the appropriate \meta{cmd(s)} is detailed below. +% +% \subsubsection{\texttt{ls [\meta{args}]}} +% +% Lists the contents of one or more directories, in a manner somewhat reminiscent +% of the Unix command |ls| or the Windows command |dir|. The exact nature of the +% output will depend on the \meta{args}, if given, along with the prevailing +% options. Note that the options names are inspired by ideas from the Unix +% commands |ls| and |find| as well as the Windows command |dir|: they therefore do +% not map directly to those of any one of the command line tools that they +% somewhat mirror. +% +% When no \meta{args} are given, all entries in the current directory will be +% listed, one per line in the output. This will include both files and +% subdirectories. Each entry will include a path relative to the current +% directory: for files \emph{in} the current directory, this will be |./|. The +% order of results will be determined by the underlying operating system process: +% unless requested \emph{via} an option, no sorting takes place. +% +% As standard, the \meta{args} are treated as a file/path name potentially +% including |?| and |*| as wildcards, for example |*.png| or |file?.txt|. +% \begin{verbatim} +% l3sys-query ls '*.png' +% \end{verbatim} +% Some care is needed in preventing expansion of such wildcards by the shell or +% \texttt{texlua} process: these are detailed in Section~\ref{sec:wildcard}. In +% this section, |'| is used to indicate a character being used to suppress +% expansion: this is for example normal on macOS and Linux. +% +% Removal of entries from the listing can be achieved using the |--exclude| +% option, which should be given with a \meta{xarg}, for example +% \begin{verbatim} +% l3sys-query ls --exclude '*.bak' 'graphics/*' +% \end{verbatim} +% Directory entries starting |.| are traditionally hidden on Linux and macOS +% systems: these \enquote{dot} entries are excluded from the output of +% \texttt{l3sys-query}. The entries |.| and |..| for the current and parent +% directory are also excluded from the results returned by \texttt{l3sys-query} as +% they can always be assumed. +% +% For more complex matching, the \meta{args} can be treated as a Lua pattern using +% the |--pattern| (|-p|) option; this also applies to the \meta{xarg} argument to +% the |--exclude| option. For example, the equivalent to wildcard |*.png| could be +% obtained using +% \begin{verbatim} +% l3sys-query ls --pattern '^.*%.png$' +% \end{verbatim} +% +% The results returned by |ls| can be sorted using the |--sort| option. This can +% be set to |none| (use the order from the file system: the default), |name| (sort +% by file name) or |date| (sort by date last modified). The sorting order can be +% reversed using |--reverse|. Sorting normally takes account of case: this can be +% suppressed with the |--ignore-case| option. +% +% The listing can be filtered based on the type of entry using the |--type| +% option. This takes a string argument, one of |d| (directory) or |f| (file). +% +% As standard, only the path specified as part of the \meta{args} is queried. +% However, if the |--recursive| (|-r|) option is set, the query is applied within +% all subdirectories. Subdirectories starting with~|.| (macOS and Linux hidden) +% are excluded from recursion. +% +% For security reasons, only paths within the current working directory can be +% queried, thus for example |graphics/*.png| will list all |png| files in the +% |graphics| subdirectory, but |../graphics/*.png| will yield no output. +% +% \subsubsection{\texttt{pwd}} +% +% Returns the current working directory from which \texttt{l3sys-query} is run. +% From within a \TeX{} run, this will (usually) be the directory containing the +% main file, assuming a command such as +% \begin{verbatim} +% pdflatex main.tex +% \end{verbatim} +% The \texttt{pwd} command is unaffected by any options. +% +% \subsection{Spaces in arguments} +% +% Since \texttt{l3sys-query} is intended primarily for use with restricted shell +% escape calls from \TeX{} processes, handling of spaces is unusual. It is not +% possible to quote spaces in such a call, so for example whilst +% \begin{verbatim} +% l3sys-query ls "foo *" +% \end{verbatim} +% does work from the command prompt to find all files with names starting +% \verb*|foo |, it would not work \emph{via} restricted shell escape. To +% circumvent this, \texttt{l3sys-query} will collect all command line arguments +% after any \meta{options}, and combine these as a space-separated \meta{args}, +% for example allowing +% \begin{verbatim} +% l3sys-query ls foo '*' +% \end{verbatim} +% to achieve the same result as the first example. The result is that the +% \meta{args} will only every be interpreted by \texttt{l3sys-query} as a single +% argument. It also means that spaces cannot be used at the start or end of the +% argument, nor can multiple spaces appear between non-space arguments. +% +% \subsection{Wildcard expansion handling\label{sec:wildcard}} +% +% The handling of wildcards needs some further comment for those using +% \texttt{l3sys-query} from the command line: the \pkg{expl3} interface described +% in Section~\ref{sec:expl3} handles this aspect automatically for the user. +% +% On macOS and Linux, the shell normally expands globs, which include the +% wildcards |*| and |?|, before passing arguments to the appropriate command. +% This can be suppressed by surrounding the argument with |'| characters, hence +% the formulation +% \begin{verbatim} +% l3sys-query ls '*.png' +% \end{verbatim} +% earlier. +% +% On Windows, the shell does no expansion, and thus arguments are passed as-is to +% the relevant command. As such, |'| has no special meaning here. However, to +% allow quoting of wildcards from the shell in a platform-neutral manner, +% \texttt{l3sys-query} will strip exactly one set of |'| characters around each +% argument before further processing. +% +% It is not possible to use |"| quotes at all in the argument passed to +% \texttt{l3sys-query} from \TeX{}, as the \TeX{} system removes all |"| in +% |\input| while handling space quoting. +% +% Restricted shell escape prevents shell expansion of wildcards entirely. On +% non-Windows systems, it does this by ensuring that each argument is |'| quoted +% to ensure further expansion. Thus a \TeX{} call such as +% \begin{verbatim} +% \input|"l3sys-query ls '*.png'" +% \end{verbatim} +% will work if |--shell-escape| is used as the argument is passed directly to the +% shell, but in restricted shell escape will give an error such as: +% \begin{verbatim} +% ! I can't find file `"|l3sys-query ls '*.png'"'. +% \end{verbatim} +% The \LaTeX{} interfaces described above adjust the quoting used depending on the +% |shell-escape| status. +% +% +% \MaybeStop{} +% +% \section{The \LaTeXe\ package implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOn +%<@@=queryfiles> +% \end{macrocode} +% +% The package should eventually work in restricted shell escape but will do +% nothing useful if the process was started with |--no-shell-escape|. +% \begin{macrocode} +\sys_if_shell:F{ + \PackageWarningNoLine{l3sys-query} + {Shell ~Escape ~is ~disabled.\MessageBreak All ~queries ~will ~return ~empty ~results} + } +% \end{macrocode} +% +% \subsection{\cs{QueryWorkingDirectory}} +% |\QueryWorkingDirectory| is a direct call to the |pwd| command provided by \texttt{l3sys-query}. +% \begin{macrocode} +\NewDocumentCommand\QueryWorkingDirectory {m} { + \sys_get_query:nN {pwd} #1 +} +% \end{macrocode} +% +% \subsection{\cs{QueryFiles} and \cs{QueryFilesTF}} +% +% The declarations of these commands are done in two steps to allow catcode chanes +% before the arguments are read. This allows the use of |%| and |^^| in patterns +% at least if the command is not nested in another command argument. (|\%| may be used +% to generate |%| in all cases). +% +% Variables for saving the current definition of |\%| and |~|. +% \begin{macrocode} +\tl_new:N\l_query_percent_tl +\tl_new:N\l_query_tilde_tl +% \end{macrocode} +% +% Allow |%| and |^^| at the top level. +% \begin{macrocode} +\NewDocumentCommand\QueryFiles {} { + \group_begin: + \char_set_catcode_other:N \% + \char_set_catcode_other:N \^ + \QueryFiles_inner + } +% \end{macrocode} +% +% \begin{macrocode} +\char_set_catcode_active:N \~ +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand\QueryFiles_inner {O{}m}{ + \group_end: + \tl_set:Nn\l_tmpa_tl{} + \cs_set_eq:NN \l_query_percent_tl \% + \cs_set_eq:NN \% \c_percent_str + \cs_set_eq:NN \l_query_tilde_tl ~ + \cs_set_eq:NN ~ \c_tilde_str + \keys_set:nn{QueryFiles}{#1} + \exp_args:NnV\sys_split_query:nnnN {ls} \l_tmpa_tl {#2} \l_tmpa_seq + \cs_set_eq:NN \% \l_query_percent_tl + \cs_set_eq:NN ~ \l_query_tilde_tl + \seq_map_inline:Nn\l_tmpa_seq +} +% \end{macrocode} +% +% This duplicates rather than shares code so as to read the function +% and TF arguments with normal catcode regime. +% (This could probably be optimised.) +% \begin{macrocode} +\NewDocumentCommand\QueryFilesTF {} { + \group_begin: + \char_set_catcode_other:N \% + \QueryFilesTF_inner + } +% \end{macrocode} +% +% \begin{macrocode} +\NewDocumentCommand\QueryFilesTF_inner {O{}m}{ + \group_end: + \tl_set:Nn\l_tmpa_tl{} + \cs_set_eq:NN \l_query_percent_tl \% + \cs_set_eq:NN \% \c_percent_str + \cs_set_eq:NN \l_query_tilde_tl ~ + \cs_set_eq:NN ~ \c_tilde_str + \keys_set:nn{QueryFiles}{#1} + \exp_args:NnV\sys_split_query:nnnN {ls} \l_tmpa_tl {#2} \l_tmpa_seq + \cs_set_eq:NN \% \l_query_percent_tl + \cs_set_eq:NN ~ \l_query_tilde_tl + \seq_if_empty:NTF \l_tmpa_seq \use_iii:nnn \__queryfiles_aux:nnn +} +% \end{macrocode} +% +% \begin{macrocode} +\char_set_catcode_space:N \~ +% \end{macrocode} +% +% \begin{macrocode} +\cs_new:Npn \__queryfiles_aux:nnn #1#2#3 { + #2 + \seq_map_inline:Nn\l_tmpa_seq {#1} + } +% \end{macrocode} +% +% Defining the keys. Most take no value and simply add a \texttt{l3sys-query} \texttt{-{}-} +% option to the command linebeing constructed. +% \begin{macrocode} +\keys_define:nn {QueryFiles} { +% \end{macrocode} +% +% \begin{macrocode} +recursive .code:n =\tl_put_right:Nn \l_tmpa_tl {--recursive ~ } , +recursive .value_forbidden:n = true , +% \end{macrocode} +% +% \begin{macrocode} +ignore-case .code:n =\tl_put_right:Nn \l_tmpa_tl {--ignore-case ~ } , +ignore-case .value_forbidden:n = true , +% \end{macrocode} +% +% \begin{macrocode} +reverse .code:n =\tl_put_right:Nn \l_tmpa_tl {--reverse ~ } , +reverse .value_forbidden:n = true , +% \end{macrocode} +% +% \begin{macrocode} +exclude .code:n =\tl_put_right:Ne \l_tmpa_tl { + --exclude ~ + \sys_if_shell_restricted:F' + \exp_not:n{#1} + \sys_if_shell_restricted:F' + ~ } , +exclude .value_required:n = true , +% \end{macrocode} +% +% The |type| key checks the supplied value is valid |d| for directories +% or |f| for files The default behaviour lists both. +% \begin{macrocode} +type .choices:nn = {d,f} + {\tl_put_right:Nn \l_tmpa_tl {--type ~ #1 ~ }} , +% \end{macrocode} +% +% The |sort| key checks the supplied value is valid |date| or |name|. +% \begin{macrocode} +sort .choices:nn = {date,name} +{\tl_put_right:Nn \l_tmpa_tl {--sort ~ #1 ~ }} , +% \end{macrocode} +% +% \begin{macrocode} +pattern .code:n =\tl_put_right:Nn \l_tmpa_tl {--pattern ~ } , +pattern .value_forbidden:n = true , +% \end{macrocode} +% +% \begin{macrocode} +} +% \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +% \end{macrocode} +% +% \begin{macrocode} +% +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex/tools/l3sys-query.ins b/Master/texmf-dist/source/latex/tools/l3sys-query.ins new file mode 100644 index 00000000000..163eec0058c --- /dev/null +++ b/Master/texmf-dist/source/latex/tools/l3sys-query.ins @@ -0,0 +1,76 @@ +%% +%% This file will generate fast loadable files and documentation +%% driver files from the doc files in this package when run through +%% LaTeX or TeX. +%% +%% Copyright (C) 1993-2024 +%% The LaTeX Project and any individual authors listed elsewhere +%% in this file. +%% +%% This file is part of the Standard LaTeX `Tools Bundle'. +%% ------------------------------------------------------- +%% +%% It may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3c +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% As this file contains legal notices, it is NOT PERMITTED to modify +%% this file in any way that the legal information placed into +%% generated files is changed (i.e., the files generated when the +%% original file is executed). This restriction does not apply if +%% (parts of) the content is reused in a different WORK producing its +%% own generated files. +%% +%% The list of all files belonging to the `Tools Bundle' is +%% given in the file `manifest.txt'. +%% +%% +%% --------------- start of docstrip commands ------------------ +%% +\input docstrip + +\keepsilent + +\usedir{tex/latex/tools} + +\preamble + +This is a generated file. + +The source is maintained by the LaTeX Project team and bug +reports for it can be opened at https://latex-project.org/bugs/ +(but please observe conditions on bug reports sent to that address!) + +Copyright (C) 1993-2024 +The LaTeX Project and any individual authors listed elsewhere +in this file. + +This file was generated from file(s) of the Standard LaTeX `Tools Bundle'. +-------------------------------------------------------------------------- + +It may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3c +of this license or (at your option) any later version. +The latest version of this license is in + https://www.latex-project.org/lppl.txt +and version 1.3c or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +This file may only be distributed together with a copy of the LaTeX +`Tools Bundle'. You may however distribute the LaTeX `Tools Bundle' +without such generated files. + +The list of all files belonging to the LaTeX `Tools Bundle' is +given in the file `manifest.txt'. + +\endpreamble + +\keepsilent + +\generate{\file{l3sys-query.sty}{\from{l3sys-query.dtx}{package}}} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/tools/layout.dtx b/Master/texmf-dist/source/latex/tools/layout.dtx index 2798bd4f60d..a2fc87a6a51 100644 --- a/Master/texmf-dist/source/latex/tools/layout.dtx +++ b/Master/texmf-dist/source/latex/tools/layout.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/longtable.dtx b/Master/texmf-dist/source/latex/tools/longtable.dtx index 2a61ab0c87e..cc3a939e7ad 100644 --- a/Master/texmf-dist/source/latex/tools/longtable.dtx +++ b/Master/texmf-dist/source/latex/tools/longtable.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -27,8 +27,9 @@ \ProvidesFile{longtable.dtx} % %\NeedsTeXFormat{LaTeX2e}[1995/06/01] -%\providecommand\DeclareRelease[3]{} -%\providecommand\DeclareCurrentRelease[2]{} +% +% Try the 2020 version for any rollback before that date: +%\DeclareRelease{}{1994-06-01}{longtable-2020-01-07.sty} % %\DeclareRelease{v4.13}{2020-01-02}{longtable-2020-01-07.sty} %\DeclareCurrentRelease{}{2020-02-07} @@ -37,7 +38,7 @@ % \ProvidesFile{longtable.drv} % \fi % \ProvidesFile{longtable.dtx} - [2023-11-01 v4.19 Multi-page Table package (DPC)] + [2024-04-26 v4.20 Multi-page Table package (DPC)] % % \iffalse %<*driver> @@ -1048,6 +1049,14 @@ \if@twocolumn \LT@err{longtable not in 1-column mode}\@ehc \fi +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/vmode/begin}% +% \end{macrocode} +% +% \begin{macrocode} \begingroup % \end{macrocode} % Check for an optional argument. @@ -1056,7 +1065,14 @@ % \end{macrocode} % \end{macro} % +% +% % \begin{macro}{\LT@array} +% \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn +% \end{macrocode} +% % Start setting the alignment. % Based on "\@array" from the \LaTeX\ kernel % and the \package{array} package. @@ -1066,7 +1082,43 @@ % so that "\caption" works correctly. % \begin{macrocode} \def\LT@array[#1]#2{% - \refstepcounter{table}\stepcounter{LT@tables}% +% \end{macrocode} +% +% With respect to tagging we have a complicated situation with +% longtable. When at the begin the \cs{endhead}, +% \cs{endfirsthead}, \cs{endfoot} and \cs{endlastfoot} are used to +% setup head and foot they create each a structure subtree with one or +% more rows. From these structures we want to keep at most two (head +% and foot) and move the foot to the end of the table. When the head +% and foot boxes are (re)inserted on following pages we want to mark +% them up as artifact with the exception of the head at the begin and +% the foot box at the end. +% +% TODO: When a line is killed the structure subtree is there already +% too and must be removed. If hard to do, then maybe at first warn if the +% construction is used. +% +% \cs{LT@array} is executed in a group, so we can disable para-tagging here. +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/init} + \@kernel@refstepcounter{table}\stepcounter{LT@tables} +% \end{macrocode} +% The target is created rather late and a \cs{label} can come earlier, +% so we have to define \cs{@currentHref} explicitly. We can't currently +% assume that \cs{theHtable} is defined always. +% \begin{macrocode} + \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable} +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_gzero_row_count: +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/longtable/init} % \end{macrocode} % Set up the glue around the table if an optional argument given. % \begin{macrocode} @@ -1101,17 +1153,18 @@ % here so that you can load the \package{array} package before or after % \package{longtable}. % \begin{macrocode} - \let\LT@@tabarray\@tabarray - \let\LT@@hl\hline + \let\LT@@@@tabarray\@tabarray + \let\LT@@@@hl\hline \def\@tabarray{% - \let\hline\LT@@hl + \let\hline\LT@@@@hl % \end{macrocode} %\begin{verbatim} % \let\multicolumn\LT@mcol %\end{verbatim} % \begin{macrocode} - \LT@@tabarray}% - \let\\\LT@tabularcr\let\tabularnewline\\% + \LT@@@@tabarray}% + \let\\\LT@tabularcr + \let\tabularnewline\\% \def\newpage{\noalign{\break}}% % \end{macrocode} % \changes{v4.05}{1996/11/12} @@ -1128,8 +1181,8 @@ % \end{macrocode} % % \changes{v4.08}{1998/01/20} -% {Move \cs{@endpbox} definition earlier and define \cs{@@endpbox} -% and \cs{@@startpbox} for non-array case. tools/2736} +% {Move \cs{@endpbox} definition earlier and define \cs{@@@@endpbox} +% and \cs{@@@@startpbox} for non-array case. tools/2736} % \begin{macrocode} \let\@endpbox\LT@endpbox % \end{macrocode} @@ -1142,8 +1195,8 @@ \let\@acol\@tabacol \let\@classz\@tabclassz \let\@classiv\@tabclassiv \def\@startpbox{\vtop\LT@startpbox}% - \let\@@startpbox\@startpbox - \let\@@endpbox\@endpbox + \let\@@@@startpbox\@startpbox + \let\@@@@endpbox\@endpbox \let\LT@LL@FM@cr\@tabularcr \else % \end{macrocode} @@ -1172,6 +1225,11 @@ \begingroup \@mkpream{#2}% % \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_count_table_cols: +% \end{macrocode} % We need to rename "\@preamble" here as F.M.'s scheme uses % "\global", and we may need to nest "\@mkpream", eg for % "\multicolumn" @@ -1180,6 +1238,11 @@ % \begin{macrocode} \xdef\LT@bchunk{% % \end{macrocode} +% We aren't inside any row when a chunk starts. +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_inbetween_rows: +% \end{macrocode} % \changes{v4.00}{1996/04/08} % {(DK) Increment Chunk counter} % \begin{macrocode} @@ -1205,7 +1268,21 @@ % \begin{macrocode} \tabskip\LTleft \noexpand\halign to\hsize\bgroup % \tabskip\LTleft\halign to\hsize\bgroup - \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}% + \tabskip\z@ \@arstrut +% \end{macrocode} +% Insert the tagging socket to start the row and initialize the cell +% data for the row. +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/row/begin}% +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_init_cell_data_for_row: +% \end{macrocode} +% \begin{macrocode} + \@preamble \tabskip\LTright \cr}% \endgroup % \end{macrocode} % Find out how many columns we have (store in "\LT@cols"). @@ -1220,11 +1297,57 @@ % A few more internal commands for \env{longtable}. % \begin{macrocode} \m@th\let\par\@empty - \everycr{}\lineskip\z@\baselineskip\z@ +% \end{macrocode} +% Tagging socket and conditional +% \begin{macrocode} + \everycr{% + \noalign{% +% \end{macrocode} +% In \pkg{longtable} we have a bunch of extra \cs{cr}s that are +% executed whenever a chunk ends. In that case they should not +% increment the main row counter, sigh. +% +% TODO: At the moment this tracing still exposes the internal row counter! +% \begin{macrocode} + \@@_trace:n {--longtable-->~chunk~row:~ \the\LT@rows \space + row:~ \the\g_@@_row_int \space + column:~ \the\g_@@_col_int + } +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \tbl_if_row_was_started:T + { + \UseTaggingSocket{tbl/row/end} +% \end{macrocode} +% The next setting prevents any of the additional \cs{cr}s at the end of the +% chunk to add another /TR. Then once we really start a new chunk +% it gets incremented so\ldots +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_inbetween_rows: + } +% \end{macrocode} +% And for the same reason such \cs{cr}s should not increment the +% main row counter (but it has to be incremented after the preamble +% of a chunk), so here we test against \cs{LT@rows} which is +% \cs{LTchunksize} at the end of a chunk. +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \int_compare:nNnT \LT@rows < \LTchunksize + { \tbl_gincr_row_count: } % next is row about to start + }% + }% +% \end{macrocode} +% \begin{macrocode} + \lineskip\z@\baselineskip\z@ % \end{macrocode} % Start the first chunk. % \begin{macrocode} \LT@bchunk} +\ExplSyntaxOff +%<@@=> % \end{macrocode} % \end{macro} % @@ -1251,6 +1374,11 @@ % force the page-breaker to wake up. The second "\endgraf" is there so % that "\pagetotal" is updated and so takes "\LTpre" into account. % \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn +% \end{macrocode} +% +% \begin{macrocode} \def\LT@start{% \let\LT@start\endgraf \endgraf\penalty\z@\vskip\LTpre\endgraf @@ -1334,7 +1462,7 @@ % \changes{v3.14}{1995/05/02} % {Set \cs{@colroom}, for tools/1584} % \begin{macrocode} - \global\@colroom\@colht + \global\@colroom\@colht % \end{macrocode} % If the foot is non empty, reduce the "\vsize" and "\@colroom" % accordingly. @@ -1342,24 +1470,46 @@ % {Rearrange vertical space tests for tools/3512 (floats on same page)} % \begin{macrocode} \ifvoid\LT@foot\else -% \advance\vsize-\ht\LT@foot \global\advance\vsize-\ht\LT@foot \global\advance\@colroom-\ht\LT@foot \dimen@\pagegoal\advance\dimen@-\ht\LT@foot\pagegoal\dimen@ \maxdepth\z@ \fi % \end{macrocode} +% +% \begin{macrocode} + \MakeLinkTarget{table} +% \end{macrocode} % Put the table head on the page, and then switch to the new output % routine. % \changes{v4.11}{2004/02/01} % {\cs{nobreak}, for tools/3484} % \begin{macrocode} \ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/longtable/head} +% \end{macrocode} +% +% \begin{macrocode} \output{\LT@output}} +\ExplSyntaxOff +%<@@=> % \end{macrocode} % \end{macro} % +% +% +% % \begin{macro}{\endlongtable} +% +% \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn +% \end{macrocode} +% % Called by "\end{longtable}". % \begin{macrocode} \def\endlongtable{% @@ -1370,11 +1520,23 @@ % been shortened, or the table numbering has gone awry). In that case % we at least start collecting valid new information with the last % chunk of this table, by removing the width constraint. +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \tbl_crcr:n {endlongtable} +% \end{macrocode} +% % \changes{v4.01}{1996/04/11} % {(DPC) use \cs{noalign} to sneak in \cs{LT@entry@chop}} % \begin{macrocode} - \crcr \noalign{% +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/longtable/finalize} +% \end{macrocode} +% +% \begin{macrocode} \let\LT@entry\LT@entry@chop \xdef\LT@save@row{\LT@save@row}}% \LT@echunk @@ -1414,10 +1576,10 @@ % \changes{v4.04}{1996/05/24} % {Use \cs{LT@final@warn}} % \begin{macrocode} - \ifx\LT@save@row\LT@@save@row + \ifx\LT@save@row\LT@@@@save@row \else - \LT@warn{Column \@width s have changed\MessageBreak - in table \thetable}% + \LT@warn{Column~ widths~ have~ changed\MessageBreak + in~ table~ \thetable}% \LT@final@warn \fi % \end{macrocode} @@ -1449,7 +1611,15 @@ % \end{macrocode} % Footnotes. As done in the \package{multicol} package. % \begin{macrocode} - \ifvoid\footins\else\insert\footins{}\fi} + \ifvoid\footins\else\insert\footins{}\fi +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/vmode/end}% +} +\ExplSyntaxOff +%<@@=> % \end{macrocode} % \end{macro} % @@ -1518,6 +1688,10 @@ \protected\def\LT@tabularcr{% \relax\iffalse{\fi\ifnum0=`}\fi \@ifstar +% \end{macrocode} +% TODO: as we replace crcr later in one case, we probably have to +% implement some further logic there! +% \begin{macrocode} {\def\crcr{\LT@crcr\noalign{\nobreak}}\let\cr\crcr \LT@t@bularcr}% {\LT@t@bularcr}} @@ -1544,8 +1718,13 @@ % \end{macrocode} % \end{macro} % +% +% +% % \begin{macro}{\LT@t@bularcr} % \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn \def\LT@t@bularcr{% % \end{macrocode} % Increment the counter, and do \env{tabular}'s "\\" or finish the @@ -1555,6 +1734,13 @@ % \begin{macrocode} \global\advance\LT@rows\@ne \ifnum\LT@rows=\LTchunksize +% \end{macrocode} +% At the end of the chunk \verb=\\= is doing something special and +% so we lose \verb=\tbl_count_missing_cells:n=. Below is about the +% right place to add it do this code branch. +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_count_missing_cells:n {echunk} \gdef\LT@setprevdepth{% \prevdepth\z@ \global\let\LT@setprevdepth\relax}% @@ -1563,6 +1749,8 @@ \ifnum0=`{}\fi \expandafter\LT@LL@FM@cr \fi} +\ExplSyntaxOff +%<@@=> % \end{macrocode} % \end{macro} % @@ -1943,7 +2131,9 @@ % This code is based on "\cline". Two copies of the line are produced, % as described above. % \begin{macrocode} -\def\LT@@hline{% +%<@@=tbl> +\ExplSyntaxOn +\def\LT@@@@hline{% \ifx\@let@token\hline \global\let\@gtempa\@gobble \gdef\LT@sep{\penalty-\@medpenalty\vskip\doublerulesep}% @@ -1954,11 +2144,25 @@ \ifnum0=`{\fi}% \multispan\LT@cols \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr - \noalign{\LT@sep}% +% \end{macrocode} +% Don't update the row counter, or rather undo the update done in \cs{everycr}: +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \noalign{ + \tbl_gdecr_row_count: + \LT@sep} \multispan\LT@cols \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr - \noalign{\penalty\@M}% +% \end{macrocode} +% Same here. +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \noalign{ + \tbl_gdecr_row_count: + \penalty\@M} \@gtempa} +\ExplSyntaxOff +%<@@=> % \end{macrocode} % \end{macro} % @@ -2049,13 +2253,15 @@ % \begin{macro}{\LT@output} % Actually this is not so bad, with FM leading the way. % \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn \def\LT@output{% \ifnum\outputpenalty <-\@Mi \ifnum\outputpenalty > -\LT@end@pen % \end{macrocode} % If this was a float or a marginpar we complain. % \begin{macrocode} - \LT@err{floats and marginpars not allowed in a longtable}\@ehc + \LT@err{floats~ and~ marginpars~ not~ allowed~ in~ a~ longtable}\@ehc \else % \end{macrocode} % We have reached the end of the table, on the scroll at least, @@ -2103,6 +2309,13 @@ % \begin{macrocode} \unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi % \end{macrocode} +% Handle foot box when tagging: +% +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/longtable/foot} +% \end{macrocode} +% % End of "\ifnum\outputpenalty > -\LT@end@pen". % \begin{macrocode} \fi @@ -2114,6 +2327,15 @@ % If we have not reached the end of the table, % \begin{macrocode} \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT@foot\vss}% +% \end{macrocode} +% +% Handle foot box when tagging: +% \changes{v4.19}{2023/12/16}{Support for tagged PDF} +% \begin{macrocode} + \UseTaggingSocket{tbl/longtable/foot} +% \end{macrocode} +% +% \begin{macrocode} \@makecol \@outputpage % \end{macrocode} @@ -2133,8 +2355,15 @@ % \begin{macrocode} \fi} % \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +%<@@=> +% \end{macrocode} % \end{macro} % +% +% % \subsection{Commands for the table head and foot} % % \begin{macro}{\LT@end@hd@ft} @@ -2142,20 +2371,86 @@ % box specified by "#1". Issue an error if the table has already % started. Then start a new chunk. % \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn \def\LT@end@hd@ft#1{% +% \end{macrocode} +% +% This command is used to store the head and foot boxes. +% We need to retrieve and store the row so that we can clean +% up the structure in the finalize code. +% +% To handle missing columns in the header we need this: +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_if_row_was_started:TF + { +% \end{macrocode} +% TODO: This is exposing internal counters, so it should be encapsulated +% in some interface command (but I'm not sure what that should be +% called, so not done yet. +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_count_missing_cells:n {head/foot} + \int_step_inline:nn + { \LT@rows + 1 } + { + \seq_gput_left:ce + {g_@@_\cs_to_str:N #1 _rows_seq } + { \int_eval:n {\g_@@_row_int + 1 - ##1 } } + } +% \end{macrocode} +% We also have to set the chunk rows to its max value before +% calling \cs{LTechunk} so that we don't get extra increments of +% the main row counter due to \cs{everycr}. +% \begin{macrocode} + \int_gset:Nn \LT@rows { \LTchunksize } + } +% \end{macrocode} + +% If we are still in column zero then we had an empty \cs{endhead} +% and so making any assignment, etc., would start a row --- something we don't want. +% To get out of this trap we run \cs{crcr} (which would normally +% come inside \cs{LT@echunk}. That will then trigger \cs{everycr} +% and update row counter unnecessarily, but now we have a defined state, so +% we can use \cs{noalign} to undo that. +% We also change \cs{LT@rows} so that further \cs{cr}s do not do +% any harm (as explained above. +% +% The \cs{crcr} inside \cs{LT@echunk} will be bypassed in that case +% as we have just executed a \cs{crcr} and are still in scanning modus for +% \cs{omit} or \cs{noalign}. +% \begin{macrocode} + { + \crcr + \noalign{ +% \end{macrocode} +% +% \changes{v4.19}{2023/12/16}{Managing cell indexes} +% \begin{macrocode} + \tbl_gdecr_row_count: % undo the increment + \int_gset:Nn \LT@rows { \LTchunksize } + } + } \LT@echunk % \end{macrocode} % Changed from "\relax" to "\endgraf" at V3.04, see "\LT@start". % \begin{macrocode} \ifx\LT@start\endgraf \LT@err - {Longtable head or foot not at start of table}% - {Increase LTchunksize}% + {Longtable~ head~ or~ foot~ not~ at~ start~ of~ table}% + {Increase~ LTchunksize}% \fi \setbox#1\box\z@ + \@@_trace:n {-->>~ Saving~\noexpand#1} \LT@get@widths \LT@bchunk} % \end{macrocode} +% +% \begin{macrocode} +\ExplSyntaxOff +%<@@=> +% \end{macrocode} % \end{macro} % % \begin{macro}{\endfirsthead} @@ -2255,6 +2550,24 @@ % \end{macrocode} % \end{macro} % +% +% +% +% +% Some variables need for the tagging support. +% \begin{macrocode} +%<@@=tbl> +\ExplSyntaxOn + \seq_new:N \g_@@_LT@firsthead_rows_seq + \seq_new:N \g_@@_LT@head_rows_seq + \seq_new:N \g_@@_LT@lastfoot_rows_seq + \seq_new:N \g_@@_LT@foot_rows_seq +\ExplSyntaxOff +%<@@=> +% \end{macrocode} +% +% +% % \begin{macrocode} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/longtable.ins b/Master/texmf-dist/source/latex/tools/longtable.ins index 5c3ad270638..60b74615718 100644 --- a/Master/texmf-dist/source/latex/tools/longtable.ins +++ b/Master/texmf-dist/source/latex/tools/longtable.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/multicol.dtx b/Master/texmf-dist/source/latex/tools/multicol.dtx index 2676d03aa18..4d864480029 100644 --- a/Master/texmf-dist/source/latex/tools/multicol.dtx +++ b/Master/texmf-dist/source/latex/tools/multicol.dtx @@ -86,11 +86,10 @@ %<*dtx> \ProvidesFile{multicol.dtx} % -%\NeedsTeXFormat{LaTeX2e}[2018-04-01] -% -%\providecommand\DeclareRelease[3]{} -%\providecommand\DeclareCurrentRelease[2]{} % +% For any rollback before 2017 load the 2017 version and hope for the best: +%\DeclareRelease{}{1994-06-01}{multicol-2017-04-11.sty} +% %\DeclareRelease{}{2017-04-11}{multicol-2017-04-11.sty} %\DeclareRelease{v1.8}{2019-10-01}{multicol-2019-10-01.sty} %\DeclareCurrentRelease{}{2021-11-15} @@ -99,10 +98,10 @@ % \ProvidesFile{multicol.drv} % \fi % \ProvidesFile{multicol.dtx} - [2023/03/30 v1.9f multicolumn formatting (FMi)] + [2024/05/23 v1.9h multicolumn formatting (FMi)] +% % % -%% % % \changes{v1.9c}{2021/11/30}{Added rollback to v1.8} % \changes{v1.5n}{1997/06/05}{Applied improvement of documentation, @@ -919,9 +918,22 @@ % And we don't show macro names in the margin. % \begin{macrocode} \setcounter{IndexColumns}{4} -\let\DescribeMacro\SpecialUsageIndex -\let\DescribeEnv\SpecialEnvIndex -\renewcommand\PrintMacroName[1]{} +% \end{macrocode} +% +% The following redefinitions have to be moved until after the +% preamble because version 3 of \pkg{doc} resets them after the +% premable (this is tmp, because \pkg{hypdoc} is not yet +% integrated, but as we all know, tmp solutions have a tendency to +% survive for a long time\ldots). +% \begin{macrocode} +\AddToHook{begindocument}{% + \let\DescribeMacro\SpecialUsageIndex + \let\DescribeEnv\SpecialEnvIndex + \renewcommand\PrintMacroName[1]{}% +} +% \end{macrocode} +% +% \begin{macrocode} \CodelineIndex %\DisableCrossrefs % Partial index \RecordChanges % Change log @@ -1082,7 +1094,7 @@ % better test for this situation. Otherwise, we will get a \TeX{} % stack overflow as this would generate a self-referencing definition. % \changes{v1.6e}{2004/02/14}{Avoid self-referencing definition of -% \cs{@footnotetext} (pr/3618)}. +% \cs{@footnotetext} (pr/3618)} % \begin{macrocode} \ifx\@footnotetext\mult@footnotetext \else @@ -2376,7 +2388,7 @@ % If |\raggedcolumns| is in force we add a |vfill| at the bottom by % unboxing the split box. % But we need to unbox anyway to ensure that at the end of the box -% we do not have unwanted space. This can sneak in in certain +% we do not have unwanted space. This can sneak in, in certain % situations, for example, if two lists follow each other and we % break between them. While such space is usually zero it still has % an effect because it hides depth of the last line in the column @@ -2925,7 +2937,11 @@ % We start by setting the kept marks by updating them with any % marks from this box. This has to be done \emph{before} we add a % penalty of $-10000$ to the top of the box, otherwise only an -% empty box will be considered. +% empty box will be considered. But even that is not enough: the box +% may contain \cs{columnbreak}s in which case doing some artifical +% splitting to get the marks out still fails to see all marks +% unless we take some special precaution in \cs{get@keptmarks} +% (which is now done). % \changes{v1.5h}{1994/08/26}{Get kept marks first} % \begin{macrocode} \get@keptmarks\mult@box @@ -3751,8 +3767,15 @@ % everything is split off. As a result |\splitfirstmark| and % |\splitbotmark| will contain the first and last mark in the box % respectively. +% +% Unfortunately, a simple \cs{vsplit} is not enough if the material +% contains forced breaks in that case we first have to get rid of +% those which is why we do this work in a separate macro that can +% call itself recursively. +% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark +% extraction (gh/1130)} % \begin{macrocode} - \setbox#1\vsplit#1to\maxdimen + \mc@get@all@box@marks #1% % \end{macrocode} % Therefore we can now set the kept marks which is a global % operation and afterwards close the group. This will restore the @@ -3773,6 +3796,29 @@ % \end{macro} % % +% \begin{macro}{\mc@get@all@box@marks} +% This macro splits a box to \cs{maxdimen} in order to get at the +% marks inside. If it turns out that we have a remainder after the +% split (e.g., if there was a \cs{columnbreak} in the material) we +% stitch the two parts together again (which omits the forced +% break) and recurse. Eventually, everything is split off and the +% split marks will then have the appropriate values. +% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark +% extraction (gh/1130)} +% \begin{macrocode} +\def\mc@get@all@box@marks #1{% + \setbox\@tempboxa\vsplit#1to\maxdimen + \ifvoid#1\else + \setbox#1\vbox{\unvbox\@tempboxa \unvbox#1}% + \mc@get@all@box@marks #1% + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% % \begin{macro}{\set@keptmarks} % The macro |\set@keptmarks| is responsible for setting % |\kept@firstmark| and |\kept@botmark|, by checking the current diff --git a/Master/texmf-dist/source/latex/tools/multicol.ins b/Master/texmf-dist/source/latex/tools/multicol.ins index fa561e0bb1e..7a7ef27d248 100644 --- a/Master/texmf-dist/source/latex/tools/multicol.ins +++ b/Master/texmf-dist/source/latex/tools/multicol.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/rawfonts.dtx b/Master/texmf-dist/source/latex/tools/rawfonts.dtx index 4b930f3ea70..3ffa2032c38 100644 --- a/Master/texmf-dist/source/latex/tools/rawfonts.dtx +++ b/Master/texmf-dist/source/latex/tools/rawfonts.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/shellesc.dtx b/Master/texmf-dist/source/latex/tools/shellesc.dtx index aa707fe550a..8a556de9229 100644 --- a/Master/texmf-dist/source/latex/tools/shellesc.dtx +++ b/Master/texmf-dist/source/latex/tools/shellesc.dtx @@ -1,6 +1,6 @@ % \iffalse %% Source File: shellesc.dtx -%% Copyright (C) 2015-2023 +%% Copyright (C) 2015-2024 %% %% The LaTeX Project and any individual authors listed elsewhere %% in this file. diff --git a/Master/texmf-dist/source/latex/tools/showkeys.dtx b/Master/texmf-dist/source/latex/tools/showkeys.dtx index c90b3863e1a..b6717950a77 100644 --- a/Master/texmf-dist/source/latex/tools/showkeys.dtx +++ b/Master/texmf-dist/source/latex/tools/showkeys.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -22,16 +22,15 @@ % \fi % \iffalse %% File: showkeys.dtx Copyright (C) 1992-1997 David Carlisle -%% File: showkeys.dtx Copyright (C) 2006-2019 David Carlisle, LaTeX Project +%% File: showkeys.dtx Copyright (C) 2006-2024 David Carlisle, LaTeX Project % %<*dtx> \ProvidesFile{showkeys.dtx} % %\NeedsTeXFormat{LaTeX2e} % -%\providecommand\DeclareRelease[3]{} -%\providecommand\DeclareCurrentRelease[2]{} -% +% For every rollback request before 2022 use the 2014 version: +%\DeclareRelease{}{1994-06-01}{showkeys-2014-10-28.sty} %\DeclareRelease{}{2014-10-28}{showkeys-2014-10-28.sty} %\DeclareCurrentRelease{}{2022-06-01} % @@ -39,7 +38,7 @@ % \ProvidesFile{showkeys.drv} % \fi % \ProvidesFile{showkeys.dtx} - [2023/07/08 v3.19 Show cite and label keys (DPC, MH)] + [2024/05/23 v3.21 Show cite and label keys (DPC, MH)] % % \iffalse %<*driver> @@ -417,6 +416,8 @@ % \end{macrocode} % \changes{v3.02}{1995/03/17} % {New code for `in label' case.} +% \changes{v3.20}{2023/12/16} +% {Avoid adding an extra box layer github/1123} % If the |\label| is straight after |\item| (|\bibitem| is handled by % this case as well) then the item label has not been added to the page % yet. It is hanging around in the box |\@labels| waiting for the @@ -425,7 +426,7 @@ \global\setbox\@labels\hbox{% \llap{\SK@lab\SK@lab@relax \kern\@totalleftmargin\kern\marginparsep}% - \box\@labels}% + \unhbox\@labels}% % \end{macrocode} % % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/somedefs.dtx b/Master/texmf-dist/source/latex/tools/somedefs.dtx index 02653a13939..156621d70e2 100644 --- a/Master/texmf-dist/source/latex/tools/somedefs.dtx +++ b/Master/texmf-dist/source/latex/tools/somedefs.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/tabularx.dtx b/Master/texmf-dist/source/latex/tools/tabularx.dtx index 6d59ca4c228..52ee62cad90 100644 --- a/Master/texmf-dist/source/latex/tools/tabularx.dtx +++ b/Master/texmf-dist/source/latex/tools/tabularx.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -31,7 +31,7 @@ % \ProvidesFile{tabularx.drv} % \fi % \ProvidesFile{tabularx.dtx} - [2023/07/08 v2.11c `tabularx' package (DPC)] + [2023/12/11 v2.12a `tabularx' package (DPC)] % \iffalse %<*driver> \documentclass{ltxdoc} @@ -261,6 +261,25 @@ % This behaviour of the package can be customised slightly % as noted in the documentation of the code section. % +% \section{Support for tagged PDF} +% +% With version 2.12a the package is made tagging aware, which means that +% it will automatically produce tagged tables (necessary, for example, for +% accessibility) if tagging is requested via \cs{DocumentMetadata}. +% +% More granular control, e.g., explicitly deciding which cells are +% header cells, etc., is currently under development, but syntax for +% this will not appear in this package. Instead it will become +% available across all tabular-generating packages and then +% automatically apply here as well. +% +% Enabling \LaTeX{} to automatically produce tagged PDF is a long-term +% project and this is a tiny step in this puzzle. For more information +% on the project and already available functionality, see +% \url{https://latex-project.org/publications/indexbytopic/pdf} and +% \url{https://github.com/latex3/tagging-project}. +% +% % \MaybeStop{} % % \section{The Macros} @@ -269,6 +288,14 @@ %<*package> % \end{macrocode} % +% We only need two changes for tagging support, but they require +% that a recent \LaTeX{} kernel is used (which should be no problem +% if \texttt{tools} is distributed in parallel with the kernel. +% \changes{v2.12a}{2023/12/11}{Require newer LaTeX kernel} +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e}[2024/06/01] +% \end{macrocode} +% % \changes{v2.00}{1994/02/07} % {New Option Handling} % \begin{macrocode} @@ -506,7 +533,15 @@ % \begin{macrocode} \TX@typeout@ {\@spaces Table Width\@spaces Column Width\@spaces X Columns}% -% \end{macrocode}% +% \end{macrocode} +% +% While we do trial typesetting we suspend any tagging if that is +% active: +% \changes{v2.12a}{2023/12/11} +% {Suspend any tagging while doing trial typesetting} +% \begin{macrocode} + \SuspendTagging {tabularx}% +% \end{macrocode} % First attempt. Modify the {\ttfamily X} definition to count {\ttfamily % X} columns. % \begin{macrocode} @@ -523,6 +558,12 @@ \TX@trial{}% \repeat % \end{macrocode} +% +% And here we restart it again: +% \begin{macrocode} + \ResumeTagging {tabularx}% +% \end{macrocode} +% % One last time, with warnings back on (see appendix D) % use {\ttfamily tabular*} to put it in a box of the right size, in case % the algorithm failed to find the correct size. @@ -737,8 +778,9 @@ % Make the table, and finish the hbox. % Since v1.06, "\toks@" contains the preamble specification, % and possible optional argument, as well as the table body. +% % \begin{macrocode} - \expandafter\tabular\the\toks@ + \expandafter\tabular\the\toks@ \endtabular}% % \end{macrocode} % Since v1.05 reset all \LaTeX\ counters, by executing "\TX@ckpt". @@ -961,6 +1003,7 @@ % \end{macrocode} % \end{macro} % +% % \begin{macrocode} % % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/tabularx.ins b/Master/texmf-dist/source/latex/tools/tabularx.ins index 6e81e934325..fdce598d379 100644 --- a/Master/texmf-dist/source/latex/tools/tabularx.ins +++ b/Master/texmf-dist/source/latex/tools/tabularx.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/theorem.dtx b/Master/texmf-dist/source/latex/tools/theorem.dtx index e3a8e90b8c2..a9c3ccae3ed 100644 --- a/Master/texmf-dist/source/latex/tools/theorem.dtx +++ b/Master/texmf-dist/source/latex/tools/theorem.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/tools.ins b/Master/texmf-dist/source/latex/tools/tools.ins index 6898faead37..8687d49d7f7 100644 --- a/Master/texmf-dist/source/latex/tools/tools.ins +++ b/Master/texmf-dist/source/latex/tools/tools.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -49,7 +49,7 @@ reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -178,6 +178,13 @@ given in the file `manifest.txt'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SimplePackage{shellesc} + +% Shell Filee System Queries +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\batchinput{l3sys-query.ins} + + + % File-Error files %%%%%%%%%%%%%%%%%% \generate{% diff --git a/Master/texmf-dist/source/latex/tools/trace.dtx b/Master/texmf-dist/source/latex/tools/trace.dtx index 788f8316204..27a39c776b4 100644 --- a/Master/texmf-dist/source/latex/tools/trace.dtx +++ b/Master/texmf-dist/source/latex/tools/trace.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. diff --git a/Master/texmf-dist/source/latex/tools/varioref.dtx b/Master/texmf-dist/source/latex/tools/varioref.dtx index e801c54f818..40b3038074f 100644 --- a/Master/texmf-dist/source/latex/tools/varioref.dtx +++ b/Master/texmf-dist/source/latex/tools/varioref.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -33,14 +33,15 @@ %% % %\NeedsTeXFormat{LaTeX2e}[1995/05/16] -%\providecommand\DeclareRelease[3]{} -%\providecommand\DeclareCurrentRelease[2]{} % +% +% For any rollback before 2019 load the 2016 version and hope for the best: +%\DeclareRelease{}{1994-06-01}{varioref-2016-02-16.sty} %\DeclareRelease{}{2016-02-16}{varioref-2016-02-16.sty} %\DeclareCurrentRelease{}{2019-10-01} % %\ProvidesPackage{varioref} -% [2022/01/09 v1.6f package for extended references (FMi)] +% [2024/05/23 v1.6g package for extended references (FMi)] % \fi % %% @@ -144,8 +145,8 @@ %\DescribeMacro\vref The implementation of |\vref| below produces only % a |\ref| when reference and |\label| are on the same page. It will % additionally produce one of the strings `on the facing page', `on -% the preceding page', or `on the following page', if label and -% reference differ by one and it will produce both |\ref| and +% the preceding page', or `on the following page' if label and +% reference differ by one; and it will produce both |\ref| and % |\pageref| when the difference is larger. The word `facing' is used % when label and reference both fall onto a double spread. However, % if a special page numbering scheme is used instead of the usual @@ -169,7 +170,7 @@ % comes out as ``\ldots~see the example which shows~\ldots'', which % could be misleading. % -% A space in front of |\vpageref| it will be ignored if +% A space in front of |\vpageref| will be ignored if % the command doesn't produce any text at all. % % But in fact |\vpageref| allows even more control. It has two @@ -210,7 +211,7 @@ % \DescribeMacro\vrefrange % This command is similar to |\vref| but it % takes two mandatory arguments denoting a range to refer to (e.g., a -% sequences of figures or a sequence of equations, etc.). So if +% sequence of figures or a sequence of equations, etc.). So if % |fig:a| is your first figure in the sequence and |fig:c| your last % you can write %\begin{verbatim} @@ -273,8 +274,8 @@ % \DescribeMacro\vpagerefcompare % \NewIn{2019} % For this kind of application the package also provides -% |\vpagerefcompare| as a command that takes four argument: two labels for -% comparison and a \meta{true} and \meta{false} argument. One of them +% |\vpagerefcompare| as a command that takes four arguments: two labels +% for comparison and a \meta{true} and \meta{false} argument. One of them % is executed depending on whether the two labels are on the same page % or on different pages. With its help the above definition could be % shortened to @@ -293,8 +294,9 @@ % Another command for conditional processing is |\vpagerefnearby|. It % takes three arguments: a label and a \meta{true} and \meta{false} % argument. It compares the page reference to the label with the -% current page number and if both are Arabic number and only differ by -% $\pm1$ the \meta{true} argument is executed otherwise the +% current page number; if each of these is a positive integer +% (expressed in Arabic numerals) and they differ by at most +% $\pm1$, the \meta{true} argument is executed, otherwise the % \meta{false} argument. In other words it tells you if a |\vpageref| % to the label would result in a textual reference to the previous, % current or next page.\footnote{There is also a @@ -320,11 +322,11 @@ % versions of the macros which do not add any space before the % generated text (they do nevertheless remove space at the left). % -% However, that too has problems (one is that \pkg{hyperref} +% However, that too has problems: one is that \pkg{hyperref} % \ChangedIn{2019} -% introduced the star forms as a means to generating references -% without hyperlinks (which is clearly the more important -% application). +% introduced the star forms as a means of generating references +% without hyperlinks, which is clearly the more important +% application. % So these days I recommend to always call the package with the option % \option{nospace} which prevents \pkg{varioref} from messing with the % space in front. Of course you are then responsible to always add it @@ -381,7 +383,7 @@ % label and reference fall onto the same page, but prefer reference to % page numbers otherwise then |\thevpagerefnum| can be used. This macro % hold the current page ``number'' when |\vpageref| and friends are -% executed. Thus, by defining, for example +% executed. Thus, by defining, for example, %\begin{verbatim} %\renewcommand\reftextfaceafter {on page~\thevpagerefnum} %\renewcommand\reftextfacebefore{on page~\thevpagerefnum} @@ -436,7 +438,7 @@ %\DescribeMacro\reftextafter %\DescribeMacro\reftextfaceafter Backward references use % |\reftextbefore| if the label is on the preceding page but invisible -% and |\reftextfacebefore| if it is one the facing page (i.e., if the +% and |\reftextfacebefore| if it is on the facing page (i.e., if the % current page number is odd). Similarly |\reftextafter| is used % when the label comes on the next page but one has to turn the page % and |\reftextfaceafter| if it is on the following but facing page. @@ -447,7 +449,7 @@ %\DescribeMacro\reftextfaraway Finally we have |\reftextfaraway| which % is used whenever label and reference differ by more than one or when % they aren't numeric. This macro is a bit different because it takes -% one argument, the symbolic reference string so that one cane make +% one argument, the symbolic reference string, so that one can make % use of |\pageref| in its replacement text. % % @@ -521,7 +523,7 @@ % and \option{nospace}. While the former is the default to allow % \NewIn{2019} % documents written in the last twenty years to continue to work -% correctly, I nowadays, suggest that you always use the package with +% correctly, I nowadays suggest that you always use the package with % the option \option{nospace}. This will stop \pkg{varioref} from % meddling with the spaces preceding commands and thus make the star % forms |\vref*| and |\vpageref*| unnecessary. @@ -536,7 +538,7 @@ % Defining commands like the ones described above poses some % interesting problems. Suppose, for example, that a generated text % like `on the next page' gets broken across pages. If this happens it -% is very difficult to find an acceptable solution and in fact can +% is very difficult to find an acceptable solution and it can, in fact, % even result in a document that will always change from one state to % another (i.e., inserting one string, finding that this is wrong, % inserting another string on the next run which makes the first @@ -699,7 +701,7 @@ % \begin{macro}{\reftextbefore} % \begin{macro}{\reftextcurrent} % \label{reftextbefore} The options do set the macros that -% generate the textual strings. Note, that they do not start with a +% generate the textual strings. Note that they do not start with a % space, the space is already added in the main macro below. % \changes{v1.2a}{1998/08/22}{Added American defaults for % \cs{reftextpagerange} and \cs{reftextlabelrange}} @@ -838,7 +840,7 @@ % the noun (clause); bertentangan is ``opposite'' in the sense of % ``facing''; berikutnya is ``next'' (in this context - actually % next-to-this, literally); berikutnya also translates as ``following -% this'' sebelumnya is ``preceding''; also ``previous'' ``ini'' translates, +% this''; sebelumnya is ``preceding'', also ``previous''; ``ini'' translates, % literally, as ``this'' but is also used in the sense of current page. % \changes{v1.4o}{2005/12/02}{Bahasa Malaysia defaults added.} % \begin{macrocode} @@ -1036,7 +1038,7 @@ \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} -% Default string for dutch have been contributed by Frank Poppe +% Default strings for Dutch have been contributed by Frank Poppe % (\verb=POPPE@SWOV.NL=). % This option currently supports one additional string macro % |\refpagename| so that you can easily change to |bladzijde| @@ -1124,9 +1126,9 @@ \let\vrefrangeformat\vrefrangedefaultformat }} % \end{macrocode} -% The finnish strings were suggested by Matti Rintala +% The Finnish strings were suggested by Matti Rintala % (\verb=bitti@cs.tut.fi=) and Hillevi Gavel -% \verb=Hillevi.Gavel@mdh.se=. +% (\verb=Hillevi.Gavel@mdh.se=). % \changes{v1.0m}{1994/09/23}{Added finnish strings} % \changes{v1.4o}{2005/11/07}{Added a few more finnish strings} % \begin{macrocode} @@ -1200,10 +1202,10 @@ }} % \end{macrocode} % There are no good variants for German (I think and still think but -% this is a matter of taste :-). +% this is a matter of taste :-)). % \changes{v1.0b}{1994/01/31}{Replace in incorrect `def by `let} % The following definitions were recently suggested to me but since -% the original are in for a long time i don't want to change them +% the originals have been there for a long time I don't want to change them % now since that could make a lot of documents change their formatting. % If you fancy them, add a redefinition of the corresponding macro(s) % to the preamble of your document. @@ -1935,7 +1937,7 @@ % \end{macrocode} % But if \texttt{nospace} is in force we simply use the same space % value that was used in the source document (unless that was zero -% or non-existent. +% or non-existent). % \begin{macrocode} \ifdim\@tempskipa=\z@ \else \hskip\@tempskipa @@ -1978,7 +1980,7 @@ % \begin{macrocode} \vrefpagenum\thevpagerefnum{#3}% % \end{macrocode} -% Now after the internal label has served its purpose if would be +% Now after the internal label has served its purpose it would be % nice to free the memory it occupies by using something like % \begin{verbatim} % \global\expandafter\let @@ -2008,7 +2010,7 @@ \fi \else % \end{macrocode} -% If |#2| is empty we do nothing otherwise we insert it followed by +% If |#2| is empty we do nothing, otherwise we insert it followed by % a space. % \begin{macrocode} \def\@tempc{#2}% @@ -2017,7 +2019,7 @@ \fi % \end{macrocode} % Now we check if the page number of the referenced object (stored -% in |\thevpagerefnum| is a single positive number. +% in |\thevpagerefnum|) is a single positive number. % \begin{macrocode} \is@pos@number\thevpagerefnum {% @@ -2032,7 +2034,7 @@ }% % \end{macrocode} % If it is not a positive number we assign the largest possible -% number to |\@tempcnta| and thereby pretending that label and +% number to |\@tempcnta|, thereby pretending that label and % reference are miles away from each other. % \begin{macrocode} {\@tempcnta\maxdimen}% @@ -2049,7 +2051,7 @@ % Thus if the object falls onto an odd page then the reference is % on the facing even page (and so we insert |\reftextfaceafter|), % otherwise the object can not be seen from the reference (and we -% in insert |\reftextafter|). Don't be surprised if we are not +% insert |\reftextafter|). Don't be surprised if we are not % using |\thevpagerefnum| in the check. Since |\@tempcnta| has the same % value it is faster to use the register instead of parsing the % macro contents anew. @@ -2061,7 +2063,7 @@ % used. % Since the value of |\if@twoside| is evaluated before reading in % packages we could do better (saving some tokens) by defining -% the current macro in dependence of this boolean. +% the current macro depending on this boolean. % \begin{macrocode} \if@twoside \reftextfaceafter @@ -2075,11 +2077,11 @@ % If the object is not on the page following the reference we check % if it is on the page before the reference. In \LaTeX{} this % situation is not too common, for example with floats it normally -% does not occur, but of course it isn't impossible if you more +% does not occur, but of course it isn't impossible if you have more % than one reference to the same object, or if you have back % references to sections, theorems, etc. To test this we now % subtract two from the current value of |\@tempcnta| (which was -% set to one higher as the reference page number). Note, that +% set to one higher as the reference page number). Note that % subtraction is also possible if the value was |\maxdimen| --- we % still get something that is much larger than any sensible page % number. @@ -2131,7 +2133,7 @@ \reftextfaraway{#3}}% \fi % \end{macrocode} -% Finally we generate the internal label so that it can be check on +% Finally, we generate the internal label so that it can be checked on % the next run. This means that we compare the position after the % string with the position of the referenced object. There is one % thing to note: to conserve space we locally make |\@currentlabel| @@ -2252,8 +2254,8 @@ % The star form is easy (and just a convenient shortcut), just call % |\ref| followed by |\vpageref| and pass the optional argument to % the latter. We don't support the second optional argument of -% |\vpageref|, it that is needed one has to call both commands -% explicitly +% |\vpageref|, if that is needed one has to call both commands +% explicitly. % \changes{v1.6a}{2019/08/25}{Command added to support hyperref better} % \changes{v1.6e}{2020/07/25}{Changed for Japanese (gh/352)} % \begin{macrocode} @@ -2264,7 +2266,7 @@ % % \begin{macro}{\vrefformat,\vrefdefaultformat} % Japanese needs a different word order in \cs{vref@star} so this -% is separated out o that it can be changed on language level. +% is separated out so that it can be changed at the language level. % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} % \begin{macrocode} \def\vrefdefaultformat#1#2{% @@ -2293,7 +2295,7 @@ \unskip \nobreakspace \fi % \end{macrocode} -% The use of|\nobreakspace| or |~| after the |\unskip| means that +% The use of |\nobreakspace| or |~| after the |\unskip| means that % this command will always produce a normal space while % something like |\nobreak\space| will % react to settings of |\nonfrenchspacing|. @@ -2341,10 +2343,10 @@ % Now we have to check whether or not the whole string was parsed % into that register or some remainder was left over. Since we have % added a |\@nil| token at the very end we can use that to delimit -% the argument of |\is@pos@num@|. Note, that the added space in +% the argument of |\is@pos@num@|. Note that the added space in % |\is@pos@number| \vpageref[above]{isposnumber} gets parsed away % by the counter assignment. If it would be missing, and the full -% string would consist of a number, \TeX{}would try to replace +% string would consist of a number, \TeX{} would try to replace % |\@nil| by its definition to see if it would contain additional % digits and thus we would be in trouble at this point. % \begin{macrocode} @@ -2389,7 +2391,7 @@ % % \begin{macro}{\fullrefformat,\fullrefdefaultformat} % Japanese needs a different word order in \cs{fullref} so this -% is separated out o that it can be changed on language level. +% is separated out so that it can be changed at the language level. % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} % \begin{macrocode} \def\fullrefdefaultformat#1{% @@ -2523,7 +2525,7 @@ % % \begin{macro}{\vrefrangeformat,\vrefrangedefaultformat} % Japanese needs a different word order in \cs{vrefrange} so this -% is separated out o that it can be changed on language level. +% is separated out so that it can be changed at the language level. % \changes{v1.6d}{2020/07/20}{Macro added (gh/352)} % \begin{macrocode} \def\vrefrangedefaultformat#1#2#3{% @@ -2558,7 +2560,7 @@ % % \begin{macro}{\Vrefformat,\Vrefdefaultformat} % Japanese needs a different word order in \cs{Vref} so this -% is separated out o that it can be changed on language level. +% is separated out so that it can be changed at the language level. % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)} % \begin{macrocode} \def\Vrefdefaultformat#1#2{% diff --git a/Master/texmf-dist/source/latex/tools/varioref.ins b/Master/texmf-dist/source/latex/tools/varioref.ins index dcc41d01766..88527a20ba1 100644 --- a/Master/texmf-dist/source/latex/tools/varioref.ins +++ b/Master/texmf-dist/source/latex/tools/varioref.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2023 +%% Copyright (C) 1993-2024 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -45,7 +45,7 @@ The source is maintained by the LaTeX Project team and bug reports for it can be opened at https://latex-project.org/bugs/ (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2023 +Copyright (C) 1993-2024 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/Master/texmf-dist/source/latex/tools/verbatim.dtx b/Master/texmf-dist/source/latex/tools/verbatim.dtx index ebcc010a807..468dead3e83 100644 --- a/Master/texmf-dist/source/latex/tools/verbatim.dtx +++ b/Master/texmf-dist/source/latex/tools/verbatim.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -69,6 +69,8 @@ %\fi % % +% +% \changes{v1.5x}{2024/01/22}{Added TAB marking support to \cs{verbatiminput*}} % \changes{v1.5u}{2020-07-07}{Typo repair and added a missing comment % character} % \changes{v1.5q}{2003/08/22}{Reintroduced \cs{@noligs}, by popular @@ -508,7 +510,7 @@ %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{verbatim} - [2023-11-06 v1.5v LaTeX2e package for verbatim enhancements] + [2024-01-22 v1.5x LaTeX2e package for verbatim enhancements] \@ifundefined{verbatim@@@}{}{\endinput} % \end{macrocode} % @@ -1570,7 +1572,14 @@ % arguments, depending on whether an asterisk follows. % \begin{macrocode} \def\verbatiminput{\begingroup - \@ifstar{\verbatim@input\relax}% +% \end{macrocode} +% +% \changes{v1.5x}{2024/01/22}{Added TAB marking support into the +% starred version (gh/1245)} +% If starred, we mark spaces and TABs, the two +% added pieces are the same as for verbatim*. +% \begin{macrocode} + \@ifstar{\verbatim@input{\@setupverbvisiblespace\@vobeyspaces}}% {\verbatim@input{\frenchspacing\@vobeyspaces}}} % \end{macrocode} % \end{macro} diff --git a/Master/texmf-dist/source/latex/tools/xr.dtx b/Master/texmf-dist/source/latex/tools/xr.dtx index be48f5a01b2..daa0778b363 100644 --- a/Master/texmf-dist/source/latex/tools/xr.dtx +++ b/Master/texmf-dist/source/latex/tools/xr.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -21,14 +21,49 @@ % % \fi % \iffalse -%% File: xr.dtx Copyright (C) 1993-2019 David Carlisle +%% File: xr.dtx Copyright (C) 1993-2024 David Carlisle % %\NeedsTeXFormat{LaTeX2e} +%\DeclareRelease{v5}{2023-07-04}{xr-2023-07-04.sty} +%\DeclareCurrentRelease{}{2024-04-10} %\ProvidesPackage{xr} -% [2023-07-04 v5.06 eXternal References (DPC)] +% [2024-04-10 v6.00 eXternal References (DPC)] % %<*driver> -\documentclass{ltxdoc} +\documentclass{l3doc} +% currently missing in l3doc, copied from array.dtx +\makeatletter +\def\MaintainedBy#1{\gdef\@maintainedby{#1}} +\let\@maintainedby\@empty +\def\MaintainedByLaTeXTeam#1{% +{\gdef\@maintainedby{% +This file is maintained by the \LaTeX{} Project team.\\% +Bug reports can be opened (category \texttt{#1}) at\\% +\url{https://latex-project.org/bugs.html}.}}} +\def\@maketitle{% + \newpage + \null + \vskip 2em% + \begin{center}% + \let \footnote \thanks + {\LARGE \@title \par}% + \vskip 1.5em% + {\large + \lineskip .5em% + \begin{tabular}[t]{c}% + \@author + \end{tabular}\par}% + \vskip 1em% + {\large \@date}% + \ifx\@maintainedby\@empty + \else + \vskip 1em% + \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}% + \fi + \end{center}% + \par + \vskip 1.5em} +\makeatother \usepackage{xr} \GetFileInfo{xr.sty} \begin{document} @@ -50,44 +85,113 @@ % % \changes{v5.00}{1993/07/07} % {First DPC version (by agreement with J-PD). New mechanism -% (\cmd{\read} instead of \cmd\input).} +% (\cs{read} instead of \cs{input}).} % % \changes{v5.01}{1993/07/20}{Fix bug added by DPC, v5.00 did not import -% aux files of \cmd\include'ed files. (Reported by J-PD)} +% aux files of \cs{include}'ed files. (Reported by J-PD)} % % \changes{v5.02}{1994/05/28}{Update for LaTeX2e} % \changes{v5.03}{2018/10/01}{Fix for conditionals in aux file} % \changes{v5.05}{2019/07/20}{include xcite} +% \changes{v6.00}{2024/04/10}{merge with xr-hyper} % % % This package implements a system for eXternal References. -% +% Version 6.00 merges the \pkg{xr} package and the \pkg{xr-hyper} package. +% \pkg{xr-hyper} was developed to support the +% extended label syntax of the \pkg{hyperref} package and to enable active links +% to the external documents. +% In the \LaTeX{} release 2023-06-01 the label syntax of \pkg{hyperref} +% and the \LaTeX{} kernel have been synchronized and there is no longer +% a need for two packages. The package \pkg{xr-hyper} will be +% deprecated. +% +% The previous version before the merge can be accessed with +% \begin{verbatim} +% \usepackage{xr}[=v5] +% \end{verbatim} +% or with a rollback date between 2023-07-04 and 2024-04-09 +% \begin{verbatim} +% \usepackage{xr}[=2024-04-09] +% \end{verbatim} +% +% \section{Usage} +% +% \begin{syntax} +% \cs{externaldocument}\oarg{prefix}\texttt[nocite\texttt]\marg{document}\oarg{url} +% \end{syntax} +% % If one document needs to refer to sections of another, say |aaa.tex|, % then this package may be loaded in the main file, and the command\\ % |\externaldocument{aaa}|\\ % given in the preamble. % -% Then you may use |\ref| and |\pageref| to refer to anything which has +% Then you may use |\ref| and |\pageref| (or |\nameref| if the +% package \pkg{nameref} has been loaded to refer to anything which has % been given a |\label| in either |aaa.tex| or the main document. +% It is also possible to refer to properties stored with \cs{RecordProperties}. % You may declare any number of such external documents. % % If any of the external documents, or the main document, use the same % |\label| then an error will occur as the label will be multiply % defined. To overcome this problem |\externaldocument| has an optional -% argument. If you declare |\externaldocument[A-]{aaa}|, then all +% argument \meta{prefix}. +% If you declare |\externaldocument[A-]{aaa}|, then all % references from |aaa| are prefixed by |A-|. So for instance, if a % section of |aaa| had |\label{intro}|, then this could be referenced % with |\ref{A-intro}|. The prefix need not be |A-|, it can be any % string chosen to ensure that all the labels imported from external -% files are unique. Note however that if your style declares certain -% active characters (|:| in French, |"| in German) then these -% characters can not usually be used in |\label|, and similarly may not -% be used in the optional argument to |\externaldocument|. +% files are unique. Note however that the prefix is expanded and +% so should not contain commands that are not safe in this context. % % As first suggested in Enrico Gregorio's |xcite| package, the current version % also allows |\cite| to reference |\bibitem| in the external document. % For compatibility with |xcite|, |\externalcitedocument| is made available % as an alias for |\externaldocument| +% +% Many packages have variant citation commands (natbib, +% biblatex,....) and the external document may or may not have used +% hyperref. Because of these differences the citation linking may not +% always work, it can be disabled by specifying \texttt{[nocite]} after the +% \meta{prefix}: +% \begin{verbatim} +% \externaldocument[][nocite]{aaa} +% \end{verbatim} +% +% The `document' referred to by the main argument \meta{document} is the file +% \file{document.aux} which must be somewhere on TeX's input path. +% Some packages (eg hyperref) really need to know the location of the +% final document rather than the aux file. By default this is assumed +% to be \file{document.pdf}. A package may redefine the command \cs{XR@ext} to +% change this default extension. However sometimes the final +% document may be in a position unrelated to the aux file, or the +% browser may not be able to find files at an arbitrary point in +% TeX's input path, so the final optional argument \meta{url} allows a full +% URL to the final document to be specified. +% \begin{verbatim} +% \externaldocument{aaa}[https://example.com/this/path/to/aaa.pdf] +% \end{verbatim} +% +% The package stores the url of the external document in the label data. It can +% e.g. be retrieved with the \pkg{refcount} package +% +% \begin{verbatim} +% \usepackage{refcount,xr} +% \externaldocument{aaa} +% ... +% \getrefbykeydefault{intro}{url}{??} %prints aaa.pdf or ?? +% \end{verbatim} +% +% \pkg{xr} supports also the properties introduced in \LaTeX{} 2023-11-01. +% Here the url of the external document is stored in the \texttt{xr-url} property. +% +% \begin{verbatim} +% \usepackage{xr} +% \externaldocument{aaa} %aaa contains \RecordProperties{intro}{page} +% ... +% \RefProperty{intro}{page} %gives page number +% \RefProperty{intro}{xr-url} %gives aaa.pdf +% \end{verbatim} % % \MaybeStop{} % @@ -98,20 +202,74 @@ % \end{macrocode} % % Check for the optional argument. +% \changes{v6.00}{2024-04-10}{Copied over extended definition of xr-hyper} % \begin{macrocode} -\def\externaldocument{\@ifnextchar[\XR@{\XR@[]}} +\def\externaldocument{\@testopt\XR@cite{}} \let\externalcitedocument\externaldocument +\def\XR@cite[#1]{\@testopt{\XR@[#1]}{}} +\def\XR@[#1][#2]#3{\@testopt{\XR@@{#1}{#2}{#3}}{#3.\XR@ext}} +% \end{macrocode} +% +% \subsection{helper definitions} +% \changes{v6.00}{2024-04-10}{new, copied over from xr-hyper} +% To test the second optional argument +% \begin{macrocode} +\def\XR@@nocite{nocite} +% \end{macrocode} +% Needed in the processing +% \begin{macrocode} +\long\def\@gobblefour #1#2#3#4{} +\long\def\@firstoffour #1#2#3#4{#1} +\long\def\@secondoffour#1#2#3#4{#2} +\long\def\@thirdoffour #1#2#3#4{#3} +\long\def\@fourthoffour #1#2#3#4{#4} +% \end{macrocode} +% The url is added as fifth argument. The command used here is +% \cs{XR@addURL}. The command is more complicated as needed +% as it tries to handle also older documents with +% \cs{newlabel}'s with two arguments. +% \begin{macrocode} +\def\XR@addURL#1{\XR@@dURL#1{}{}{}{}\\} +\def\XR@@dURL#1#2#3#4#5\\{% + \unexpanded{{#1}{#2}{#3}{#4}}{\XR@URL}% + }% +% \end{macrocode} +% +% \subsection{Variables} +% \changes{v6.00}{2024-04-10}{new, copied over from xr-hyper} +% Default file extension: +% \begin{macrocode} +\providecommand\XR@ext{pdf} % \end{macrocode} % -% Save the optional prefix. Start processing the first |aux| file. -% \changes{v5.06}{2020-05-10}{Remove leading and trailing sapces from +% Save the optional prefix. Start processing the first |aux| file. +% \changes{v6.00}{2024-04-10}{copied over the new extended internal command from xr-hyper. +% It prepends the directory name.} +% Olivier Michel pointed out that +% if the aux file was not on texinputs you could not always go +% \cs{externaldocument}{/some/path/to/file} +% specifically that worked if file.aux was a `simple' document with +% one aux file, but if \cs{include} had been used, the `sub' aux files +% would not be found by xr in the remote directory. +% This version calls \cs{filename@parse} to get the directory name of the +% remote directory, which is then explicitly prepended to the names of +% any included aux files. +% \changes{v5.06}{2020-05-10}{Remove leading and trailing spaces from % the filename (gh/2223)} % \begin{macrocode} -\def\XR@[#1]#2{{% +\def\XR@@#1#2#3[#4]{{% \makeatletter \def\XR@prefix{#1}% - \set@curr@file{#2}% - \expandafter\XR@next\@curr@file.aux\relax\\}} + \def\XR@nocite{#2}% + \ifx\XR@nocite\XR@@nocite + \let\XR@bibcite\vadjust + \else + \let\XR@bibcite\bibcite + \fi + \def\XR@URL{#4}% + \set@curr@file{#3}% + \filename@parse\@curr@file + \XR@next\@curr@file.aux\relax\\}} % \end{macrocode} % % Process the next |aux| file in the list and remove it from the head of @@ -161,23 +319,40 @@ % \end{macrocode} % % Look at the first token of the line. -% If it is |\newlabel|, do the |\newlabel|. If it is |\@input|, add the -% filename to the list of files to process. Otherwise ignore. +% If it is |\newlabel|, define \cs{r@}\meta{label}, ensure that it has +% five label data argument and add the url as the last one. +% If it is |\@input|, add the +% filename to the list of files to process. +% If it is |\bibcite|, call a |\bibcite|. +% If it is |\new@label@record| add the url and then call it. +% Otherwise ignore. % Go around the loop if not at end of file. Finally process the next % file in the list. % % 2018 update: make sure the arguments are handled outside the |\ifx| test, +% \changes{v6.00}{2024-04-10}{copied over extended definition from xr-hyper} % \begin{macrocode} \long\def\XR@test#1#2#3#4\XR@{% - \let\XR@tempa\@gobbletwo + \let\XR@tempa\@gobblefour \ifx#1\newlabel - \let\XR@tempa\@firstoftwo - \else\ifx#1\bibcite - \let\XR@tempa\@firstoftwo + \let\XR@tempa\@firstoffour + \else\ifx#1\XR@bibcite + \let\XR@tempa\@secondoffour \else\ifx#1\@input - \let\XR@tempa\@secondoftwo - \fi\fi\fi - \XR@tempa{#1{\XR@prefix#2}{#3}}{\edef\XR@list{\XR@list#2\relax}}% + \let\XR@tempa\@thirdoffour + \else\ifx#1\new@label@record + \let\XR@tempa\@fourthoffour + \fi\fi\fi\fi + \XR@tempa + {% + \expandafter\protected@xdef\csname r@\XR@prefix#2\endcsname{\XR@addURL{#3}}% + }% + {\expandafter\bibcite\expandafter{\XR@prefix#2}{#3}}% + {\edef\XR@list{\XR@list\filename@area#2\relax}}% + {% + \edef\next{\noexpand\new@label@record{\XR@prefix#2}{\unexpanded{#3}{xr-url}{\XR@URL}}}% + \next + } \ifeof\@inputcheck\expandafter\XR@aux \else\expandafter\XR@read\fi} % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/tools/xspace.dtx b/Master/texmf-dist/source/latex/tools/xspace.dtx index 807fc9c5df3..be20fc9e522 100644 --- a/Master/texmf-dist/source/latex/tools/xspace.dtx +++ b/Master/texmf-dist/source/latex/tools/xspace.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2023 +% Copyright (C) 1993-2024 % % The LaTeX Project and any individual authors listed elsewhere % in this file. -- cgit v1.2.3