summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r--Master/texmf-dist/source/latex-dev/base/alltt.dtx6
-rw-r--r--Master/texmf-dist/source/latex-dev/base/alltt.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/classes.dtx14
-rw-r--r--Master/texmf-dist/source/latex-dev/base/classes.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/cmextra.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/cmfonts.fdd2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/cmfonts.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/doc.dtx223
-rw-r--r--Master/texmf-dist/source/latex-dev/base/docstrip.dtx16
-rw-r--r--Master/texmf-dist/source/latex-dev/base/docstrip.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ec.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/exscale.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/exscale.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/fix-cm.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/fix-cm.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/fontdef.dtx32
-rw-r--r--Master/texmf-dist/source/latex-dev/base/format.ins14
-rw-r--r--Master/texmf-dist/source/latex-dev/base/graphpap.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/graphpap.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ifthen.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ifthen.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/inputenc.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/inputenc.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latex209.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latex209.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexrelease.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexrelease.ins5
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexsym.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexsym.ins6
-rw-r--r--Master/texmf-dist/source/latex-dev/base/letter.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/letter.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltalloc.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltbibl.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltboxes.dtx9
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltclass.dtx38
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcmd.dtx217
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx24
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcntrl.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcounts.dtx21
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltdefns.dtx22
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lterror.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltexpl.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx26
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfiles.dtx59
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfinal.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfloat.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfntcmd.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx12
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssbas.dtx6
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfsscmp.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssdcl.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfssini.dtx12
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfsstrc.dtx25
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lthooks.dtx403
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lthyphen.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltidxglo.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltkeys.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltlength.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltlists.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltlogos.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltluatex.dtx28
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmarks.dtx656
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmath.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmeta.dtx15
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx14
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx27
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutenc.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltoutput.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpage.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpageno.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpar.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpara.dtx20
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltpictur.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltplain.dtx22
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltproperties.dtx45
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltsect.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltshipout.dtx34
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltsockets.dtx38
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltspace.dtx14
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lttab.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lttagging.dtx775
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lttemplates.dtx2698
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx677
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltthm.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltvers.dtx4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx13
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltxref.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/makeindx.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/makeindx.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/newdc.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/newlfont.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/nfssfont.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/nfssfont.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/olddc.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/oldlfont.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/preload.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/proc.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/proc.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/slides.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/slides.ins8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/slifonts.fdd8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/syntonly.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/syntonly.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/tulm.fdd2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/tulm.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/base/unpack.ins2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/utf8ienc.dtx7
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx48
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-amsmath.dtx90
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-bib.dtx19
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-block.dtx153
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx16
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-float.dtx71
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-graphic.dtx9
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-marginpar.dtx259
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx1560
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathpkg.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathtools.dtx11
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-minipage.dtx4
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-namespace.dtx4
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-1.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-2.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-sec.dtx17
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-table.dtx1311
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx5
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-text.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-title.dtx518
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-hyperref-changes.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-kernel-changes.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins8
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/afterpage.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/afterpage.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/array.dtx465
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/bm.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/bm.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/calc.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/dcolumn.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/delarray.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/enumerate.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/fileerr.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/fontsmpl.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/ftnright.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/hhline.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/indentfirst.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/layout.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/longtable.dtx366
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/longtable.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/multicol.dtx65
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/multicol.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/rawfonts.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/shellesc.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/showkeys.dtx10
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/somedefs.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/tabularx.dtx51
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/tabularx.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/theorem.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/tools.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/trace.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/varioref.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/varioref.ins4
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/verbatim.dtx31
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/xr.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/tools/xspace.dtx2
165 files changed, 9224 insertions, 2490 deletions
diff --git a/Master/texmf-dist/source/latex-dev/base/alltt.dtx b/Master/texmf-dist/source/latex-dev/base/alltt.dtx
index 548b91bcea8..4718c004b40 100644
--- a/Master/texmf-dist/source/latex-dev/base/alltt.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/alltt.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.
%
@@ -40,7 +40,7 @@
%<package>\ProvidesPackage{alltt}
%<driver>\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-dev/base/alltt.ins b/Master/texmf-dist/source/latex-dev/base/alltt.ins
index 3f40ddc0f0d..6d702c1cc71 100644
--- a/Master/texmf-dist/source/latex-dev/base/alltt.ins
+++ b/Master/texmf-dist/source/latex-dev/base/alltt.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/classes.dtx b/Master/texmf-dist/source/latex-dev/base/classes.dtx
index 58690e83759..f7c53f0f719 100644
--- a/Master/texmf-dist/source/latex-dev/base/classes.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/classes.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.
%
@@ -53,7 +53,7 @@
%<*driver>
\ProvidesFile{classes.drv}
%</driver>
- [2023/05/17 v1.4n
+ [2024/02/08 v1.4n
%<article|report|book> 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-dev/base/classes.ins b/Master/texmf-dist/source/latex-dev/base/classes.ins
index 50a51ea666c..7fa35896a42 100644
--- a/Master/texmf-dist/source/latex-dev/base/classes.ins
+++ b/Master/texmf-dist/source/latex-dev/base/classes.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/cmextra.ins b/Master/texmf-dist/source/latex-dev/base/cmextra.ins
index 0fa45183fc9..3f06c1548b7 100644
--- a/Master/texmf-dist/source/latex-dev/base/cmextra.ins
+++ b/Master/texmf-dist/source/latex-dev/base/cmextra.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/cmfonts.fdd b/Master/texmf-dist/source/latex-dev/base/cmfonts.fdd
index af898e47b24..556db5be813 100644
--- a/Master/texmf-dist/source/latex-dev/base/cmfonts.fdd
+++ b/Master/texmf-dist/source/latex-dev/base/cmfonts.fdd
@@ -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-dev/base/cmfonts.ins b/Master/texmf-dist/source/latex-dev/base/cmfonts.ins
index af5ac7e5f86..fb9d08f440c 100644
--- a/Master/texmf-dist/source/latex-dev/base/cmfonts.ins
+++ b/Master/texmf-dist/source/latex-dev/base/cmfonts.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/doc.dtx b/Master/texmf-dist/source/latex-dev/base/doc.dtx
index 75e04cc299c..82eb8dc5b88 100644
--- a/Master/texmf-dist/source/latex-dev/base/doc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/doc.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.
%
@@ -45,7 +45,7 @@
%<+package>
%<+package>\ProvidesPackage{doc}
%<+shortvrb>\ProvidesPackage{shortvrb}
-%<+package|shortvrb> [2022/11/13 v3.0m
+%<+package|shortvrb> [2024/02/08 v3.0o
%<+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-dev/base/docstrip.dtx b/Master/texmf-dist/source/latex-dev/base/docstrip.dtx
index 776d0e68d7d..d5366b3fddf 100644
--- a/Master/texmf-dist/source/latex-dev/base/docstrip.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/docstrip.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 @@
\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@<Terminal>,#1,<Terminal>,\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-dev/base/docstrip.ins b/Master/texmf-dist/source/latex-dev/base/docstrip.ins
index 79d4c429ddd..6ed99c92239 100644
--- a/Master/texmf-dist/source/latex-dev/base/docstrip.ins
+++ b/Master/texmf-dist/source/latex-dev/base/docstrip.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -52,7 +52,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/ec.ins b/Master/texmf-dist/source/latex-dev/base/ec.ins
index 15a7c3848cf..53ea22f9573 100644
--- a/Master/texmf-dist/source/latex-dev/base/ec.ins
+++ b/Master/texmf-dist/source/latex-dev/base/ec.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/exscale.dtx b/Master/texmf-dist/source/latex-dev/base/exscale.dtx
index 89890a41981..1712d18a267 100644
--- a/Master/texmf-dist/source/latex-dev/base/exscale.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/exscale.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-dev/base/exscale.ins b/Master/texmf-dist/source/latex-dev/base/exscale.ins
index ae75460ee53..38c6aea61ee 100644
--- a/Master/texmf-dist/source/latex-dev/base/exscale.ins
+++ b/Master/texmf-dist/source/latex-dev/base/exscale.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/fix-cm.dtx b/Master/texmf-dist/source/latex-dev/base/fix-cm.dtx
index 9e39cd192b9..09af95dad35 100644
--- a/Master/texmf-dist/source/latex-dev/base/fix-cm.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/fix-cm.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-dev/base/fix-cm.ins b/Master/texmf-dist/source/latex-dev/base/fix-cm.ins
index 68c67924123..2023ea229c3 100644
--- a/Master/texmf-dist/source/latex-dev/base/fix-cm.ins
+++ b/Master/texmf-dist/source/latex-dev/base/fix-cm.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/fontdef.dtx b/Master/texmf-dist/source/latex-dev/base/fontdef.dtx
index 5e88e550791..281add29efc 100644
--- a/Master/texmf-dist/source/latex-dev/base/fontdef.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/fontdef.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,7 +27,8 @@
%
% \fi
% \iffalse
-%%% From File: fontdef.dtx
+%%% From File: fontdef.dtx
+%<*!latexrelease>
%<*dtx>
\ProvidesFile{fontdef.dtx}
%</dtx>
@@ -38,17 +39,24 @@
%<+cfgprel>\ProvidesFile{preload.cfg}
%<driver, >\ProvidesFile{fontdef.drv}
% \fi
-% \ProvidesFile{fontdef.dtx}
-%<-latexrelease> [2021/01/15 v3.0i LaTeX Kernel
-% \iftrue (\else
-%<text, >(Text
-%<math, >(Math
-%<+cfgtext>(Uncustomized text
-%<+cfgmath>(Uncustomized math
-%<+cfgprel>(Uncustomized preload
+% \ProvidesFile{fontdef.dtx}
+ [2024/02/09 v3.0i LaTeX Kernel
+% \iffalse
+%<text, > (Text font setup)
+%<math, > (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
+%</dtx>
+%\fi
+]
+% \iffalse
+%</!latexrelease>
+%\fi
%
%\iffalse This is a META comment
%
diff --git a/Master/texmf-dist/source/latex-dev/base/format.ins b/Master/texmf-dist/source/latex-dev/base/format.ins
index ba0965004d1..e20ff094380 100644
--- a/Master/texmf-dist/source/latex-dev/base/format.ins
+++ b/Master/texmf-dist/source/latex-dev/base/format.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -88,7 +88,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 2015-2023
+Copyright (C) 2015-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -123,7 +123,7 @@ extension .ins) which are part of the distribution.
This is a generated file.
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -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-dev/base/graphpap.dtx b/Master/texmf-dist/source/latex-dev/base/graphpap.dtx
index 6b7bc8b8229..7d93512b267 100644
--- a/Master/texmf-dist/source/latex-dev/base/graphpap.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/graphpap.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-dev/base/graphpap.ins b/Master/texmf-dist/source/latex-dev/base/graphpap.ins
index 43ba83aae3c..7898dd2f92e 100644
--- a/Master/texmf-dist/source/latex-dev/base/graphpap.ins
+++ b/Master/texmf-dist/source/latex-dev/base/graphpap.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/ifthen.dtx b/Master/texmf-dist/source/latex-dev/base/ifthen.dtx
index aefc4a76660..ef7d8ab3987 100644
--- a/Master/texmf-dist/source/latex-dev/base/ifthen.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ifthen.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-dev/base/ifthen.ins b/Master/texmf-dist/source/latex-dev/base/ifthen.ins
index 697a4a38b3f..0382d2255e0 100644
--- a/Master/texmf-dist/source/latex-dev/base/ifthen.ins
+++ b/Master/texmf-dist/source/latex-dev/base/ifthen.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/inputenc.dtx b/Master/texmf-dist/source/latex-dev/base/inputenc.dtx
index 02956a8c07b..7ab9713d8e9 100644
--- a/Master/texmf-dist/source/latex-dev/base/inputenc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/inputenc.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
% LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -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 @@
%<cp1252&!ansinew> \ProvidesFile{cp1252.def}
%<cp1250> \ProvidesFile{cp1250.def}
%<cp1257> \ProvidesFile{cp1257.def}
- [2021/02/14 v1.3d Input encoding file]
+ [2024/02/08 v1.3d Input encoding file]
%<cp850>%%
%<cp850>%% If you need a Euro symbol, try cp858 instead.
%<cp850>%%
@@ -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-dev/base/inputenc.ins b/Master/texmf-dist/source/latex-dev/base/inputenc.ins
index 38578270709..2cfe820673c 100644
--- a/Master/texmf-dist/source/latex-dev/base/inputenc.ins
+++ b/Master/texmf-dist/source/latex-dev/base/inputenc.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/latex209.dtx b/Master/texmf-dist/source/latex-dev/base/latex209.dtx
index b84564bb55f..7e4132665ff 100644
--- a/Master/texmf-dist/source/latex-dev/base/latex209.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/latex209.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-dev/base/latex209.ins b/Master/texmf-dist/source/latex-dev/base/latex209.ins
index 0c90fa36ea7..9226268c281 100644
--- a/Master/texmf-dist/source/latex-dev/base/latex209.ins
+++ b/Master/texmf-dist/source/latex-dev/base/latex209.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/latexrelease.dtx b/Master/texmf-dist/source/latex-dev/base/latexrelease.dtx
index 4abde253e16..eeda0f8d557 100644
--- a/Master/texmf-dist/source/latex-dev/base/latexrelease.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/latexrelease.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-dev/base/latexrelease.ins b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
index 93739630e3e..89c3b0fc3a7 100644
--- a/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
+++ b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -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-dev/base/latexsym.dtx b/Master/texmf-dist/source/latex-dev/base/latexsym.dtx
index e4e1559e277..4ad17315899 100644
--- a/Master/texmf-dist/source/latex-dev/base/latexsym.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/latexsym.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-dev/base/latexsym.ins b/Master/texmf-dist/source/latex-dev/base/latexsym.ins
index 12d658bca98..874f12cbf7b 100644
--- a/Master/texmf-dist/source/latex-dev/base/latexsym.ins
+++ b/Master/texmf-dist/source/latex-dev/base/latexsym.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -87,7 +87,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/letter.dtx b/Master/texmf-dist/source/latex-dev/base/letter.dtx
index 3e3c36d3d06..4df9e5ead62 100644
--- a/Master/texmf-dist/source/latex-dev/base/letter.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/letter.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-dev/base/letter.ins b/Master/texmf-dist/source/latex-dev/base/letter.ins
index c522f39e595..72bb25531c2 100644
--- a/Master/texmf-dist/source/latex-dev/base/letter.ins
+++ b/Master/texmf-dist/source/latex-dev/base/letter.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/ltalloc.dtx b/Master/texmf-dist/source/latex-dev/base/ltalloc.dtx
index c3498fb9c70..d9d5ebd3bee 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltalloc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltalloc.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-dev/base/ltbibl.dtx b/Master/texmf-dist/source/latex-dev/base/ltbibl.dtx
index 8e34ca685ae..37d11a97aa8 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltbibl.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltbibl.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-dev/base/ltboxes.dtx b/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx
index d84158c161b..a041312cc59 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltboxes.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltboxes.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,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltboxes.dtx}
- [2023/10/26 v1.4e LaTeX Kernel (Box Commands)]
+ [2024/02/08 v1.4e 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}
%</2ekernel>
diff --git a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx b/Master/texmf-dist/source/latex-dev/base/ltclass.dtx
index bb521485085..c6c0495fcae 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltclass.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltclass.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,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltclass.dtx}
- [2023/04/14 v1.5h LaTeX Kernel (Class & Package Interface)]
+ [2024/02/14 v1.5i 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
@@ -1950,12 +1950,34 @@
% \end{macro}
%
% \begin{macro}{\@fileswithoptions}
+% \changes{v1.5i}{2024/01/30}{Test group level}
% The common part of |\documentclass| and |\usepackage|.
% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2024/06/01}%
+%<latexrelease> {\@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[]}}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@fileswithoptions}{Check Group}%
+%<latexrelease>\def\@fileswithoptions#1{%
+%<latexrelease> \@ifnextchar[%]
+%<latexrelease> {\@fileswith@ptions#1}%
+%<latexrelease> {\@fileswith@ptions#1[]}}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+% \begin{macrocode}
\@onlypreamble\@fileswithoptions
% \end{macrocode}
%
@@ -2624,8 +2646,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 +3019,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 +3607,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 +3717,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-dev/base/ltcmd.dtx b/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
index dcb85a1ae8d..1733af54163 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
@@ -2,7 +2,7 @@
%
% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX Project
-% Copyright (C) 2009-2023
+% Copyright (C) 2009-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -34,8 +34,8 @@
%%% From File: ltcmd.dtx
%
% \begin{macrocode}
-\def\ltcmdversion{v1.2a}
-\def\ltcmddate{2023-08-19}
+\def\ltcmdversion{v1.2c}
+\def\ltcmddate{2024-02-08}
% \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 @@
%<latexrelease>\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}
%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_copy:NN (part 2)}%
%<latexrelease> {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
@@ -4376,13 +4524,14 @@
% \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}
% \begin{macro}{\@@_cmd_if_xparse_aux:N}
%
% To determine whether the command is an \pkg{xparse} command check
@@ -4390,13 +4539,14 @@
% 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
{
@@ -4406,20 +4556,21 @@
{
{ \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 +4662,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 +4671,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 +4763,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-dev/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
index 6f885a2c6ce..bb071e629c0 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
-%% File: ltcmdhooks.dtx
-%% Copyright (C) 2020-2023
+%%% From File: ltcmdhooks.dtx
+%% Copyright (C) 2020-2024
%% Frank Mittelbach, Phelype Oleinik, The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
@@ -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/02/11 v1.0i 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}
%
@@ -643,7 +647,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.
diff --git a/Master/texmf-dist/source/latex-dev/base/ltcntrl.dtx b/Master/texmf-dist/source/latex-dev/base/ltcntrl.dtx
index 52dcdbf9837..fad5bf479ec 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcntrl.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcntrl.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-dev/base/ltcounts.dtx b/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx
index 69025fa479f..006486d23b2 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcounts.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcounts.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,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-dev/base/ltdefns.dtx b/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx
index 209c4e0fbab..4d8368e2c04 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltdefns.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltdefns.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.
%
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltdefns.dtx}
- [2022/11/24 v1.5s LaTeX Kernel (definition commands)]
+ [2024/02/08 v1.5s LaTeX Kernel (definition commands)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltdefns.dtx}
@@ -530,9 +530,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 +597,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 +708,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 +891,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}
@@ -2296,7 +2300,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-dev/base/ltdirchk.dtx b/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx
index 6e029297544..d06f68a706d 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltdirchk.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltdirchk.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.
%
@@ -36,8 +36,10 @@
%</unstripped>
%<*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}
@@ -1000,8 +1002,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-dev/base/lterror.dtx b/Master/texmf-dist/source/latex-dev/base/lterror.dtx
index 77672168ce1..99bdc79e4f8 100644
--- a/Master/texmf-dist/source/latex-dev/base/lterror.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lterror.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-dev/base/ltexpl.dtx b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx
index 4e5eba550b0..4aaf799e325 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltexpl.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2019-2023
+% Copyright (C) 2019-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
index ae183bfeb47..831d633eefe 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2020-2023
+% Copyright (C) 2020-2024
% Frank Mittelbach, Phelype Oleinik and The LaTeX Project
%
% This file is part of the LaTeX base system.
@@ -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/02/11}
+\def\ltfilehookversion{v1.0o}
+%\iffalse
+%</driver,structuredlog>
%<*driver>
-
+%\fi
+\expanded{\noexpand\ProvidesFile{ltfilehook.dtx}
+[\ltfilehookdate\space \ltfilehookversion\space LaTeX Kernel (hooks)]}
+% \iffalse
+%
\documentclass{l3doc}
-
\providecommand\InternalDetectionOff{}
\providecommand\InternalDetectionOn{}
@@ -407,7 +413,7 @@
%
% \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
@@ -1328,7 +1334,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-dev/base/ltfiles.dtx b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx
index f079c2cf5b1..2e2a8884a01 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfiles.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.
%
@@ -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-dev/base/ltfinal.dtx b/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx
index 2652f6ce44e..648e3e1b8bd 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfinal.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfinal.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,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-dev/base/ltfloat.dtx b/Master/texmf-dist/source/latex-dev/base/ltfloat.dtx
index 72478245483..a07e5e81dae 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfloat.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfloat.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-dev/base/ltfntcmd.dtx b/Master/texmf-dist/source/latex-dev/base/ltfntcmd.dtx
index bb6dbfe75ca..097b8f692e4 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfntcmd.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfntcmd.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.
%
@@ -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-dev/base/ltfssaxes.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx
index a0746bd08c0..8b5014a4cc1 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfssaxes.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2019-2023
+% Copyright (C) 2019-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -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-dev/base/ltfssbas.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssbas.dtx
index fa82bd73bb6..df02a5749a7 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfssbas.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfssbas.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.
%
@@ -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-dev/base/ltfsscmp.dtx b/Master/texmf-dist/source/latex-dev/base/ltfsscmp.dtx
index 7bdfe2fd3ee..57c94ea6889 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfsscmp.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfsscmp.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-dev/base/ltfssdcl.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssdcl.dtx
index c3a743d249d..32f9eedf19d 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfssdcl.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfssdcl.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-dev/base/ltfssini.dtx b/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx
index 7b43f0228b7..255abe03f3a 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfssini.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfssini.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.
%
@@ -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-dev/base/ltfsstrc.dtx b/Master/texmf-dist/source/latex-dev/base/ltfsstrc.dtx
index be0e6c68cf6..4f0e43021aa 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfsstrc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfsstrc.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.
%
@@ -37,7 +37,7 @@
%<package> [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-dev/base/lthooks.dtx b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
index 20d48730c48..ea337d306d8 100644
--- a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2020-2023
+% Copyright (C) 2020-2024
% Frank Mittelbach, Phelype Oleinik, The LaTeX Project
%
% This file is part of the LaTeX base system.
@@ -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/02/11 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}
@@ -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}
@@ -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 @@
%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_gput_code:nnn}
%<latexrelease> {Providing~hooks}
%<latexrelease>\cs_gset_protected:Npn \hook_gput_code:nnn #1 #2
-%<latexrelease> { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} }
+%<latexrelease> { \@@_normalize_hook_args:Nnn
+%<latexrelease> \@@_gput_code:nnn {#1} {#2} }
%<latexrelease>\cs_gset_protected:Npn \@@_gput_code:nnn #1 #2 #3
%<latexrelease> {
%<latexrelease> \@@_if_execute_immediately:nTF {#1}
@@ -3736,7 +3762,8 @@
%<latexrelease> {
%<latexrelease> \@@_if_disabled:nTF {#1}
%<latexrelease> { \msg_error:nnn { hooks } { hook-disabled } {#1} }
-%<latexrelease> { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+%<latexrelease> { \@@_try_declaring_generic_hook:nnn
+%<latexrelease> {#1} {#2} {#3} }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> }
@@ -3748,7 +3775,8 @@
%<latexrelease> \on@line\space <-~ \tl_to_str:n{#3}} }
%<latexrelease> \str_if_eq:nnTF {#2} { top-level }
%<latexrelease> {
-%<latexrelease> \str_if_eq:eeTF { top-level } { \@@_currname_or_default: }
+%<latexrelease> \str_if_eq:eeTF { top-level }
+%<latexrelease> { \@@_currname_or_default: }
%<latexrelease> {
%<latexrelease> \@@_init_structure:n {#1}
%<latexrelease> \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3}
@@ -3756,7 +3784,8 @@
%<latexrelease> { \msg_error:nnn { hooks } { misused-top-level } {#1} }
%<latexrelease> }
%<latexrelease> {
-%<latexrelease> \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl
+%<latexrelease> \prop_get:cnNTF
+%<latexrelease> { g_@@_#1_code_prop } {#2} \l_@@_return_tl
%<latexrelease> {
%<latexrelease> \prop_gput:cno { g_@@_#1_code_prop } {#2}
%<latexrelease> { \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}
-%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:nnn}
+%<latexrelease>\IncludeInRelease{2023/06/01}
+%<latexrelease> {\@@_try_declaring_generic_hook:nnn}
%<latexrelease> {Hooks~with~args}
\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1
{
@@ -3857,31 +3887,38 @@
{#1}
}
%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn}
+%<latexrelease>\IncludeInRelease{2021/11/15}
+%<latexrelease> {\@@_try_declaring_generic_hook:nnn}
%<latexrelease> {Standardise~generic~hook~names}
%<latexrelease>\cs_gset_protected:Npn \@@_try_declaring_generic_hook:nnn #1
%<latexrelease> {
-%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+%<latexrelease> {#1}
%<latexrelease> \hook_gput_code:nnn
%<latexrelease> \@@_gput_undeclared_hook:nnn
%<latexrelease> {#1}
%<latexrelease> }
-%<latexrelease>\cs_gset_protected:Npn \@@_try_declaring_generic_next_hook:nn #1
+%<latexrelease>\cs_gset_protected:Npn
+%<latexrelease> \@@_try_declaring_generic_next_hook:nn #1
%<latexrelease> {
-%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+%<latexrelease> {#1}
%<latexrelease> \hook_gput_next_code:nn
%<latexrelease> \@@_gput_next_do:nn
%<latexrelease> {#1}
%<latexrelease> }
%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:nnn}
+%<latexrelease>\IncludeInRelease{2020/10/01}
+%<latexrelease> {\@@_try_declaring_generic_hook:nnn}
%<latexrelease> {Standardise~generic~hook~names}
-%<latexrelease>\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1
+%<latexrelease>\cs_new_protected:Npn
+%<latexrelease> \@@_try_declaring_generic_hook:nnn #1
%<latexrelease> {
%<latexrelease> \@@_try_declaring_generic_hook:nNNnn {#1}
%<latexrelease> \hook_gput_code:nnn \@@_gput_undeclared_hook:nnn
%<latexrelease> }
-%<latexrelease>\cs_new_protected:Npn \@@_try_declaring_generic_next_hook:nn #1
+%<latexrelease>\cs_new_protected:Npn
+%<latexrelease> \@@_try_declaring_generic_next_hook:nn #1
%<latexrelease> {
%<latexrelease> \@@_try_declaring_generic_hook:nNNnn {#1}
%<latexrelease> \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}
%<latexrelease>\cs_new_protected:Npn \@@_try_declaring_generic_hook:nNNnn #1
%<latexrelease> {
-%<latexrelease> \@@_if_file_hook:wTF #1 / \s_@@_mark
+%<latexrelease> \@@_if_file_hook:wTF #1 / / \s_@@_mark
%<latexrelease> {
-%<latexrelease> \exp_args:Ne \@@_try_declaring_generic_hook_split:nNNnn
+%<latexrelease> \exp_args:Ne
+%<latexrelease> \@@_try_declaring_generic_hook_split:nNNnn
%<latexrelease> { \exp_args:Ne \@@_file_hook_normalize:n {#1} }
%<latexrelease> }
%<latexrelease> { \@@_try_declaring_generic_hook_split:nNNnn {#1} }
@@ -3917,9 +3957,11 @@
% \end{macrocode}
%
% \begin{macrocode}
-%<latexrelease>\cs_new_protected:Npn \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3
+%<latexrelease>\cs_new_protected:Npn
+%<latexrelease> \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3
%<latexrelease> {
-%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+%<latexrelease> {#1}
%<latexrelease> { #2 }
%<latexrelease> { #3 } {#1}
%<latexrelease> }
@@ -3931,9 +3973,11 @@
% \changes{v1.1a}{2023/04/06}
% {Changes to add hook arguments (hook-args).}
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:wn}
+%<latexrelease>\IncludeInRelease{2023/06/01}
+%<latexrelease> {\@@_try_declaring_generic_hook:wn}
%<latexrelease> {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}
-%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn}
+%<latexrelease>\IncludeInRelease{2021/11/15}
+%<latexrelease> {\@@_try_declaring_generic_hook:wn}
%<latexrelease> {Standardise~generic~hook~names}
-%<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn
+%<latexrelease>\prg_new_protected_conditional:Npnn
+%<latexrelease> \@@_try_declaring_generic_hook:wn
%<latexrelease> #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
%<latexrelease> {
%<latexrelease> \@@_if_generic:nTF {#5}
@@ -4083,9 +4129,11 @@
% \end{macrocode}
%
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2021/06/01}{\@@_try_declaring_generic_hook:wn}
+%<latexrelease>\IncludeInRelease{2021/06/01}
+%<latexrelease> {\@@_try_declaring_generic_hook:wn}
%<latexrelease> {Support~cmd~hooks}
-%<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn
+%<latexrelease>\prg_new_protected_conditional:Npnn
+%<latexrelease> \@@_try_declaring_generic_hook:wn
%<latexrelease> #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
%<latexrelease> {
%<latexrelease> \tl_if_empty:nTF {#2}
@@ -4099,10 +4147,12 @@
%<latexrelease> { \@@_try_put_cmd_hook:n {#5} }
%<latexrelease> \@@_make_usable:n {#5}
%<latexrelease> }
-%<latexrelease> \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2}
+%<latexrelease> \prop_if_in:NnTF
+%<latexrelease> \c_@@_generics_reversed_ii_prop {#2}
%<latexrelease> { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
%<latexrelease> {
-%<latexrelease> \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3}
+%<latexrelease> \prop_if_in:NnT
+%<latexrelease> \c_@@_generics_reversed_iii_prop {#3}
%<latexrelease> { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
%<latexrelease> }
%<latexrelease> \prg_return_true:
@@ -4114,9 +4164,11 @@
% \end{macrocode}
%
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn}
+%<latexrelease>\IncludeInRelease{2020/10/01}
+%<latexrelease> {\@@_try_declaring_generic_hook:wn}
%<latexrelease> {Support~cmd~hooks}
-%<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn
+%<latexrelease>\prg_new_protected_conditional:Npnn
+%<latexrelease> \@@_try_declaring_generic_hook:wn
%<latexrelease> #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
%<latexrelease> {
%<latexrelease> \tl_if_empty:nTF {#2}
@@ -4125,10 +4177,12 @@
%<latexrelease> \prop_if_in:NnTF \c_@@_generics_prop {#1}
%<latexrelease> {
%<latexrelease> \@@_if_declared:nF {#5} { \hook_new:n {#5} }
-%<latexrelease> \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2}
+%<latexrelease> \prop_if_in:NnTF
+%<latexrelease> \c_@@_generics_reversed_ii_prop {#2}
%<latexrelease> { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
%<latexrelease> {
-%<latexrelease> \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3}
+%<latexrelease> \prop_if_in:NnT
+%<latexrelease> \c_@@_generics_reversed_iii_prop {#3}
%<latexrelease> { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
%<latexrelease> }
%<latexrelease> \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}
-%<latexrelease>\cs_new:Npn \@@_strip_double_slash:w #1/#2/#3 // #4 \s_@@_mark
+%<latexrelease>\cs_new:Npn \@@_strip_double_slash:w #1/#2/#3//#4\s_@@_mark
%<latexrelease> {
%<latexrelease> \tl_if_empty:nTF {#4}
%<latexrelease> { #1/#2/#3 }
-%<latexrelease> { \@@_strip_double_slash:w #1/#2/#3 / #4 \s_@@_mark }
+%<latexrelease> { \@@_strip_double_slash:w #1/#2/#3 /#4\s_@@_mark }
%<latexrelease> }
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -4287,9 +4341,12 @@
% \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop}
%<latexrelease> {Standardise~generic~hook~names}
-%<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_reversed_ii_prop {after=,end=}
-%<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_reversed_iii_prop {after=}
-%<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_file_prop {before=,after=}
+%<latexrelease>\prop_const_from_keyval:Nn
+%<latexrelease> \c_@@_generics_reversed_ii_prop {after=,end=}
+%<latexrelease>\prop_const_from_keyval:Nn
+%<latexrelease> \c_@@_generics_reversed_iii_prop {after=}
+%<latexrelease>\prop_const_from_keyval:Nn
+%<latexrelease> \c_@@_generics_file_prop {before=,after=}
%<latexrelease>\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 @@
%<latexrelease> \str_if_eq:nnTF {#2} { top-level }
%<latexrelease> { \@@_tl_gclear:c { @@_toplevel~#1 } }
%<latexrelease> {
-%<latexrelease> \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl
-%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
+%<latexrelease> \prop_gpop:cnNF { g_@@_#1_code_prop }
+%<latexrelease> {#2} \l_@@_return_tl
+%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove }
+%<latexrelease> {#1} {#2} }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> \@@_if_usable:nT {#1}
@@ -4423,9 +4484,11 @@
%<latexrelease> \@@_if_deprecated_generic:nTF {#1}
%<latexrelease> {
%<latexrelease> \@@_deprecated_generic_warn:n {#1}
-%<latexrelease> \@@_do_deprecated_generic:Nn \@@_gremove_code:nn {#1} {#2}
+%<latexrelease> \@@_do_deprecated_generic:Nn
+%<latexrelease> \@@_gremove_code:nn {#1} {#2}
%<latexrelease> }
-%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
+%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove }
+%<latexrelease> {#1} {#2} }
%<latexrelease> }
%<latexrelease> }
%<latexrelease>\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 @@
%<latexrelease> \@@_if_deprecated_generic:nT {#1}
%<latexrelease> {
%<latexrelease> \@@_deprecated_generic_warn:n {#1}
-%<latexrelease> \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn {#1}
-%<latexrelease> {#2} {#3} {#4}
+%<latexrelease> \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn
+%<latexrelease> {#1} {#2} {#3} {#4}
%<latexrelease> \exp_after:wN \use_none:nnnnnnnnn \use_none:n
%<latexrelease> }
%<latexrelease> \@@_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 @@
%<latexrelease> {Hooks~with~args}
%<latexrelease>\cs_gset_protected:Npn \@@_initialize_all:
%<latexrelease> {
-%<latexrelease> \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n
+%<latexrelease> \cs_gset_eq:NN \@@_update_hook_code:n
+%<latexrelease> \@@_initialize_hook_code:n
%<latexrelease> \@@_debug:n { \prop_gclear:N \g_@@_used_prop }
%<latexrelease> \seq_map_inline:Nn \g_@@_all_seq
%<latexrelease> { \@@_update_hook_code:n {##1} }
@@ -5291,7 +5364,8 @@
%<latexrelease> \prop_map_inline:Nn \g_@@_used_prop
%<latexrelease> {
%<latexrelease> \iow_term:x
-%<latexrelease> { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ }
+%<latexrelease> { ^^J ~ ##1 ~ -> ~
+%<latexrelease> \cs_replacement_spec:c { @@~##1 } ~ }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> \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 @@
%<latexrelease>\cs_gset_protected:Npn \@@_initialize_hook_code:n #1
%<latexrelease> {
%<latexrelease> \@@_debug:n
-%<latexrelease> { \iow_term:x { ^^J Update~code~for~hook~'#1' \on@line :^^J } }
+%<latexrelease> { \iow_term:x { ^^J Update~code~for~hook~'#1'
+%<latexrelease> \on@line :^^J } }
%<latexrelease> \@@_include_legacy_code_chunk:n {#1}
%<latexrelease> \@@_if_usable:nT {#1}
%<latexrelease> {
@@ -5414,15 +5491,21 @@
%<latexrelease> }
%<latexrelease> {
%<latexrelease> \@@_if_reversed:nTF {#1}
-%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_left:Nn
-%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV }
-%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_right:Nn
-%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV }
-%<latexrelease> \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop }
+%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn
+%<latexrelease> \@@_tl_gput_left:Nn
+%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV
+%<latexrelease> \clist_gput_left:NV }
+%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn
+%<latexrelease> \@@_tl_gput_right:Nn
+%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV
+%<latexrelease> \clist_gput_right:NV }
+%<latexrelease> \prop_set_eq:Nc \l_@@_work_prop
+%<latexrelease> { g_@@_#1_code_prop }
%<latexrelease> \@@_initialize_single:ccn
%<latexrelease> { @@~#1 } { g_@@_#1_labels_clist } {#1}
%<latexrelease> \@@_debug:n
-%<latexrelease> { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1} { } }
+%<latexrelease> { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop
+%<latexrelease> {#1} { } }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> }
@@ -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 @@
%<latexrelease> {#3}
%<latexrelease> }
%<latexrelease> }
-%<latexrelease> \@@_debug:n { \@@_debug_label_data:N \l_@@_work_prop }
+%<latexrelease> \@@_debug:n
+%<latexrelease> { \@@_debug_label_data:N \l_@@_work_prop }
%<latexrelease> \tl_set:Nn \l_@@_rear_tl { 0 }
%<latexrelease> \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 }
%<latexrelease> \seq_map_inline:Nn \l_@@_labels_seq
%<latexrelease> {
-%<latexrelease> \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0
-%<latexrelease> {
-%<latexrelease> \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } }{##1}
-%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1}
-%<latexrelease> }
+%<latexrelease> \int_compare:nNnT
+%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0
+%<latexrelease> {
+%<latexrelease> \tl_set:cn { \@@_tl_csname:n
+%<latexrelease> { \l_@@_rear_tl } } {##1}
+%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1}
+%<latexrelease> }
%<latexrelease> }
%<latexrelease> \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { 0 } }
%<latexrelease> \@@_tl_gclear:N #1
%<latexrelease> \clist_gclear:N #2
-%<latexrelease> \bool_while_do:nn { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } }
+%<latexrelease> \bool_while_do:nn
+%<latexrelease> { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } }
%<latexrelease> {
%<latexrelease> \int_decr:N \l_@@_labels_int
-%<latexrelease> \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl
+%<latexrelease> \prop_get:NVN \l_@@_work_prop
+%<latexrelease> \l_@@_front_tl \l_@@_return_tl
%<latexrelease> \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl
%<latexrelease> \@@_clist_gput:NV #2 \l_@@_front_tl
-%<latexrelease> \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} }
-%<latexrelease> \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } }
+%<latexrelease> \@@_debug:n{ \iow_term:x
+%<latexrelease> {Handled~ code~ for~ \l_@@_front_tl} }
+%<latexrelease> \seq_map_inline:cn
+%<latexrelease> { \@@_seq_csname:n { \l_@@_front_tl } }
%<latexrelease> {
%<latexrelease> \tl_set:cx { \@@_tl_csname:n {##1} }
-%<latexrelease> { \int_eval:n
-%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 }
-%<latexrelease> }
+%<latexrelease> { \int_eval:n
+%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 }
+%<latexrelease> }
%<latexrelease> \int_compare:nNnT
-%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0
-%<latexrelease> {
-%<latexrelease> \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1}
-%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1}
-%<latexrelease> }
+%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0
+%<latexrelease> {
+%<latexrelease> \tl_set:cn { \@@_tl_csname:n
+%<latexrelease> { \l_@@_rear_tl } } {##1}
+%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1}
+%<latexrelease> }
%<latexrelease> }
%<latexrelease> \tl_set_eq:Nc \l_@@_front_tl
-%<latexrelease> { \@@_tl_csname:n { \l_@@_front_tl } }
+%<latexrelease> { \@@_tl_csname:n { \l_@@_front_tl } }
%<latexrelease> }
%<latexrelease> \int_compare:nNnF \l_@@_labels_int = 0
%<latexrelease> {
@@ -5747,7 +5839,8 @@
%<latexrelease> \@@_debug_label_data:N \l_@@_work_prop
%<latexrelease> \iow_term:x{====================}
%<latexrelease> }
-%<latexrelease> \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: }
+%<latexrelease> \exp_args:NNo \@@_tl_gput:Nn #1
+%<latexrelease> { \cs:w @@_toplevel~#3 \cs_end: }
%<latexrelease> \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: }
%<latexrelease> }
%<latexrelease>\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}
%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_log:nN}
%<latexrelease> {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 @@
%<latexrelease> }
%<latexrelease> \@@_preamble_hook:n {#1}
%<latexrelease> \@@_log_cmd:x
-%<latexrelease> { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': }
+%<latexrelease> { ^^J ->~The~ \@@_if_generic:nT
+%<latexrelease> {#1} { generic~ } hook~'#1': }
%<latexrelease> \@@_if_usable:nF {#1}
%<latexrelease> { \@@_log_line:x { The~hook~is~not~declared. } }
%<latexrelease> \@@_if_disabled:nT {#1}
@@ -6177,26 +6273,30 @@
%<latexrelease> { \@@_log_line_indent:x { --- } }
%<latexrelease> {
%<latexrelease> \prop_map_inline:cn { g_@@_#1_code_prop }
-%<latexrelease> { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } }
+%<latexrelease> { \@@_log_line_indent:x
+%<latexrelease> { ##1~->~\tl_to_str:n {##2} } }
%<latexrelease> }
%<latexrelease> \@@_log_line:x
%<latexrelease> {
%<latexrelease> Document-level~(top-level)~code
%<latexrelease> \@@_if_usable:nT {#1}
-%<latexrelease> { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } :
+%<latexrelease> { ~(executed~
+%<latexrelease> \@@_if_reversed:nTF {#1} {first} {last} ) } :
%<latexrelease> }
%<latexrelease> \@@_log_line_indent:x
%<latexrelease> {
%<latexrelease> \tl_if_empty:cTF { @@_toplevel~#1 }
%<latexrelease> { --- }
-%<latexrelease> { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } }
+%<latexrelease> { -> ~ \exp_args:Nv \tl_to_str:n
+%<latexrelease> { @@_toplevel~#1 } }
%<latexrelease> }
%<latexrelease> \@@_log_line:x { Extra~code~for~next~invocation: }
%<latexrelease> \@@_log_line_indent:x
%<latexrelease> {
%<latexrelease> \tl_if_empty:cTF { @@_next~#1 }
%<latexrelease> { --- }
-%<latexrelease> { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } }
+%<latexrelease> { ->~ \exp_args:Nv \@@_log_next_code:n
+%<latexrelease> { @@_next~#1 } }
%<latexrelease> }
%<latexrelease> \@@_log_line:x { Rules: }
%<latexrelease> \bool_set_true:N \l_@@_tmpa_bool
@@ -6220,7 +6320,8 @@
%<latexrelease> {
%<latexrelease> Execution~order
%<latexrelease> \bool_if:NTF \l_@@_tmpa_bool
-%<latexrelease> { \@@_if_reversed:nT {#1} { ~(after~reversal) } }
+%<latexrelease> { \@@_if_reversed:nT
+%<latexrelease> {#1}{ ~(after~reversal) } }
%<latexrelease> { ~(after~
%<latexrelease> \@@_if_reversed:nT {#1} { reversal~and~ }
%<latexrelease> applying~rules)
@@ -6231,16 +6332,19 @@
%<latexrelease> \@spaces
%<latexrelease> \clist_if_empty:cTF { g_@@_#1_labels_clist }
%<latexrelease> { --- }
-%<latexrelease> { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } }
+%<latexrelease> { \clist_use:cn
+%<latexrelease> { g_@@_#1_labels_clist } { ,~ } }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> {
%<latexrelease> \@@_log_line:x { Execution~order: }
%<latexrelease> #2
%<latexrelease> {
-%<latexrelease> \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1}
+%<latexrelease> \@spaces Not~set~because~the~hook~
+%<latexrelease> \@@_if_usable:nTF {#1}
%<latexrelease> { code~pool~is~empty }
-%<latexrelease> { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} }
+%<latexrelease> { is~\@@_if_disabled:nTF
+%<latexrelease> {#1} {disabled} {undeclared} }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> }
@@ -6388,7 +6492,8 @@
%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_gput_next_code:nn}
%<latexrelease> {Hooks~with~args}
%<latexrelease>\cs_gset_protected:Npn \hook_gput_next_code:nn #1
-%<latexrelease> { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} }
+%<latexrelease> { \@@_normalize_hook_args:Nn
+%<latexrelease> \@@_gput_next_code:nn {#1} }
%<latexrelease>\cs_gset_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 { }
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -6580,7 +6685,8 @@
%<latexrelease> \fi:
%<latexrelease> \cs:w @@~#1 \@@_use_end:
%<latexrelease> }
-%<latexrelease>\cs_new:Npn \@@_use_undefined:w #1 #2 @@~#3 \@@_use_end:
+%<latexrelease>\cs_new:Npn \@@_use_undefined:w
+%<latexrelease> #1 #2 @@~#3 \@@_use_end:
%<latexrelease> {
%<latexrelease> #1 % fi
%<latexrelease> \@@_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}
%<latexrelease>\cs_new_protected:Npn \@@_try_file_hook:n #1
%<latexrelease> {
-%<latexrelease> \@@_if_file_hook:wTF #1 / \s_@@_mark
+%<latexrelease> \@@_if_file_hook:wTF #1 / / \s_@@_mark
%<latexrelease> {
%<latexrelease> \exp_args:Ne \@@_if_usable_use:n
%<latexrelease> { \exp_args:Ne \@@_file_hook_normalize:n {#1} }
%<latexrelease> }
-%<latexrelease> { \@@_if_usable_use:n {#1} } % file/ generic hook (e.g. file/before)
+%<latexrelease> { \@@_if_usable_use:n {#1} }
+%<latexrelease> % file/ generic hook (e.g. file/before)
%<latexrelease> }
% \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} }
}
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -6743,7 +6854,8 @@
%<latexrelease>\cs_gset_protected:Npn \hook_use_once:n #1
%<latexrelease> {
%<latexrelease> \@@_if_execute_immediately:nF {#1}
-%<latexrelease> { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } }
+%<latexrelease> { \@@_normalize_hook_args:Nn \@@_use_once:n
+%<latexrelease> { \use:n {#1} } }
%<latexrelease> }
%<latexrelease>\cs_gset:Npn \hook_use_once:nnw #1 #2
%<latexrelease> { \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 @@
%<latexrelease> {Hooks~with~args}
%<latexrelease>\cs_new_protected:Npn \NewHookWithArguments #1 #2 { }
%<latexrelease>\cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { }
-%<latexrelease>\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3 { }
+%<latexrelease>\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3{}
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
% \end{macro}
@@ -7835,7 +7949,8 @@
%<latexrelease> \exp_args:No \exp_not:o
%<latexrelease> {
%<latexrelease> \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end:
-%<latexrelease> { \@@_braced_cs_parameter:n { @@#1~#2 } }
+%<latexrelease> { \@@_braced_cs_parameter:n
+%<latexrelease> { @@#1~#2 } }
%<latexrelease> }
%<latexrelease> }
%<latexrelease> }
diff --git a/Master/texmf-dist/source/latex-dev/base/lthyphen.dtx b/Master/texmf-dist/source/latex-dev/base/lthyphen.dtx
index 88d30c9ccac..ae1e2182aa3 100644
--- a/Master/texmf-dist/source/latex-dev/base/lthyphen.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lthyphen.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-dev/base/ltidxglo.dtx b/Master/texmf-dist/source/latex-dev/base/ltidxglo.dtx
index a2dc6b873ee..25b8dd12e94 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltidxglo.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltidxglo.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-dev/base/ltkeys.dtx b/Master/texmf-dist/source/latex-dev/base/ltkeys.dtx
index 80c36d5cd9a..da8340ea9d0 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltkeys.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltkeys.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2021-2023
+% Copyright (C) 2021-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltkeys.dtx}
- [2022/10/22 v1.0l LaTeX Kernel (Keyval options)]
+ [2024/01/13 v1.0m LaTeX Kernel (Keyval options)]
% \iffalse
\documentclass{l3doc}
\GetFileInfo{ltkeys.dtx}
@@ -294,6 +294,7 @@
% \changes{v1.0g}{2022/06/16}{Better handling of option removal}
% \changes{v1.0h}{2022/06/19}{Further work on handling of option removal}
% \changes{v1.0h}{2022/06/20}{Use raw options data}
+% \changes{v1.0m}{2024/01/13}{Trim spaces off key names}
% \begin{macro}{\@@_options_class:nnn}
% \changes{v1.0h}{2022/06/20}{New function}
% \changes{v1.0i}{2022/07/05}{Correct naming of raw class options storage}
@@ -318,7 +319,7 @@
\clist_map_inline:cn { @raw@opt@ \@currname . \@currext }
{
\exp_args:Ne \@@_options_class:nnn
- { \@@_remove_equals:n {##1} }
+ { \tl_trim_spaces:e { \@@_remove_equals:n {##1} } }
{##1} {#1}
}
}
@@ -344,6 +345,7 @@
% \changes{v1.0g}{2022/06/16}{Better handling of option removal}
% \changes{v1.0h}{2022/06/19}{Further work on handling of option removal}
% \changes{v1.0h}{2022/06/20}{Use raw options data}
+% \changes{v1.0m}{2024/01/13}{Trim spaces off key names}
% \begin{macro}{\@@_options_package:nnn}
% \changes{v1.0h}{2022/06/19}{New function}
% For global options when processing a package, the tasks are slightly
@@ -356,7 +358,7 @@
\clist_map_inline:Nn \@raw@classoptionslist
{
\exp_args:Ne \@@_options_package:nnn
- { \@@_remove_equals:n {##1} }
+ { \tl_trim_spaces:e { \@@_remove_equals:n {##1} } }
{##1} {#1}
}
}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltlength.dtx b/Master/texmf-dist/source/latex-dev/base/ltlength.dtx
index 10e4b671c81..c81e6edfb74 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltlength.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltlength.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-dev/base/ltlists.dtx b/Master/texmf-dist/source/latex-dev/base/ltlists.dtx
index d43df93a54e..8d4c25d9164 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltlists.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltlists.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-dev/base/ltlogos.dtx b/Master/texmf-dist/source/latex-dev/base/ltlogos.dtx
index 7589cf36e1b..4fc710ba40d 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltlogos.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltlogos.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-dev/base/ltluatex.dtx b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
index 6d274ed5c33..a15019dcd55 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2015-2023
+% Copyright (C) 2015-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -23,16 +23,22 @@
%<tex> \ProvidesFile\undefined\begingroup\def\ProvidesFile
%<tex> #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}}
%<tex>\fi
-%<plain>\ProvidesFile{ltluatex.tex}%
-%<*driver>
+%<*dtx>
\ProvidesFile{ltluatex.dtx}
-%</driver>
-%<*tex>
-[2023/08/03 v1.2c
-%</tex>
-%<plain> LuaTeX support for plain TeX (core)
-%<*tex>
+%</dtx>
+%<plain>\ProvidesFile{ltluatex.tex}
+%<*plain>
+% \fi
+% \ProvidesFile{ltluatex.dtx}
+[2024/02/11 v1.2c
+% LaTeX Kernel (LuaTeX support)^^A
+%\iffalse
+%<plain> LuaTeX support for plain TeX (core)%
+%\fi
]
+% \iffalse
+%</plain>
+%<*tex>
\edef\etatcatcode{\the\catcode`\@}
\catcode`\@=11
%</tex>
@@ -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-dev/base/ltmarks.dtx b/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx
index 677534dd27c..dcfa2fcb27e 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltmarks.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
%% File: ltmarks.dtx
-%% Copyright (C) 2022-2023
+%% Copyright (C) 2022-2024
%% Frank Mittelbach, The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
@@ -14,12 +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/02/11 v1.0e LaTeX Kernel (Marks)]
+% \iffalse
+%
\documentclass{l3doc}
+\GetFileInfo{ltmarks.dtx}
%\usepackage{ltmarks}
@@ -45,7 +47,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 +158,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}.
@@ -299,6 +301,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 +357,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 +401,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 +614,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 +631,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 +646,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 +654,6 @@
%
%
%
-%
% \begin{function}{\@@_update_structure_to_err:n}
% \begin{syntax}
% \cs{@@_update_structure_to_err:n} \Arg{region}
@@ -662,6 +665,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 +737,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
{
@@ -784,57 +819,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 +894,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: } }
+%</trace>
+ \@@_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.
+% <argument> 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 +1145,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 +1182,144 @@
}
}
}
- }
+}
+% \end{macrocode}
+% \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}
+\cs_new_protected:Npn \@@_get_marks_for_reinsertion:nNN #1#2#3 {
% \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.
+% First we clear the temporary token lists as we haven't seen any marks yet.
% \begin{macrocode}
- {
- \msg_error:nnn { mark } { infinite-shrinkage } {#1}
- \seq_map_inline:Nn \g_@@_classes_seq
+ \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: } }
+%</trace>
+ }
+% \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 } }
+%</trace>
+ \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 }
+ } }
+%</trace>
+ \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}
%
@@ -1158,7 +1468,7 @@
% 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
@@ -1207,7 +1517,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 +1557,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 +1658,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 +1670,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} }
+%</trace>
+}
+% \end{macrocode}
+% \end{macro}
%
%
% \subsection{Designer-level interfaces}
@@ -1425,9 +1741,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 +1761,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 +1805,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}
@@ -1583,17 +1899,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 +1926,9 @@
%
%
%
+% \subsection{Rollback information}
+%
+%
% \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}{ltmarks}%
%<latexrelease> {Undo~Marks~handling}
@@ -1609,7 +1937,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}
%<latexrelease>\DeclareRobustCommand \NewMarkClass[1]{}
%<latexrelease>\DeclareRobustCommand \InsertMark[2]{}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltmath.dtx b/Master/texmf-dist/source/latex-dev/base/ltmath.dtx
index 3b1518dd2eb..b40faa8a800 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltmath.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltmath.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-dev/base/ltmeta.dtx b/Master/texmf-dist/source/latex-dev/base/ltmeta.dtx
index daaa71626bb..1e4bdaed2ca 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltmeta.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltmeta.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
%% File: ltmeta.dtx
-%% Copyright (C) 2021-2023
+%% Copyright (C) 2021-2024
%% Frank Mittelbach, The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
@@ -13,13 +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/02/11 v1.0b LaTeX Kernel (Document Metadata)]
+% \iffalse
+%
\documentclass{l3doc}
+\GetFileInfo{ltmeta.dtx}
% Fixing footnotes in functions and variables: this should be in l3doc!
@@ -43,7 +44,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-dev/base/ltmiscen.dtx b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx
index 74a9685f1fb..accdac24b2f 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltmiscen.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.
%
@@ -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-dev/base/ltoutenc.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx
index 1d257805a43..c18ff014464 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltoutenc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltoutenc.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.
%
@@ -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-dev/base/ltoutenc.ins b/Master/texmf-dist/source/latex-dev/base/ltoutenc.ins
index 2f0c39517fe..c5316f9aaba 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltoutenc.ins
+++ b/Master/texmf-dist/source/latex-dev/base/ltoutenc.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/ltoutput.dtx b/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
index 18388b1cc64..b067ef5ecbd 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltoutput.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltoutput.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-dev/base/ltpage.dtx b/Master/texmf-dist/source/latex-dev/base/ltpage.dtx
index 1a6586d067e..f4efe0fd584 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltpage.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltpage.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-dev/base/ltpageno.dtx b/Master/texmf-dist/source/latex-dev/base/ltpageno.dtx
index 6c02d0fa7f7..da80dbaab73 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltpageno.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltpageno.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-dev/base/ltpar.dtx b/Master/texmf-dist/source/latex-dev/base/ltpar.dtx
index 31d863610b4..200d3b4238b 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltpar.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltpar.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-dev/base/ltpara.dtx b/Master/texmf-dist/source/latex-dev/base/ltpara.dtx
index 9c1a95ee61b..e9741ff935e 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltpara.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltpara.dtx
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
%% File: ltpara.dtx
-%% Copyright (C) 2020-2023
+%% Copyright (C) 2020-2024
%% Frank Mittelbach, The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
@@ -14,12 +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/02/11 v1.0m LaTeX Kernel (paragraph hooks)]
+% \iffalse
+%
\documentclass{l3doc}
+\GetFileInfo{ltpara.dtx}
%\usepackage{ltpara}
@@ -45,7 +47,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 +813,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 +849,7 @@
%<latexrelease> \@kernel@before@para@begin
%<latexrelease> \hook_use:n {para/begin}
%<latexrelease> \if_mode_horizontal: \else:
-%<latexrelease> \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+%<latexrelease> \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi:
%<latexrelease> \@@_handle_indent:
%<latexrelease>}
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx b/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx
index 926fd5c6924..ea5ac4205b5 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltpictur.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltpictur.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-dev/base/ltplain.dtx b/Master/texmf-dist/source/latex-dev/base/ltplain.dtx
index b41810373d0..a628b954d97 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltplain.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltplain.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.
%
@@ -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 @@
%<latexrelease>\IncludeInRelease{2022/06/01}{\obeylines}%
%<latexrelease> {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-dev/base/ltproperties.dtx b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx
index 40c50cd20a2..4a5fa78b5fe 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: ltproperties.dtx
+% File: ltproperties.dtx
%
% Copyright (C) 2021-2023 The LaTeX Project
%
@@ -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/02/11 v1.0d 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}.\\
@@ -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}
@@ -342,7 +350,7 @@
%
% \begin{function}{\IfPropertyExistTF}
% \begin{syntax}
-% \cs{IfPropertyExistTF} \Arg{property} \Arg{true code} \Arg{false code}
+% \cs{IfPropertyExistTF} \Arg{property} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the \meta{property} has been declared.
% \end{function}
@@ -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,7 +746,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{IfPropertyExistTF}
+% \begin{macro}{\IfPropertyExistTF}
% \begin{macrocode}
\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltsect.dtx b/Master/texmf-dist/source/latex-dev/base/ltsect.dtx
index 5a03fd49777..4560704463a 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltsect.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltsect.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-dev/base/ltshipout.dtx b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx
index b19814a6fd4..0c9113ce938 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltshipout.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%%
-%% Copyright (C) 2020-2023
+%% Copyright (C) 2020-2024
%% Frank Mittelbach, The LaTeX Project
%%
%
@@ -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-dev/base/ltsockets.dtx b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx
index 7d2940f454b..243963f7bcc 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2023
+% Copyright (C) 2023-2024
% Frank Mittelbach, The LaTeX Project
%
% This file is part of the LaTeX base system.
@@ -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-dev/base/ltspace.dtx b/Master/texmf-dist/source/latex-dev/base/ltspace.dtx
index 03b34450474..206e4f38858 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltspace.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltspace.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.
%
@@ -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-dev/base/lttab.dtx b/Master/texmf-dist/source/latex-dev/base/lttab.dtx
index e76325d82ba..a85b4f8cf7a 100644
--- a/Master/texmf-dist/source/latex-dev/base/lttab.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lttab.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-dev/base/lttagging.dtx b/Master/texmf-dist/source/latex-dev/base/lttagging.dtx
new file mode 100644
index 00000000000..585479df214
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/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}
+%</driver>
+% \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}
+%<latexrelease>\NewModuleRelease{2024/06/01}{lttagging}
+%<latexrelease> {Tagging support}
+% \end{macrocode}
+%
+%
+%
+%
+% \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}{lttagging}%
+%<latexrelease> {Undo tagging support}
+%<latexrelease>
+%<latexrelease>
+%<latexrelease>
+%<latexrelease>\EndModuleRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+% \end{macrocode}
+%
+% \Finale
+%
diff --git a/Master/texmf-dist/source/latex-dev/base/lttemplates.dtx b/Master/texmf-dist/source/latex-dev/base/lttemplates.dtx
new file mode 100644
index 00000000000..844fb6fd346
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/base/lttemplates.dtx
@@ -0,0 +1,2698 @@
+% \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-02-11 v1.0a LaTeX Kernel (Prototype document functions)]
+% \iffalse
+\documentclass{l3doc}
+\GetFileInfo{lttemplates.dtx}
+\begin{document}
+ \DocInput{lttemplates.dtx}
+\end{document}
+%</driver>
+% \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.
+% \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 & 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}{\IfInstanceExistT, \IfInstanceExistF, \IfInstanceExistTF}
+% \begin{syntax}
+% \cs{IfInstanceExistTF} \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 } { <settings> }
+% }
+% \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,}
+%</2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*2ekernel|latexrelease>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease>\NewModuleRelease{2024/06/01}{lttemplates}
+%<latexrelease> {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}
+ \use:c { @@_assign_ \l_@@_keytype_tl : }
+ }
+ { \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_integer:}
+% \begin{macro}{\@@_assign_length:}
+% \begin{macro}{\@@_assign_muskip:}
+% \begin{macro}{\@@_assign_real:}
+% \begin{macro}{\@@_assign_skip:}
+% All of the calculated assignments use the same underlying code, with
+% only the low-level assignment function changing.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_integer:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_variable:N \int_gset:Nn }
+ { \@@_assign_variable:N \int_set:Nn }
+ }
+\cs_new_protected:Npn \@@_assign_length:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_variable:N \dim_gset:Nn }
+ { \@@_assign_variable:N \dim_set:Nn }
+}
+\cs_new_protected:Npn \@@_assign_muskip:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_variable:N \muskip_gset:Nn }
+ { \@@_assign_variable:N \muskip_set:Nn }
+ }
+\cs_new_protected:Npn \@@_assign_real:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_variable:N \fp_gset:Nn }
+ { \@@_assign_variable:N \fp_set:Nn }
+ }
+\cs_new_protected:Npn \@@_assign_skip:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_variable:N \skip_gset:Nn }
+ { \@@_assign_variable:N \skip_set:Nn }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_tokenlist:}
+% \begin{macro}{\@@_assign_tokenlist_aux:NN}
+% Life would be easy here if it were not for \cs{KeyValue}. To deal
+% correctly with that, we need to allow for the recovery a stored value
+% at point of use.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_tokenlist:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_tokenlist_aux:NN \tl_gset:NV \tl_gset:Nn }
+ { \@@_assign_tokenlist_aux:NN \tl_set:NV \tl_set:Nn }
+ }
+\cs_new_protected:Npn \@@_assign_tokenlist_aux:NN #1#2
+ {
+ \@@_if_key_value:VTF \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 }
+ }
+ }
+ {
+ \tl_put_right:Ne \l_@@_assignments_tl
+ {
+ #2 \exp_not:V \l_@@_var_tl
+ { \exp_not:V \l_@@_value_tl }
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_commalist:}
+% Very similar for commas lists, so some code is shared.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_commalist:
+ {
+ \bool_if:NTF \l_@@_global_bool
+ { \@@_assign_tokenlist_aux:NN \clist_gset:NV \clist_gset:Nn }
+ { \@@_assign_tokenlist_aux:NN \clist_set:NV \clist_set:Nn }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_variable:N}
+% A general-purpose function for all of the numerical 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: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 }
+ }
+ }
+% \end{macrocode}
+% \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 \\
+ ~~'<variable>'\\
+ ~or~\\
+ ~~'global~<variable>'.\\
+ 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 = <code> ~} \\
+ but~LaTeX~did~not~find~any~<code>.
+ }
+\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:\\
+ \ \ <key-name>~:~#1~{~<argument>~} \\
+ but~LaTeX~did~not~find~an~<argument>.
+ }
+\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:\\
+ \ \ <key>~:~<key-type>\\
+ LaTeX~could~not~find~a~<key-type>~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:\\
+ \ \ <key>~=~<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~:~<key-type>\\
+ but~LaTeX~could~not~find~a~<key-type>.
+ }
+\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}{\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}
+%<latexrelease>\IncludeInRelease{0000/00/00}{lttemplates}%
+%<latexrelease> {Prototype~document~commands}%
+%<latexrelease>
+%<latexrelease>\EndModuleRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+% \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-dev/base/lttextcomp.dtx b/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx
index 3602e0a6b00..c67bac00dd8 100644
--- a/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lttextcomp.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2019-2023
+% Copyright (C) 2019-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -37,7 +37,7 @@
%
%
\ProvidesFile{lttextcomp.dtx}
- [2022/08/07 v1.0g LaTeX Kernel (text companion symbols)]
+ [2024/02/08 v1.1a 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,7 +1522,6 @@
%
%
%
-%
% \section{The \texttt{textcomp} package}
%
%
@@ -1706,7 +1746,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 +2341,547 @@
% \begin{macrocode}
%</TS1oldsty>
% \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 <enter> 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
+%</TS1check>
+% \end{macrocode}
+%
% \Finale
%
diff --git a/Master/texmf-dist/source/latex-dev/base/ltthm.dtx b/Master/texmf-dist/source/latex-dev/base/ltthm.dtx
index b321c7ac2b1..180b8accfe4 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltthm.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltthm.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-dev/base/ltvers.dtx b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx
index e169dee020d..38969355259 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltvers.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.
%
@@ -115,7 +115,7 @@
{2024-06-01}
%</2ekernel|latexrelease>
%<*2ekernel>
-\def\patch@level{0}
+\def\patch@level{-1}
% \end{macrocode}
%
% \begin{macro}{\development@branch@name}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx b/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx
index e147c9d22fe..5e8b4946926 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltxdoc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltxdoc.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.
%
@@ -30,7 +30,7 @@
%
%<class>\NeedsTeXFormat{LaTeX2e}
%<class>\ProvidesClass{ltxdoc}
-%<class> [2023/03/28 v2.1j Standard LaTeX documentation class]
+%<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}
@@ -676,7 +677,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
%
% Copyright 2006, 2007, 2011
% Heiko Oberdiek
-% Copyright (C) 2014-2023
+% Copyright (C) 2014-2024
% The LaTeX Project
%
diff --git a/Master/texmf-dist/source/latex-dev/base/ltxref.dtx b/Master/texmf-dist/source/latex-dev/base/ltxref.dtx
index 0f842e4312a..79cf01be770 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltxref.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltxref.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-dev/base/makeindx.dtx b/Master/texmf-dist/source/latex-dev/base/makeindx.dtx
index b91d3a6c441..20da2f159df 100644
--- a/Master/texmf-dist/source/latex-dev/base/makeindx.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/makeindx.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-dev/base/makeindx.ins b/Master/texmf-dist/source/latex-dev/base/makeindx.ins
index 1c5f6edcb92..45e5c9aab00 100644
--- a/Master/texmf-dist/source/latex-dev/base/makeindx.ins
+++ b/Master/texmf-dist/source/latex-dev/base/makeindx.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/newdc.ins b/Master/texmf-dist/source/latex-dev/base/newdc.ins
index 277e8ea21f6..69d74d61676 100644
--- a/Master/texmf-dist/source/latex-dev/base/newdc.ins
+++ b/Master/texmf-dist/source/latex-dev/base/newdc.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/newlfont.dtx b/Master/texmf-dist/source/latex-dev/base/newlfont.dtx
index 0b35eddd800..2792395c58a 100644
--- a/Master/texmf-dist/source/latex-dev/base/newlfont.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/newlfont.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-dev/base/nfssfont.dtx b/Master/texmf-dist/source/latex-dev/base/nfssfont.dtx
index 556ce5f76da..0464053c10f 100644
--- a/Master/texmf-dist/source/latex-dev/base/nfssfont.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/nfssfont.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.
%
@@ -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-dev/base/nfssfont.ins b/Master/texmf-dist/source/latex-dev/base/nfssfont.ins
index 21a13f70a89..00f5a0c8a39 100644
--- a/Master/texmf-dist/source/latex-dev/base/nfssfont.ins
+++ b/Master/texmf-dist/source/latex-dev/base/nfssfont.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/olddc.ins b/Master/texmf-dist/source/latex-dev/base/olddc.ins
index 320b3a4b0ef..1f5d12ece4a 100644
--- a/Master/texmf-dist/source/latex-dev/base/olddc.ins
+++ b/Master/texmf-dist/source/latex-dev/base/olddc.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/oldlfont.dtx b/Master/texmf-dist/source/latex-dev/base/oldlfont.dtx
index 33ae5e6fd9d..7a3534f517a 100644
--- a/Master/texmf-dist/source/latex-dev/base/oldlfont.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/oldlfont.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-dev/base/preload.dtx b/Master/texmf-dist/source/latex-dev/base/preload.dtx
index d26bdaa9ed1..fb5f86824cf 100644
--- a/Master/texmf-dist/source/latex-dev/base/preload.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/preload.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-dev/base/proc.dtx b/Master/texmf-dist/source/latex-dev/base/proc.dtx
index bbbf71162ff..ec69e473966 100644
--- a/Master/texmf-dist/source/latex-dev/base/proc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/proc.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-dev/base/proc.ins b/Master/texmf-dist/source/latex-dev/base/proc.ins
index 056816e99ef..83f50bda123 100644
--- a/Master/texmf-dist/source/latex-dev/base/proc.ins
+++ b/Master/texmf-dist/source/latex-dev/base/proc.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/slides.dtx b/Master/texmf-dist/source/latex-dev/base/slides.dtx
index a918c337dd8..3674a6c05f6 100644
--- a/Master/texmf-dist/source/latex-dev/base/slides.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/slides.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-dev/base/slides.ins b/Master/texmf-dist/source/latex-dev/base/slides.ins
index 3acb556b96a..3124ed366f9 100644
--- a/Master/texmf-dist/source/latex-dev/base/slides.ins
+++ b/Master/texmf-dist/source/latex-dev/base/slides.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -96,7 +96,7 @@ extension .ins) which are part of the distribution.
This is a generated file.
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -138,7 +138,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/slifonts.fdd b/Master/texmf-dist/source/latex-dev/base/slifonts.fdd
index 5b66975095c..b35cd07a8be 100644
--- a/Master/texmf-dist/source/latex-dev/base/slifonts.fdd
+++ b/Master/texmf-dist/source/latex-dev/base/slifonts.fdd
@@ -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.
%
@@ -45,7 +45,7 @@
%<*driver, >
\ProvidesFile{sfonts.drv}
%</driver, >
- [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-dev/base/syntonly.dtx b/Master/texmf-dist/source/latex-dev/base/syntonly.dtx
index 2b0049b6964..9844585fa56 100644
--- a/Master/texmf-dist/source/latex-dev/base/syntonly.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/syntonly.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.
%
@@ -71,7 +71,7 @@
\ProvidesFile{syntonly.dtx}
%</dtx>
%<*package|dtx>
- [2017/06/30 v2.1e Standard LaTeX2e package]
+ [2024/02/08 v2.1e Standard LaTeX2e package]
%</package|dtx>
% \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-dev/base/syntonly.ins b/Master/texmf-dist/source/latex-dev/base/syntonly.ins
index 8ccaf254d15..6435e0a6ee8 100644
--- a/Master/texmf-dist/source/latex-dev/base/syntonly.ins
+++ b/Master/texmf-dist/source/latex-dev/base/syntonly.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 1993-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-dev/base/tulm.fdd b/Master/texmf-dist/source/latex-dev/base/tulm.fdd
index c8dd8b95fcf..6f7a6873cd6 100644
--- a/Master/texmf-dist/source/latex-dev/base/tulm.fdd
+++ b/Master/texmf-dist/source/latex-dev/base/tulm.fdd
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2016-2023
+% Copyright (C) 2016-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/Master/texmf-dist/source/latex-dev/base/tulm.ins b/Master/texmf-dist/source/latex-dev/base/tulm.ins
index 85970a51333..ea8fd7b22bf 100644
--- a/Master/texmf-dist/source/latex-dev/base/tulm.ins
+++ b/Master/texmf-dist/source/latex-dev/base/tulm.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 2016-2023
+%% Copyright (C) 2016-2024
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 2016-2023
+Copyright (C) 2016-2024
The LaTeX Project and any individual authors listed elsewhere
in this file.
diff --git a/Master/texmf-dist/source/latex-dev/base/unpack.ins b/Master/texmf-dist/source/latex-dev/base/unpack.ins
index 5baa2b5447c..e81c8dbfa82 100644
--- a/Master/texmf-dist/source/latex-dev/base/unpack.ins
+++ b/Master/texmf-dist/source/latex-dev/base/unpack.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 1993-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-dev/base/utf8ienc.dtx b/Master/texmf-dist/source/latex-dev/base/utf8ienc.dtx
index f1623ee0e6c..a2701ac5c87 100644
--- a/Master/texmf-dist/source/latex-dev/base/utf8ienc.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/utf8ienc.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.
%
@@ -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}
%<all,x2,t2c,t2b>\DeclareUnicodeCharacter{04C5}{\CYRLDSC}
%<all,x2,t2c,t2b>\DeclareUnicodeCharacter{04C6}{\cyrldsc}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
index b37ae6c9d79..6bc7e232a14 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/documentmetadata-support.dtx
@@ -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}
%
%
@@ -215,6 +224,10 @@
% This code is also loaded by the \texttt{phase-III} 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 +287,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
@@ -348,15 +381,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 =
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-amsmath.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-amsmath.dtx
index e1f95730fae..c50a40eeddf 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-amsmath.dtx
+++ b/Master/texmf-dist/source/latex-dev/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{paratag=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,78 @@
}
% \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}
+%
% \begin{macrocode}
\ExplSyntaxOff
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-bib.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-bib.dtx
index a467bf31582..e8ee192a7b2 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-bib.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-block.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-block.dtx
index e0a723ca87c..75203f8ed55 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-block.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-02-12}
+\def\ltlabblockversion{0.8l}
%<*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}
%
@@ -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} }
@@ -2488,10 +2529,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 +2674,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 +3334,7 @@
\DeclareInstance{item}{description}{std}
{
label-format = \normalfont\bfseries #1 ,
+ label-align = left
}
% \end{macrocode}
% \end{instance}
@@ -3389,9 +3434,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 +3467,12 @@
{
\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,
+ }
}
}
}
@@ -3445,7 +3492,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 +3539,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 +3598,20 @@
{
\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,
+ }
}
}
- \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 +3623,19 @@
\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,
+ }
}
- \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 +3649,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 +3712,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 +3735,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 +3777,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
}
@@ -3792,7 +3847,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 +3890,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 +3909,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-dev/latex-lab/latex-lab-firstaid.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx
index e2ee78b2fff..a50b3678379 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-firstaid.dtx
@@ -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-01-21}
+\def\ltlabfirstaidversion{0.85b}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -64,7 +64,17 @@
\ltlabfirstaiddate\space v\ltlabfirstaiddate\space
Temporary patches to external packages needed for the tagging project]
% \end{macrocode}
-
+% \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{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
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-float.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-float.dtx
index 3bd34836008..e1c70968abb 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-float.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-02-05}
+\def\ltlabfloatversion{0.81c}
%<*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}
}
@@ -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 ...
@@ -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-dev/latex-lab/latex-lab-graphic.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-graphic.dtx
index 158b0d2a9c4..9585bee189e 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-graphic.dtx
+++ b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-graphic.dtx
@@ -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
@@ -894,7 +897,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 +973,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-dev/latex-lab/latex-lab-marginpar.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-marginpar.dtx
new file mode 100644
index 00000000000..ca79d8a67fa
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/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}
+%</driver>
+%
+% \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:
+ }
+%</package>
+% \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}
+
+%</latex-lab>
+% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx
index 285471addc3..03eb8e42d08 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-math.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-02-09}
+\def\ltlabmathversion{0.5i}
%
%<*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 |<!DOCTYPE html><html>| and end with |</html>|
+% 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 |<mo>{</mo>|
+%
+% The file should contain a number of representations in this format:
+% \begin{quote}
+% |<div>| \\
+% | <h2>\mml| \meta{key}|</h2>|\\
+% | <p>|\meta{source}|</p>| \\
+% | <p>|\meta{hash}|</p>| \\
+% | <math | \meta{attributes} |>|\\
+% \meta{mathml}\\
+% | </math>|\\
+% |</div>|
+% \end{quote}
+% The keywords |<div>|, |<h2>\mml|, |<p>|, |<math|, |</math>| |</div>| 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}
+% <math alttext="\mathbf{G}" class="ltx_Math" display="inline">
+% \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
+ {newattribute = {inline} {/O /Layout /Placement/Inline},
+ newattribute = {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</h2>#2<p>#3</p>#4<p>#5</p>#6<math{
+ \begingroup
+ \char_set_catcode_other:N\{
+ \char_set_catcode_other:N\}
+ \char_set_catcode_other:N\#
+ \char_set_catcode_other:N\%
+ \@@_AF_html_reader_verb:w{#1}{#3}{#5}<math
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new_protected:Npn\@@_AF_html_reader_verb:w#1#2#3#4~</div>{
+ \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{&}{&amp;}
+ \str_replace_all:Nnn\l_@@_tmpa_str{<}{&lt;}
+ \iow_now:Ne \g_@@_writedummy_iow
+ {
+ \iow_newline:
+ <div>
+ \iow_newline:
+ <h2>\c_backslash_str mml\c_space_tl \int_use:N \g_@@_math_total_int </h2>
+ \iow_newline:
+ <p>\l_@@_tmpa_str</p>
+ \iow_newline:
+ <p>\l_@@_content_hash_tl </p>
+ \iow_newline:
+ <math></math>
+ \iow_newline:
+ </div>
+ \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
+ {
+ <!DOCTYPE~html>
+ \iow_newline:
+ <html>
+ }
+ \AssignSocketPlug {tagsupport/math/mathml/write}{On}
+ \AddToHook{enddocument/afterlastpage}
+ {
+ \iow_now:Nn \g_@@_writedummy_iow {</html>}
+ \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,61 @@
\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,
% \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 $ }
+ {
+ \socket_use:n {tagsupport/math/inline/begin} %end P-MC
+ \socket_use:nn{tagsupport/math/inline/formula/begin}{#1}
+ $
+ \socket_use:n {tagsupport/math/inline/formula/end}
+ \socket_use:n {tagsupport/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 +1443,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 +1496,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 +1505,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 +1516,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 +1539,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 +1550,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 +1575,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 +1586,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 +1622,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 +1631,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 +1654,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 +1671,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 +1703,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 +1748,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 +1799,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 +1813,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 +1845,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 +1876,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 +1926,7 @@
$$\ignorespacesafterend
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\def\common@align@ending {
\math@cr \black@\totwidth@
@@ -1007,9 +1999,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 +2026,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 +2041,7 @@
\cr
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\@namedef{math@cr @ @ @ align}{%
\ifst@rred\nonumber\fi
@@ -1104,7 +2062,7 @@
\cr
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\def\restore@math@cr{\@namedef{math@cr @ @ @}{
%
@@ -1113,7 +2071,7 @@
\cr}}
\restore@math@cr
% \end{macrocode}
-%
+%
% \begin{macrocode}
}
% \end{macrocode}
@@ -1125,9 +2083,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 +2104,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 +2122,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 +2133,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 +2162,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 +2199,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 +2269,6 @@
% \end{macrocode}
%
% \begin{macrocode}
-%
-% \end{macrocode}
-%
-% \begin{macrocode}
%</kernel>
% \end{macrocode}
%
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathpkg.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathpkg.dtx
index 14d8e943624..a8e8e810ada 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathpkg.dtx
+++ b/Master/texmf-dist/source/latex-dev/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
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathtools.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathtools.dtx
index c3f43243b10..1a0b8e06306 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-mathtools.dtx
+++ b/Master/texmf-dist/source/latex-dev/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
@@ -170,6 +170,7 @@
\MH_fi:
\tag_mc_end_push:
\tagpdfsetup{paratag=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{paratag=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-dev/latex-lab/latex-lab-minipage.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-minipage.dtx
index 1d3ee828aa4..ffbe5357e76 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-minipage.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-namespace.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-namespace.dtx
index 2ec9b0584bf..a6087abe578 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-namespace.dtx
+++ b/Master/texmf-dist/source/latex-dev/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
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-1.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-1.dtx
index cc60f50de01..9994b15cb8d 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-1.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-new-or-2.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-2.dtx
index d2011256b1a..ee20331a8f4 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-new-or-2.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-sec.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-sec.dtx
index ae7a0b85c30..f3786c2ddb8 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-sec.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-table.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-table.dtx
index 700d4ce6c17..2eafb0a21e3 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-table.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-02-07}
+\def\ltlabtblversion{0.85k}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -115,9 +115,17 @@
% 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 he 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}.
%
% Inside cells the automatic tagging of paragraphs is disabled with the exception of
% p/m/b-type cells.
@@ -126,9 +134,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 +148,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 +202,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 +220,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 +283,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 +296,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 +316,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 +358,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 +368,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 +389,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 +400,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 +415,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 +454,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 +470,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
@@ -683,11 +671,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 +713,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 +721,7 @@
%
% \begin{plugdecl}{Table}
% \begin{macrocode}
-\NewSocketPlug{tagsupport/tblhmode/end}{Table}
+\NewSocketPlug{tagsupport/tbl/hmode/end}{Table}
{
\tag_struct_end:
% \end{macrocode}
@@ -721,9 +738,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 +748,7 @@
%
% \begin{plugdecl}{Table}
% \begin{macrocode}
-\NewSocketPlug{tagsupport/tblvmode/end}{Table}
+\NewSocketPlug{tagsupport/tbl/vmode/end}{Table}
{
\tag_struct_end:
\par
@@ -740,30 +757,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 +808,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 +819,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 +846,58 @@
% \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}
+ },
+ 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
@@ -983,261 +1010,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}
- {
- \typeout{==>~
- ~Inserting~\int_eval:n{#1}~additional~cell(s)~into~previous~row:}
- }
- \int_step_inline:nn { #1 }
+ \int_compare:nNnT \g_@@_missing_cells_int > 0
{
- \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,120 +1079,9 @@
%
%
%
-% \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}
% {
% \g_@@_struct_table_tl, \l_@@_saved_struct_table_tl,
@@ -1390,474 +1113,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.
-% \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.
+% This is also the right point to initialize
+% them. \cs{g_@@_struct_table_tl} is set elsewhere.
% \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 +1195,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}
%</package>
% \end{macrocode}
@@ -1973,3 +1212,11 @@
\RequirePackage{latex-lab-testphase-table}
%</latex-lab>
% \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}
+%</latex-lab-alias>
+% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx
index b2ed5ecf8a4..ca3afe896dd 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-testphase.dtx
+++ b/Master/texmf-dist/source/latex-dev/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}{}}
%</phase-III>
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-text.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-text.dtx
index 4041336ecbf..fe9b6ababc7 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-text.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-title.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-title.dtx
new file mode 100644
index 00000000000..757bb284a45
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/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}
+%</driver>
+%
+% \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{<FEFF>}
+ {
+ \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{<FEFF>}
+ {
+ \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}
+%</package>
+% \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}
+
+%</latex-lab>
+% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-hyperref-changes.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-hyperref-changes.dtx
index 2f00b83c059..ff9dd950b76 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-hyperref-changes.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-toc-kernel-changes.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-kernel-changes.dtx
index 81c9edfe4dc..bb88ffdcb03 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc-kernel-changes.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab-toc.dtx b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc.dtx
index 6def505e113..7235eb9ed95 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab-toc.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/latex-lab/latex-lab.ins b/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins
index 548f18a6fa7..7071ed6e3dc 100644
--- a/Master/texmf-dist/source/latex-dev/latex-lab/latex-lab.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/afterpage.dtx b/Master/texmf-dist/source/latex-dev/tools/afterpage.dtx
index 518b70761d9..72df39402c9 100644
--- a/Master/texmf-dist/source/latex-dev/tools/afterpage.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/afterpage.ins b/Master/texmf-dist/source/latex-dev/tools/afterpage.ins
index 6fec5edc6f6..17792ddfa13 100644
--- a/Master/texmf-dist/source/latex-dev/tools/afterpage.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/array.dtx b/Master/texmf-dist/source/latex-dev/tools/array.dtx
index 6e4e34ea260..66c40a52675 100644
--- a/Master/texmf-dist/source/latex-dev/tools/array.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.
@@ -30,10 +30,15 @@
%<+package>
%<+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> [2023/12/11 v2.6a Tabular extension package (FMi)]
%
% \fi
%
@@ -177,6 +182,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 +212,8 @@
% \MaintainedByLaTeXTeam{tools}
% \maketitle
%
+%
+%
% \MakeShortVerb{\=}
%
% \begin{abstract}
@@ -750,12 +769,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 +808,6 @@
% \newblock
% Addison-Wesley, Reading, Massachusetts, 1986.
% \end{thebibliography}
-%
% } ^^A end of \MaybeStop
%
%
@@ -786,8 +821,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 +893,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 +1071,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 +1081,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 +1132,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 +1142,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 +1163,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 +1175,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 +1212,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 +1234,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 +1243,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}
%
@@ -1275,6 +1376,13 @@
% \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}
@@ -1302,12 +1410,36 @@
% \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}
% \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 +1453,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 +1538,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 +1622,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 +1816,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 +1834,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 +1928,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 +1981,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 +2177,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 +2196,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 +2212,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 +2243,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 +2311,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 +2331,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 +2420,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 +2456,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 +2466,11 @@
\@ifstar \@xarraycr \@xarraycr}
% \end{macrocode}
% \end{macro}
+
+
+
+
+
%
% \begin{macro}{\@xarraycr}
% In the command =\@xarraycr= we test if an optional argument
@@ -2301,6 +2562,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 +2572,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 +2608,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 +2736,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 +2770,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 {
+ \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}
-%\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
+ \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 +2813,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 +2838,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 +2896,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 +2936,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 +3032,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 +3131,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 +3194,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 +3234,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 +3246,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}
%</ncols>
% \end{macrocode}
@@ -2936,28 +3262,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 +3507,14 @@
% \end{macro}
%
%
+%
+%
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+%
% \PrintIndex
% \PrintChanges
%
diff --git a/Master/texmf-dist/source/latex-dev/tools/bm.dtx b/Master/texmf-dist/source/latex-dev/tools/bm.dtx
index a608c6aeb58..d7d6eb54ee2 100644
--- a/Master/texmf-dist/source/latex-dev/tools/bm.dtx
+++ b/Master/texmf-dist/source/latex-dev/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 @@
%<driver>\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-dev/tools/bm.ins b/Master/texmf-dist/source/latex-dev/tools/bm.ins
index a7424a0e675..c0c8125d101 100644
--- a/Master/texmf-dist/source/latex-dev/tools/bm.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/calc.dtx b/Master/texmf-dist/source/latex-dev/tools/calc.dtx
index 2c4cecbf038..154c6ba26a8 100644
--- a/Master/texmf-dist/source/latex-dev/tools/calc.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/dcolumn.dtx b/Master/texmf-dist/source/latex-dev/tools/dcolumn.dtx
index c8ddaf4ce6b..feb3096ccec 100644
--- a/Master/texmf-dist/source/latex-dev/tools/dcolumn.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/delarray.dtx b/Master/texmf-dist/source/latex-dev/tools/delarray.dtx
index 86a1a6203f6..61d40b5c744 100644
--- a/Master/texmf-dist/source/latex-dev/tools/delarray.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/enumerate.dtx b/Master/texmf-dist/source/latex-dev/tools/enumerate.dtx
index 2818a73a09b..c3889a9157a 100644
--- a/Master/texmf-dist/source/latex-dev/tools/enumerate.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/fileerr.dtx b/Master/texmf-dist/source/latex-dev/tools/fileerr.dtx
index eef222bb6eb..0e8eeb1ffb1 100644
--- a/Master/texmf-dist/source/latex-dev/tools/fileerr.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/fontsmpl.dtx b/Master/texmf-dist/source/latex-dev/tools/fontsmpl.dtx
index 525065cde5f..6e9835e20eb 100644
--- a/Master/texmf-dist/source/latex-dev/tools/fontsmpl.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/ftnright.dtx b/Master/texmf-dist/source/latex-dev/tools/ftnright.dtx
index 663fa304a94..a3826376dbb 100644
--- a/Master/texmf-dist/source/latex-dev/tools/ftnright.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/hhline.dtx b/Master/texmf-dist/source/latex-dev/tools/hhline.dtx
index 49ac1ae2082..b2d833d965d 100644
--- a/Master/texmf-dist/source/latex-dev/tools/hhline.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/indentfirst.dtx b/Master/texmf-dist/source/latex-dev/tools/indentfirst.dtx
index 2314db1c70c..9bbe1871e15 100644
--- a/Master/texmf-dist/source/latex-dev/tools/indentfirst.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/layout.dtx b/Master/texmf-dist/source/latex-dev/tools/layout.dtx
index 2798bd4f60d..a2fc87a6a51 100644
--- a/Master/texmf-dist/source/latex-dev/tools/layout.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/longtable.dtx b/Master/texmf-dist/source/latex-dev/tools/longtable.dtx
index 2a61ab0c87e..5a23f3ecb39 100644
--- a/Master/texmf-dist/source/latex-dev/tools/longtable.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.
@@ -37,7 +37,7 @@
%<driver> \ProvidesFile{longtable.drv}
% \fi
% \ProvidesFile{longtable.dtx}
- [2023-11-01 v4.19 Multi-page Table package (DPC)]
+ [2023-12-16 v4.19 Multi-page Table package (DPC)]
%
% \iffalse
%<*driver>
@@ -1048,6 +1048,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 +1064,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 +1081,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 +1152,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 +1180,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 +1194,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 +1224,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 +1237,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 +1267,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 +1296,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 +1373,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 +1461,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 +1469,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 +1519,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 +1575,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 +1610,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 +1687,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 +1717,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 +1733,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 +1748,8 @@
\ifnum0=`{}\fi
\expandafter\LT@LL@FM@cr
\fi}
+\ExplSyntaxOff
+%<@@=>
% \end{macrocode}
% \end{macro}
%
@@ -1943,7 +2130,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 +2143,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 +2252,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 +2308,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 +2326,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 +2354,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 +2370,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 +2549,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}
%</package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/tools/longtable.ins b/Master/texmf-dist/source/latex-dev/tools/longtable.ins
index 5c3ad270638..60b74615718 100644
--- a/Master/texmf-dist/source/latex-dev/tools/longtable.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/multicol.dtx b/Master/texmf-dist/source/latex-dev/tools/multicol.dtx
index 2676d03aa18..9c680ab5639 100644
--- a/Master/texmf-dist/source/latex-dev/tools/multicol.dtx
+++ b/Master/texmf-dist/source/latex-dev/tools/multicol.dtx
@@ -99,10 +99,10 @@
%<driver> \ProvidesFile{multicol.drv}
% \fi
% \ProvidesFile{multicol.dtx}
- [2023/03/30 v1.9f multicolumn formatting (FMi)]
+ [2024/01/29 v1.9g 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 +919,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 +1095,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 +2389,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 +2938,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 +3768,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 +3797,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-dev/tools/multicol.ins b/Master/texmf-dist/source/latex-dev/tools/multicol.ins
index fa561e0bb1e..7a7ef27d248 100644
--- a/Master/texmf-dist/source/latex-dev/tools/multicol.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/rawfonts.dtx b/Master/texmf-dist/source/latex-dev/tools/rawfonts.dtx
index 4b930f3ea70..3ffa2032c38 100644
--- a/Master/texmf-dist/source/latex-dev/tools/rawfonts.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/shellesc.dtx b/Master/texmf-dist/source/latex-dev/tools/shellesc.dtx
index aa707fe550a..8a556de9229 100644
--- a/Master/texmf-dist/source/latex-dev/tools/shellesc.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/showkeys.dtx b/Master/texmf-dist/source/latex-dev/tools/showkeys.dtx
index c90b3863e1a..aba96a7eabe 100644
--- a/Master/texmf-dist/source/latex-dev/tools/showkeys.dtx
+++ b/Master/texmf-dist/source/latex-dev/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,7 +22,7 @@
% \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-2023 David Carlisle, LaTeX Project
%
%<*dtx>
\ProvidesFile{showkeys.dtx}
@@ -39,7 +39,7 @@
%<driver> \ProvidesFile{showkeys.drv}
% \fi
% \ProvidesFile{showkeys.dtx}
- [2023/07/08 v3.19 Show cite and label keys (DPC, MH)]
+ [2023/12/16 v3.20 Show cite and label keys (DPC, MH)]
%
% \iffalse
%<*driver>
@@ -417,6 +417,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 +427,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-dev/tools/somedefs.dtx b/Master/texmf-dist/source/latex-dev/tools/somedefs.dtx
index 02653a13939..156621d70e2 100644
--- a/Master/texmf-dist/source/latex-dev/tools/somedefs.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/tabularx.dtx b/Master/texmf-dist/source/latex-dev/tools/tabularx.dtx
index 6d59ca4c228..52ee62cad90 100644
--- a/Master/texmf-dist/source/latex-dev/tools/tabularx.dtx
+++ b/Master/texmf-dist/source/latex-dev/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 @@
%<driver> \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}
%</package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex-dev/tools/tabularx.ins b/Master/texmf-dist/source/latex-dev/tools/tabularx.ins
index 6e81e934325..fdce598d379 100644
--- a/Master/texmf-dist/source/latex-dev/tools/tabularx.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/theorem.dtx b/Master/texmf-dist/source/latex-dev/tools/theorem.dtx
index e3a8e90b8c2..a9c3ccae3ed 100644
--- a/Master/texmf-dist/source/latex-dev/tools/theorem.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/tools.ins b/Master/texmf-dist/source/latex-dev/tools/tools.ins
index 6898faead37..2fd1cd174b8 100644
--- a/Master/texmf-dist/source/latex-dev/tools/tools.ins
+++ b/Master/texmf-dist/source/latex-dev/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.
diff --git a/Master/texmf-dist/source/latex-dev/tools/trace.dtx b/Master/texmf-dist/source/latex-dev/tools/trace.dtx
index 788f8316204..27a39c776b4 100644
--- a/Master/texmf-dist/source/latex-dev/tools/trace.dtx
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/varioref.dtx b/Master/texmf-dist/source/latex-dev/tools/varioref.dtx
index e801c54f818..ccf3468c9b9 100644
--- a/Master/texmf-dist/source/latex-dev/tools/varioref.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.
diff --git a/Master/texmf-dist/source/latex-dev/tools/varioref.ins b/Master/texmf-dist/source/latex-dev/tools/varioref.ins
index dcc41d01766..88527a20ba1 100644
--- a/Master/texmf-dist/source/latex-dev/tools/varioref.ins
+++ b/Master/texmf-dist/source/latex-dev/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-dev/tools/verbatim.dtx b/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx
index 832f80ef3a0..468dead3e83 100644
--- a/Master/texmf-dist/source/latex-dev/tools/verbatim.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.
@@ -55,7 +55,7 @@
\and
Chris Rowley}
-\date{2023/07/08}
+\date{2023/11/06}
\begin{document}
\markboth{Verbatim style option}{Verbatim style option}
\MaintainedByLaTeXTeam{tools}
@@ -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}
- [2022-07-02 v1.5u LaTeX2e package for verbatim enhancements]
+ [2024-01-22 v1.5x LaTeX2e package for verbatim enhancements]
\@ifundefined{verbatim@@@}{}{\endinput}
% \end{macrocode}
%
@@ -549,9 +551,17 @@
% to be printed as spaces in the output.
% \begin{macrocode}
\begingroup
- \catcode`\ =\active%
- \def\x{\def\@vobeyspaces{\catcode`\ \active\let \@xobeysp}}
- \expandafter\endgroup\x
+\catcode`\ =\active%
+% \end{macrocode}
+% Because space is active we can't indent the following code
+% nicely---we would then get the spaces at the beginning of the
+% line as the third and fourth argument to \cs{@ifl@t@r}.
+% \changes{v1.5v}{2023/11/06}{\cs{@vobeytabs} added when available (gh/1160)}
+% \begin{macrocode}
+\@ifl@t@r\fmtversion{2023-11-01}%
+{\def\x{\def\@vobeyspaces{\catcode`\ \active\let \@xobeysp\@vobeytabs}}}%
+{\def\x{\def\@vobeyspaces{\catcode`\ \active\let \@xobeysp}}}%
+\expandafter\endgroup\x
% \end{macrocode}
% \end{macro}
%
@@ -1562,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-dev/tools/xr.dtx b/Master/texmf-dist/source/latex-dev/tools/xr.dtx
index be48f5a01b2..3914cebcd98 100644
--- a/Master/texmf-dist/source/latex-dev/tools/xr.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.
diff --git a/Master/texmf-dist/source/latex-dev/tools/xspace.dtx b/Master/texmf-dist/source/latex-dev/tools/xspace.dtx
index 807fc9c5df3..be20fc9e522 100644
--- a/Master/texmf-dist/source/latex-dev/tools/xspace.dtx
+++ b/Master/texmf-dist/source/latex-dev/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.