summaryrefslogtreecommitdiff
path: root/macros/latex-dev/base
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/base')
-rw-r--r--macros/latex-dev/base/README.md2
-rw-r--r--macros/latex-dev/base/alltt.dtx6
-rw-r--r--macros/latex-dev/base/alltt.ins4
-rw-r--r--macros/latex-dev/base/alltt.pdfbin223831 -> 223861 bytes
-rw-r--r--macros/latex-dev/base/cfgguide.pdfbin264168 -> 264168 bytes
-rw-r--r--macros/latex-dev/base/cfgguide.tex2
-rw-r--r--macros/latex-dev/base/changes.txt137
-rw-r--r--macros/latex-dev/base/classes.dtx14
-rw-r--r--macros/latex-dev/base/classes.ins4
-rw-r--r--macros/latex-dev/base/classes.pdfbin560998 -> 560294 bytes
-rw-r--r--macros/latex-dev/base/clsguide-historic.pdfbin415615 -> 415956 bytes
-rw-r--r--macros/latex-dev/base/clsguide-historic.tex12
-rw-r--r--macros/latex-dev/base/clsguide.pdfbin489925 -> 489795 bytes
-rw-r--r--macros/latex-dev/base/clsguide.tex6
-rw-r--r--macros/latex-dev/base/cmextra.ins4
-rw-r--r--macros/latex-dev/base/cmfonts.fdd2
-rw-r--r--macros/latex-dev/base/cmfonts.ins4
-rw-r--r--macros/latex-dev/base/cmfonts.pdfbin292600 -> 292600 bytes
-rw-r--r--macros/latex-dev/base/cyrguide.pdfbin257359 -> 257359 bytes
-rw-r--r--macros/latex-dev/base/cyrguide.tex2
-rw-r--r--macros/latex-dev/base/doc-code.pdfbin1075915 -> 1078428 bytes
-rw-r--r--macros/latex-dev/base/doc.dtx223
-rw-r--r--macros/latex-dev/base/doc.pdfbin756298 -> 757049 bytes
-rw-r--r--macros/latex-dev/base/docstrip.dtx16
-rw-r--r--macros/latex-dev/base/docstrip.ins4
-rw-r--r--macros/latex-dev/base/docstrip.pdfbin506630 -> 506365 bytes
-rw-r--r--macros/latex-dev/base/ec.ins4
-rw-r--r--macros/latex-dev/base/encguide.pdfbin1318576 -> 1318576 bytes
-rw-r--r--macros/latex-dev/base/encguide.tex2
-rw-r--r--macros/latex-dev/base/exscale.dtx2
-rw-r--r--macros/latex-dev/base/exscale.ins4
-rw-r--r--macros/latex-dev/base/exscale.pdfbin204708 -> 204708 bytes
-rw-r--r--macros/latex-dev/base/fix-cm.dtx2
-rw-r--r--macros/latex-dev/base/fix-cm.ins4
-rw-r--r--macros/latex-dev/base/fix-cm.pdfbin287727 -> 287727 bytes
-rw-r--r--macros/latex-dev/base/fntguide.pdfbin517708 -> 517708 bytes
-rw-r--r--macros/latex-dev/base/fntguide.tex2
-rw-r--r--macros/latex-dev/base/fontdef.dtx32
-rw-r--r--macros/latex-dev/base/format.ins14
-rw-r--r--macros/latex-dev/base/graphpap.dtx2
-rw-r--r--macros/latex-dev/base/graphpap.ins4
-rw-r--r--macros/latex-dev/base/graphpap.pdfbin161722 -> 161722 bytes
-rw-r--r--macros/latex-dev/base/idx.tex2
-rw-r--r--macros/latex-dev/base/ifthen.dtx2
-rw-r--r--macros/latex-dev/base/ifthen.ins4
-rw-r--r--macros/latex-dev/base/ifthen.pdfbin221219 -> 221219 bytes
-rw-r--r--macros/latex-dev/base/inputenc.dtx8
-rw-r--r--macros/latex-dev/base/inputenc.ins4
-rw-r--r--macros/latex-dev/base/inputenc.pdfbin318199 -> 318372 bytes
-rw-r--r--macros/latex-dev/base/lablst.tex2
-rw-r--r--macros/latex-dev/base/lamport-manual.pdfbin170876 -> 170876 bytes
-rw-r--r--macros/latex-dev/base/latex209.dtx2
-rw-r--r--macros/latex-dev/base/latex209.ins4
-rw-r--r--macros/latex-dev/base/latexrelease.dtx2
-rw-r--r--macros/latex-dev/base/latexrelease.ins5
-rw-r--r--macros/latex-dev/base/latexrelease.pdfbin282095 -> 282095 bytes
-rw-r--r--macros/latex-dev/base/latexsym.dtx2
-rw-r--r--macros/latex-dev/base/latexsym.ins6
-rw-r--r--macros/latex-dev/base/latexsym.pdfbin200759 -> 200759 bytes
-rw-r--r--macros/latex-dev/base/lb2.err11
-rw-r--r--macros/latex-dev/base/lb2.pdfbin252497 -> 253116 bytes
-rw-r--r--macros/latex-dev/base/letter.dtx2
-rw-r--r--macros/latex-dev/base/letter.ins4
-rw-r--r--macros/latex-dev/base/letter.pdfbin337852 -> 337772 bytes
-rw-r--r--macros/latex-dev/base/lgc2.pdfbin217659 -> 217659 bytes
-rw-r--r--macros/latex-dev/base/lppl.pdfbin132370 -> 132370 bytes
-rw-r--r--macros/latex-dev/base/ltalloc.dtx2
-rw-r--r--macros/latex-dev/base/ltbibl.dtx2
-rw-r--r--macros/latex-dev/base/ltboxes.dtx9
-rw-r--r--macros/latex-dev/base/ltclass.dtx38
-rw-r--r--macros/latex-dev/base/ltcmd.dtx217
-rw-r--r--macros/latex-dev/base/ltcmdhooks-code.pdfbin755882 -> 752365 bytes
-rw-r--r--macros/latex-dev/base/ltcmdhooks-doc.pdfbin499346 -> 497334 bytes
-rw-r--r--macros/latex-dev/base/ltcmdhooks.dtx24
-rw-r--r--macros/latex-dev/base/ltcntrl.dtx2
-rw-r--r--macros/latex-dev/base/ltcounts.dtx21
-rw-r--r--macros/latex-dev/base/ltdefns.dtx22
-rw-r--r--macros/latex-dev/base/ltdirchk.dtx10
-rw-r--r--macros/latex-dev/base/lterror.dtx2
-rw-r--r--macros/latex-dev/base/ltexpl.dtx2
-rw-r--r--macros/latex-dev/base/ltfilehook-code.pdfbin804030 -> 803049 bytes
-rw-r--r--macros/latex-dev/base/ltfilehook-doc.pdfbin548695 -> 548011 bytes
-rw-r--r--macros/latex-dev/base/ltfilehook.dtx26
-rw-r--r--macros/latex-dev/base/ltfiles.dtx59
-rw-r--r--macros/latex-dev/base/ltfinal.dtx8
-rw-r--r--macros/latex-dev/base/ltfloat.dtx2
-rw-r--r--macros/latex-dev/base/ltfntcmd.dtx10
-rw-r--r--macros/latex-dev/base/ltfssaxes.dtx12
-rw-r--r--macros/latex-dev/base/ltfssbas.dtx6
-rw-r--r--macros/latex-dev/base/ltfsscmp.dtx2
-rw-r--r--macros/latex-dev/base/ltfssdcl.dtx2
-rw-r--r--macros/latex-dev/base/ltfssini.dtx12
-rw-r--r--macros/latex-dev/base/ltfsstrc.dtx25
-rw-r--r--macros/latex-dev/base/lthooks-code.pdfbin1258628 -> 1248644 bytes
-rw-r--r--macros/latex-dev/base/lthooks-doc.pdfbin755246 -> 758273 bytes
-rw-r--r--macros/latex-dev/base/lthooks.dtx403
-rw-r--r--macros/latex-dev/base/lthyphen.dtx2
-rw-r--r--macros/latex-dev/base/ltidxglo.dtx2
-rw-r--r--macros/latex-dev/base/ltkeys.dtx10
-rw-r--r--macros/latex-dev/base/ltlength.dtx2
-rw-r--r--macros/latex-dev/base/ltlists.dtx2
-rw-r--r--macros/latex-dev/base/ltlogos.dtx2
-rw-r--r--macros/latex-dev/base/ltluatex.dtx28
-rw-r--r--macros/latex-dev/base/ltluatex.pdfbin325191 -> 325142 bytes
-rw-r--r--macros/latex-dev/base/ltmarks-code.pdfbin716681 -> 711767 bytes
-rw-r--r--macros/latex-dev/base/ltmarks-doc.pdfbin586808 -> 575242 bytes
-rw-r--r--macros/latex-dev/base/ltmarks.dtx656
-rw-r--r--macros/latex-dev/base/ltmath.dtx2
-rw-r--r--macros/latex-dev/base/ltmeta.dtx15
-rw-r--r--macros/latex-dev/base/ltmiscen.dtx14
-rw-r--r--macros/latex-dev/base/ltnews.cls2
-rw-r--r--macros/latex-dev/base/ltnews.pdfbin1360066 -> 1390205 bytes
-rw-r--r--macros/latex-dev/base/ltnews.tex4
-rw-r--r--macros/latex-dev/base/ltnews01.pdfbin169553 -> 169553 bytes
-rw-r--r--macros/latex-dev/base/ltnews01.tex2
-rw-r--r--macros/latex-dev/base/ltnews02.pdfbin151773 -> 151773 bytes
-rw-r--r--macros/latex-dev/base/ltnews02.tex2
-rw-r--r--macros/latex-dev/base/ltnews03.pdfbin151324 -> 151324 bytes
-rw-r--r--macros/latex-dev/base/ltnews03.tex2
-rw-r--r--macros/latex-dev/base/ltnews04.pdfbin152551 -> 152551 bytes
-rw-r--r--macros/latex-dev/base/ltnews04.tex2
-rw-r--r--macros/latex-dev/base/ltnews05.pdfbin175211 -> 175211 bytes
-rw-r--r--macros/latex-dev/base/ltnews05.tex2
-rw-r--r--macros/latex-dev/base/ltnews06.pdfbin142867 -> 142867 bytes
-rw-r--r--macros/latex-dev/base/ltnews06.tex2
-rw-r--r--macros/latex-dev/base/ltnews07.pdfbin138214 -> 138214 bytes
-rw-r--r--macros/latex-dev/base/ltnews07.tex2
-rw-r--r--macros/latex-dev/base/ltnews08.pdfbin155442 -> 155442 bytes
-rw-r--r--macros/latex-dev/base/ltnews08.tex2
-rw-r--r--macros/latex-dev/base/ltnews09.pdfbin130028 -> 130028 bytes
-rw-r--r--macros/latex-dev/base/ltnews09.tex2
-rw-r--r--macros/latex-dev/base/ltnews10.pdfbin169433 -> 169433 bytes
-rw-r--r--macros/latex-dev/base/ltnews10.tex2
-rw-r--r--macros/latex-dev/base/ltnews11.pdfbin112208 -> 112208 bytes
-rw-r--r--macros/latex-dev/base/ltnews11.tex2
-rw-r--r--macros/latex-dev/base/ltnews12.pdfbin156764 -> 156764 bytes
-rw-r--r--macros/latex-dev/base/ltnews12.tex2
-rw-r--r--macros/latex-dev/base/ltnews13.pdfbin182483 -> 182483 bytes
-rw-r--r--macros/latex-dev/base/ltnews13.tex2
-rw-r--r--macros/latex-dev/base/ltnews14.pdfbin170722 -> 170722 bytes
-rw-r--r--macros/latex-dev/base/ltnews14.tex2
-rw-r--r--macros/latex-dev/base/ltnews15.pdfbin130328 -> 130328 bytes
-rw-r--r--macros/latex-dev/base/ltnews15.tex2
-rw-r--r--macros/latex-dev/base/ltnews16.pdfbin138107 -> 138107 bytes
-rw-r--r--macros/latex-dev/base/ltnews16.tex2
-rw-r--r--macros/latex-dev/base/ltnews17.pdfbin166269 -> 166269 bytes
-rw-r--r--macros/latex-dev/base/ltnews17.tex2
-rw-r--r--macros/latex-dev/base/ltnews18.pdfbin39839 -> 39839 bytes
-rw-r--r--macros/latex-dev/base/ltnews18.tex2
-rw-r--r--macros/latex-dev/base/ltnews19.pdfbin225936 -> 225936 bytes
-rw-r--r--macros/latex-dev/base/ltnews19.tex2
-rw-r--r--macros/latex-dev/base/ltnews20.pdfbin318193 -> 318193 bytes
-rw-r--r--macros/latex-dev/base/ltnews20.tex2
-rw-r--r--macros/latex-dev/base/ltnews21.pdfbin245228 -> 245228 bytes
-rw-r--r--macros/latex-dev/base/ltnews21.tex2
-rw-r--r--macros/latex-dev/base/ltnews22.pdfbin318026 -> 318026 bytes
-rw-r--r--macros/latex-dev/base/ltnews22.tex2
-rw-r--r--macros/latex-dev/base/ltnews23.pdfbin286824 -> 286824 bytes
-rw-r--r--macros/latex-dev/base/ltnews23.tex2
-rw-r--r--macros/latex-dev/base/ltnews24.pdfbin265497 -> 265497 bytes
-rw-r--r--macros/latex-dev/base/ltnews24.tex2
-rw-r--r--macros/latex-dev/base/ltnews25.pdfbin205100 -> 205100 bytes
-rw-r--r--macros/latex-dev/base/ltnews25.tex2
-rw-r--r--macros/latex-dev/base/ltnews26.pdfbin379733 -> 379733 bytes
-rw-r--r--macros/latex-dev/base/ltnews26.tex2
-rw-r--r--macros/latex-dev/base/ltnews27.pdfbin251283 -> 251283 bytes
-rw-r--r--macros/latex-dev/base/ltnews27.tex2
-rw-r--r--macros/latex-dev/base/ltnews28.pdfbin376933 -> 376933 bytes
-rw-r--r--macros/latex-dev/base/ltnews28.tex2
-rw-r--r--macros/latex-dev/base/ltnews29.pdfbin455437 -> 455437 bytes
-rw-r--r--macros/latex-dev/base/ltnews29.tex2
-rw-r--r--macros/latex-dev/base/ltnews30.pdfbin512240 -> 512240 bytes
-rw-r--r--macros/latex-dev/base/ltnews30.tex2
-rw-r--r--macros/latex-dev/base/ltnews31.pdfbin526688 -> 526688 bytes
-rw-r--r--macros/latex-dev/base/ltnews31.tex2
-rw-r--r--macros/latex-dev/base/ltnews32.pdfbin546540 -> 546540 bytes
-rw-r--r--macros/latex-dev/base/ltnews32.tex2
-rw-r--r--macros/latex-dev/base/ltnews33.pdfbin522757 -> 522757 bytes
-rw-r--r--macros/latex-dev/base/ltnews33.tex2
-rw-r--r--macros/latex-dev/base/ltnews34.pdfbin508345 -> 508345 bytes
-rw-r--r--macros/latex-dev/base/ltnews34.tex2
-rw-r--r--macros/latex-dev/base/ltnews35.pdfbin563307 -> 563307 bytes
-rw-r--r--macros/latex-dev/base/ltnews35.tex2
-rw-r--r--macros/latex-dev/base/ltnews36.pdfbin517934 -> 517934 bytes
-rw-r--r--macros/latex-dev/base/ltnews36.tex2
-rw-r--r--macros/latex-dev/base/ltnews37.pdfbin456933 -> 456933 bytes
-rw-r--r--macros/latex-dev/base/ltnews37.tex2
-rw-r--r--macros/latex-dev/base/ltnews38.pdfbin523672 -> 523675 bytes
-rw-r--r--macros/latex-dev/base/ltnews38.tex2
-rw-r--r--macros/latex-dev/base/ltnews39.pdfbin0 -> 473345 bytes
-rw-r--r--macros/latex-dev/base/ltnews39.tex640
-rw-r--r--macros/latex-dev/base/ltoutenc.dtx27
-rw-r--r--macros/latex-dev/base/ltoutenc.ins4
-rw-r--r--macros/latex-dev/base/ltoutput.dtx2
-rw-r--r--macros/latex-dev/base/ltpage.dtx2
-rw-r--r--macros/latex-dev/base/ltpageno.dtx2
-rw-r--r--macros/latex-dev/base/ltpar.dtx2
-rw-r--r--macros/latex-dev/base/ltpara-code.pdfbin672700 -> 672114 bytes
-rw-r--r--macros/latex-dev/base/ltpara-doc.pdfbin560578 -> 560037 bytes
-rw-r--r--macros/latex-dev/base/ltpara.dtx20
-rw-r--r--macros/latex-dev/base/ltpictur.dtx2
-rw-r--r--macros/latex-dev/base/ltplain.dtx22
-rw-r--r--macros/latex-dev/base/ltproperties-code.pdfbin558646 -> 557051 bytes
-rw-r--r--macros/latex-dev/base/ltproperties-doc.pdfbin433141 -> 432129 bytes
-rw-r--r--macros/latex-dev/base/ltproperties.dtx45
-rw-r--r--macros/latex-dev/base/ltsect.dtx2
-rw-r--r--macros/latex-dev/base/ltshipout-code.pdfbin821655 -> 821580 bytes
-rw-r--r--macros/latex-dev/base/ltshipout-doc.pdfbin566566 -> 567728 bytes
-rw-r--r--macros/latex-dev/base/ltshipout.dtx34
-rw-r--r--macros/latex-dev/base/ltsockets-code.pdfbin606454 -> 598937 bytes
-rw-r--r--macros/latex-dev/base/ltsockets-doc.pdfbin489314 -> 481774 bytes
-rw-r--r--macros/latex-dev/base/ltsockets.dtx38
-rw-r--r--macros/latex-dev/base/ltspace.dtx14
-rw-r--r--macros/latex-dev/base/lttab.dtx2
-rw-r--r--macros/latex-dev/base/lttagging.dtx775
-rw-r--r--macros/latex-dev/base/lttemplates.dtx2698
-rw-r--r--macros/latex-dev/base/lttextcomp.dtx677
-rw-r--r--macros/latex-dev/base/ltthm.dtx2
-rw-r--r--macros/latex-dev/base/ltvers.dtx4
-rw-r--r--macros/latex-dev/base/ltx3info.pdfbin219358 -> 219358 bytes
-rw-r--r--macros/latex-dev/base/ltx3info.tex2
-rw-r--r--macros/latex-dev/base/ltxcheck.tex2
-rw-r--r--macros/latex-dev/base/ltxdoc.dtx13
-rw-r--r--macros/latex-dev/base/ltxdoc.pdfbin244215 -> 244141 bytes
-rw-r--r--macros/latex-dev/base/ltxguide.cls2
-rw-r--r--macros/latex-dev/base/ltxref.dtx2
-rw-r--r--macros/latex-dev/base/makeindx.dtx2
-rw-r--r--macros/latex-dev/base/makeindx.ins4
-rw-r--r--macros/latex-dev/base/makeindx.pdfbin165816 -> 165816 bytes
-rw-r--r--macros/latex-dev/base/minimal.cls2
-rw-r--r--macros/latex-dev/base/modguide.pdfbin257825 -> 257825 bytes
-rw-r--r--macros/latex-dev/base/modguide.tex2
-rw-r--r--macros/latex-dev/base/newdc.ins4
-rw-r--r--macros/latex-dev/base/newlfont.dtx2
-rw-r--r--macros/latex-dev/base/nfssfont.dtx8
-rw-r--r--macros/latex-dev/base/nfssfont.ins4
-rw-r--r--macros/latex-dev/base/nfssfont.pdfbin211171 -> 211314 bytes
-rw-r--r--macros/latex-dev/base/olddc.ins4
-rw-r--r--macros/latex-dev/base/oldlfont.dtx2
-rw-r--r--macros/latex-dev/base/preload.dtx2
-rw-r--r--macros/latex-dev/base/proc.dtx2
-rw-r--r--macros/latex-dev/base/proc.ins4
-rw-r--r--macros/latex-dev/base/proc.pdfbin227065 -> 227065 bytes
-rw-r--r--macros/latex-dev/base/slides.dtx2
-rw-r--r--macros/latex-dev/base/slides.ins8
-rw-r--r--macros/latex-dev/base/slides.pdfbin375493 -> 375493 bytes
-rw-r--r--macros/latex-dev/base/slifonts.fdd8
-rw-r--r--macros/latex-dev/base/slifonts.pdfbin234171 -> 233905 bytes
-rw-r--r--macros/latex-dev/base/source2e.pdfbin6150247 -> 6239225 bytes
-rw-r--r--macros/latex-dev/base/source2e.tex6
-rw-r--r--macros/latex-dev/base/source2edoc.cls87
-rw-r--r--macros/latex-dev/base/syntonly.dtx8
-rw-r--r--macros/latex-dev/base/syntonly.ins4
-rw-r--r--macros/latex-dev/base/syntonly.pdfbin190255 -> 189440 bytes
-rw-r--r--macros/latex-dev/base/testpage.tex2
-rw-r--r--macros/latex-dev/base/tlc2.pdfbin291143 -> 291143 bytes
-rw-r--r--macros/latex-dev/base/tlc3.err31
-rw-r--r--macros/latex-dev/base/tlc3.pdfbin326462 -> 345764 bytes
-rw-r--r--macros/latex-dev/base/tulm.fdd2
-rw-r--r--macros/latex-dev/base/tulm.ins4
-rw-r--r--macros/latex-dev/base/tulm.pdfbin162773 -> 162773 bytes
-rw-r--r--macros/latex-dev/base/unpack.ins2
-rw-r--r--macros/latex-dev/base/usrguide-historic.pdfbin438602 -> 439393 bytes
-rw-r--r--macros/latex-dev/base/usrguide-historic.tex8
-rw-r--r--macros/latex-dev/base/usrguide.pdfbin477695 -> 483354 bytes
-rw-r--r--macros/latex-dev/base/usrguide.tex72
-rw-r--r--macros/latex-dev/base/utf8ienc.dtx7
-rw-r--r--macros/latex-dev/base/utf8ienc.pdfbin353655 -> 353399 bytes
-rw-r--r--macros/latex-dev/base/webcomp.err2
-rw-r--r--macros/latex-dev/base/webcomp.pdfbin146199 -> 146197 bytes
270 files changed, 6578 insertions, 1061 deletions
diff --git a/macros/latex-dev/base/README.md b/macros/latex-dev/base/README.md
index fcfee6ef01..ed14347e98 100644
--- a/macros/latex-dev/base/README.md
+++ b/macros/latex-dev/base/README.md
@@ -1,7 +1,7 @@
The LaTeX kernel
================
-Release 2024-06-01 pre-release 0
+Release 2024-06-01 pre-release 1
Overview
--------
diff --git a/macros/latex-dev/base/alltt.dtx b/macros/latex-dev/base/alltt.dtx
index 548b91bcea..4718c004b4 100644
--- a/macros/latex-dev/base/alltt.dtx
+++ b/macros/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/macros/latex-dev/base/alltt.ins b/macros/latex-dev/base/alltt.ins
index 3f40ddc0f0..6d702c1cc7 100644
--- a/macros/latex-dev/base/alltt.ins
+++ b/macros/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/macros/latex-dev/base/alltt.pdf b/macros/latex-dev/base/alltt.pdf
index 074d5b4de9..54c606fcf2 100644
--- a/macros/latex-dev/base/alltt.pdf
+++ b/macros/latex-dev/base/alltt.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cfgguide.pdf b/macros/latex-dev/base/cfgguide.pdf
index 16a9f23b96..2456f57219 100644
--- a/macros/latex-dev/base/cfgguide.pdf
+++ b/macros/latex-dev/base/cfgguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cfgguide.tex b/macros/latex-dev/base/cfgguide.tex
index e0f76b74fb..9b750593c4 100644
--- a/macros/latex-dev/base/cfgguide.tex
+++ b/macros/latex-dev/base/cfgguide.tex
@@ -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/macros/latex-dev/base/changes.txt b/macros/latex-dev/base/changes.txt
index 812143d3e3..dec230e890 100644
--- a/macros/latex-dev/base/changes.txt
+++ b/macros/latex-dev/base/changes.txt
@@ -1,22 +1,133 @@
-================================================================================
-This file lists changes to the LaTeX2e files in reverse chronological order
-of publication (therefore the dates might be out of sequence if there are
-hotfixes). It is provided for convenience only. It therefore makes no claims
-to completeness or accuracy and it contains some references to files that are
-not part of the distribution.
-================================================================================
+================================================================================
+This file lists changes to the LaTeX2e files in reverse chronological order
+of publication (therefore the dates might be out of sequence if there are
+hotfixes). It is provided for convenience only. It therefore makes no claims
+to completeness or accuracy and it contains some references to files that are
+not part of the distribution.
+================================================================================
+
+2024-01-30 David Carlisle <David.Carlisle@latex-project.org>
+ * ltclass.dtx: check that \RequirePackage, \documentclass, \usepackage
+ and related commands are at top level (gh/1185)
+
+2023-11-12 Joseph Wright <Joseph.Wright@latex-project.org>
+ * lttemplates.dtx
+ New file to replace loading xtemplate
+
+2024-01-30 Jérôme Laurens <jerome.laurens@u-bourgogn.fr>
+ * lthooks.dtx:
+ Fix rollback to 2020-10-01.
+
+2024-01-29 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * ltmarks.dtx:
+ Generalized the support for extracting marks to cover cases like multicols.
+
+ Some internal commands renamed and extended.
+ Renamed \__mark_update_structure:nn to \__mark_update_structure_from_material:nn
+ Added \__mark_get_marks_for_reinsertion:nNN
+ Added \ShowMarksAt for debugging (might not stay this way)
+
+2024-01-27 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * lttextcomp.dtx (section{Font family sub-encodings setup}):
+ Adjusted/corrected TS1 sub-encoding declarations for various families.
+ Some families have changed their names (due to licensing issues),
+ some got new glyphs added, and some were simply incorrectly categorized
+ (gh/1257)
+
+ * lttextcomp.dtx (section{The \texttt{checkencodingsubset.tex} file}):
+ Added check file for encoding subset
+
+2024-01-03 Phelype Oleinik <phelype.oleinik@latex-project.org>
+ * lthooks.dtx:
+ Correct expansion of \@@_print_args:nn argument (gh/1221).
+
+2023-12-30 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * doc.dtx (subsection{Macros surrounding the `definition parts'}):
+ Use \@noligs from the LaTeX kernel, so that the upquote
+ package can add its patch (gh/1230)
+
+2023-12-26 Yukai Chou <muzimuzhi@gmai.com>
+ * ltproperties.dtx:
+ Correct typo (gh/1223)
+ * doc.dtx, ltfntcmd.dtx, lthooks.dtx
+ Correct similar typos of missing backslashes
+ * ltfilehook.dtx
+ Change flag markup in macro env
+
+2023-12-22 Yukai Chou <muzimuzhi@gmail.com>
+ * ltcmd.dtx (subsection{Normalizing the argument specifications})
+ Clarify error message when an argument prefix `!' is applied to
+ a non-trailing optional argument. (gh/1198)
+
+2023-12-16 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * lttagging.dtx:
+ First version of lttagging module added
+
+2023-12-07 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * ltproperties.dtx: use \protected@write, (gh1200)
+
+2023-12-02 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * doc.dtx (subsection{API creation}):
+ Provide \ProvideDocElement for use cases where files are processed
+ individually as well as together, e.g., the LaTeX kernel documentation.
+
+2023-12-01 Joseph Wright <Joseph.Wright@latex-project.org>
+ * ltcmd.dtx (subsection{Declaring commands and environments}):
+ Optimize creation of simple document commands (gh/1189)
+ * usrguide.tex (subsection{Performance}):
+ Document efficiency of ltcmd definitions
+
+2023-11-16 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * ltpara.dtx (subsection{Providing hooks for paragraphs}):
+ Correct error message: hook left horizontal not vertical mode (gh/1182)
+
+2023-11-15 Joseph Wright <Joseph.Wright@latex-project.org>
+ * ltfiles.dtx (subsection{Listing files}):
+ Extend \listfiles to optionally include file sizes and hashes
+ * usrguide.tex
+ Re-introduce \listfiles (extended) description
+
+2023-11-09 Yukai Chou <muzimuzhi@gmail.com>
+ * clsguide-historic.tex, usrguide.tex:
+ Replace quotation with quote envs for zero para indent
+
+ * clsguide-historic.tex, usrguide-historic.tex
+ Mention correct source file names in license footnotes
+
+2023-11-07 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * ltoutenc.dtx (subsection{The fontenc package}):
+ Add more explanation to error message about missing encoding (gh/1102)
+
+ * nfssfont.dtx (section{The code}):
+ Corrected spelling in error message.
+
+ * ltcounts.dtx (subsection{Environment Counter Macros}):
+ In \newcounter do not change \the... if already defined (gh/823)
+
+ * ltplain.dtx (section{Plain \TeX}):
+ Set \tracinglostchars to 2 in \tracingnone (gh/549)
================================================================================
All changes above are only part of the development branch for the next release.
================================================================================
#########################
+# 2023-11-01 PL1 Release
+#########################
+
+2024-01-13 Jonathan P. Spratte <jspratte@yahoo.de>
+ * ltkeys.dtx:
+ Trim spaces off key names taken from the raw-lists (gh1238)
+
+#########################
# 2023-11-01 Release
#########################
-2023-10-15 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
- * ltproperties.dtx:
- Add support for pagetarget property.
+2023-10-15 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * ltproperties.dtx:
+ Add support for pagetarget property.
2023-10-26 David Carlisle <David.Carlisle@latex-project.org>
* ltboxes.dtx:
@@ -48,9 +159,9 @@ All changes above are only part of the development branch for the next release.
Explain the steps carried out by the replacement algorithm for @@.
2023-09-13 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
- * ltproperties.dtx:
+ * ltproperties.dtx:
Use \protected@edef for expansion in the LaTeX2e commands.
-
+
2023-09-13 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
* ltproperties.dtx:
Expand consistently the label/property names in the LaTeX2e commands.
@@ -135,7 +246,7 @@ All changes above are only part of the development branch for the next release.
* ltfiles.dtx
Allow for pipes in \input, etc.
-2023-06-16 Phelype Oleinik <Joseph.Wright@latex-project.org>
+2023-06-16 Phelype Oleinik <phelype.oleinik@latex-project.org>
* lthooks.dtx, ltcmdhooks.dtx
Correct some rollback labels and dates.
diff --git a/macros/latex-dev/base/classes.dtx b/macros/latex-dev/base/classes.dtx
index 58690e8375..f7c53f0f71 100644
--- a/macros/latex-dev/base/classes.dtx
+++ b/macros/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/macros/latex-dev/base/classes.ins b/macros/latex-dev/base/classes.ins
index 50a51ea666..7fa35896a4 100644
--- a/macros/latex-dev/base/classes.ins
+++ b/macros/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/macros/latex-dev/base/classes.pdf b/macros/latex-dev/base/classes.pdf
index 6ba6e988b6..c45fd63ac0 100644
--- a/macros/latex-dev/base/classes.pdf
+++ b/macros/latex-dev/base/classes.pdf
Binary files differ
diff --git a/macros/latex-dev/base/clsguide-historic.pdf b/macros/latex-dev/base/clsguide-historic.pdf
index c40cf8d8d7..89df4cf17e 100644
--- a/macros/latex-dev/base/clsguide-historic.pdf
+++ b/macros/latex-dev/base/clsguide-historic.pdf
Binary files differ
diff --git a/macros/latex-dev/base/clsguide-historic.tex b/macros/latex-dev/base/clsguide-historic.tex
index d7a27e3c40..bb5e4b5e96 100644
--- a/macros/latex-dev/base/clsguide-historic.tex
+++ b/macros/latex-dev/base/clsguide-historic.tex
@@ -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.
%
@@ -34,15 +34,15 @@
\title{\LaTeXe~for class and package writers --- historic version}
-\author{Copyright \copyright~1995--2006 The \LaTeX\ Project\\
+\author{Copyright \copyright~1995--2023 The \LaTeX\ Project\\
All rights reserved.%
\footnote{This file 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. See the source
- \texttt{clsguide.tex} for full details.}%
+ \texttt{clsguide-historic.tex} for full details.}%
}
-\date{11 January 2023}
+\date{09 November 2023}
\begin{document}
@@ -1481,7 +1481,7 @@ problem, \LaTeX{} provides two new commands |\MakeUppercase| and
|\MakeLowercase| to do this.
For example:
-\begin{quotation}
+\begin{quote}
\begin{tabular}{rl}
|\uppercase{aBcD\ae\AA\ss\OE}| & \uppercase{aBcD\ae\AA\ss\OE}\\
|\lowercase{aBcD\ae\AA\ss\OE}| & \lowercase{aBcD\ae\AA\ss\OE}\\
@@ -1489,7 +1489,7 @@ For example:
\MakeUppercase{aBcD\ae\AA\ss\OE}\\
|\MakeLowercase{aBcD\ae\AA\ss\OE}| & \MakeLowercase{aBcD\ae\AA\ss\OE}
\end{tabular}
-\end{quotation}
+\end{quote}
The commands |\MakeUppercase| and |\MakeLowercase| themselves are
robust, but they have moving arguments.
diff --git a/macros/latex-dev/base/clsguide.pdf b/macros/latex-dev/base/clsguide.pdf
index c8c14014da..b6146de10e 100644
--- a/macros/latex-dev/base/clsguide.pdf
+++ b/macros/latex-dev/base/clsguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/clsguide.tex b/macros/latex-dev/base/clsguide.tex
index 457f74f287..c23f0a55e9 100644
--- a/macros/latex-dev/base/clsguide.tex
+++ b/macros/latex-dev/base/clsguide.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2023
+% Copyright (C) 2023-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -42,7 +42,7 @@
\texttt{clsguide.tex} for full details.}%
}
-\date{2023-10-24}
+\date{2023-12-02}
\NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
\NewDocumentCommand\marg{m}{\arg{#1}}
@@ -891,7 +891,7 @@ unknown option on to a non-keyval class such as \pkg{article}:
The |\ProcessKeyOptions| function is used to check the current option list
against the keys defined for \m{family}. Global (class) options and local
(package) options are checked when this function is called in a package.
-The command will process \emph{all} options given the the current
+The command will process \emph{all} options given the current
package or class: there is no need to also apply \cs{ProcessOptions}.
\begin{decl}
diff --git a/macros/latex-dev/base/cmextra.ins b/macros/latex-dev/base/cmextra.ins
index 0fa45183fc..3f06c1548b 100644
--- a/macros/latex-dev/base/cmextra.ins
+++ b/macros/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/macros/latex-dev/base/cmfonts.fdd b/macros/latex-dev/base/cmfonts.fdd
index af898e47b2..556db5be81 100644
--- a/macros/latex-dev/base/cmfonts.fdd
+++ b/macros/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/macros/latex-dev/base/cmfonts.ins b/macros/latex-dev/base/cmfonts.ins
index af5ac7e5f8..fb9d08f440 100644
--- a/macros/latex-dev/base/cmfonts.ins
+++ b/macros/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/macros/latex-dev/base/cmfonts.pdf b/macros/latex-dev/base/cmfonts.pdf
index fe88b5af3b..e417fb5389 100644
--- a/macros/latex-dev/base/cmfonts.pdf
+++ b/macros/latex-dev/base/cmfonts.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cyrguide.pdf b/macros/latex-dev/base/cyrguide.pdf
index 5678806510..f9f6644c9a 100644
--- a/macros/latex-dev/base/cyrguide.pdf
+++ b/macros/latex-dev/base/cyrguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cyrguide.tex b/macros/latex-dev/base/cyrguide.tex
index 394cd59e20..9a79a80e59 100644
--- a/macros/latex-dev/base/cyrguide.tex
+++ b/macros/latex-dev/base/cyrguide.tex
@@ -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/macros/latex-dev/base/doc-code.pdf b/macros/latex-dev/base/doc-code.pdf
index 51e6dad9e8..67ab8bf64d 100644
--- a/macros/latex-dev/base/doc-code.pdf
+++ b/macros/latex-dev/base/doc-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/doc.dtx b/macros/latex-dev/base/doc.dtx
index 75e04cc299..82eb8dc5b8 100644
--- a/macros/latex-dev/base/doc.dtx
+++ b/macros/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/macros/latex-dev/base/doc.pdf b/macros/latex-dev/base/doc.pdf
index e8a184011e..1783af35f6 100644
--- a/macros/latex-dev/base/doc.pdf
+++ b/macros/latex-dev/base/doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/docstrip.dtx b/macros/latex-dev/base/docstrip.dtx
index 776d0e68d7..d5366b3fdd 100644
--- a/macros/latex-dev/base/docstrip.dtx
+++ b/macros/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/macros/latex-dev/base/docstrip.ins b/macros/latex-dev/base/docstrip.ins
index 79d4c429dd..6ed99c9223 100644
--- a/macros/latex-dev/base/docstrip.ins
+++ b/macros/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/macros/latex-dev/base/docstrip.pdf b/macros/latex-dev/base/docstrip.pdf
index b87f05e2e8..55e029485c 100644
--- a/macros/latex-dev/base/docstrip.pdf
+++ b/macros/latex-dev/base/docstrip.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ec.ins b/macros/latex-dev/base/ec.ins
index 15a7c3848c..53ea22f957 100644
--- a/macros/latex-dev/base/ec.ins
+++ b/macros/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/macros/latex-dev/base/encguide.pdf b/macros/latex-dev/base/encguide.pdf
index 53e032c97b..3653bc1dbf 100644
--- a/macros/latex-dev/base/encguide.pdf
+++ b/macros/latex-dev/base/encguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/encguide.tex b/macros/latex-dev/base/encguide.tex
index 1a0978267e..11d968d2ea 100644
--- a/macros/latex-dev/base/encguide.tex
+++ b/macros/latex-dev/base/encguide.tex
@@ -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/macros/latex-dev/base/exscale.dtx b/macros/latex-dev/base/exscale.dtx
index 89890a4198..1712d18a26 100644
--- a/macros/latex-dev/base/exscale.dtx
+++ b/macros/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/macros/latex-dev/base/exscale.ins b/macros/latex-dev/base/exscale.ins
index ae75460ee5..38c6aea61e 100644
--- a/macros/latex-dev/base/exscale.ins
+++ b/macros/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/macros/latex-dev/base/exscale.pdf b/macros/latex-dev/base/exscale.pdf
index 0c9dd72583..9fe9e195db 100644
--- a/macros/latex-dev/base/exscale.pdf
+++ b/macros/latex-dev/base/exscale.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fix-cm.dtx b/macros/latex-dev/base/fix-cm.dtx
index 9e39cd192b..09af95dad3 100644
--- a/macros/latex-dev/base/fix-cm.dtx
+++ b/macros/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/macros/latex-dev/base/fix-cm.ins b/macros/latex-dev/base/fix-cm.ins
index 68c6792412..2023ea229c 100644
--- a/macros/latex-dev/base/fix-cm.ins
+++ b/macros/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/macros/latex-dev/base/fix-cm.pdf b/macros/latex-dev/base/fix-cm.pdf
index eb2306a8fe..d1eaa48bd0 100644
--- a/macros/latex-dev/base/fix-cm.pdf
+++ b/macros/latex-dev/base/fix-cm.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fntguide.pdf b/macros/latex-dev/base/fntguide.pdf
index a3c42f9cc3..d6dda9e8e2 100644
--- a/macros/latex-dev/base/fntguide.pdf
+++ b/macros/latex-dev/base/fntguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fntguide.tex b/macros/latex-dev/base/fntguide.tex
index 143956ecc4..7cf5d23981 100644
--- a/macros/latex-dev/base/fntguide.tex
+++ b/macros/latex-dev/base/fntguide.tex
@@ -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/macros/latex-dev/base/fontdef.dtx b/macros/latex-dev/base/fontdef.dtx
index 5e88e55079..281add29ef 100644
--- a/macros/latex-dev/base/fontdef.dtx
+++ b/macros/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/macros/latex-dev/base/format.ins b/macros/latex-dev/base/format.ins
index ba0965004d..e20ff09438 100644
--- a/macros/latex-dev/base/format.ins
+++ b/macros/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/macros/latex-dev/base/graphpap.dtx b/macros/latex-dev/base/graphpap.dtx
index 6b7bc8b822..7d93512b26 100644
--- a/macros/latex-dev/base/graphpap.dtx
+++ b/macros/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/macros/latex-dev/base/graphpap.ins b/macros/latex-dev/base/graphpap.ins
index 43ba83aae3..7898dd2f92 100644
--- a/macros/latex-dev/base/graphpap.ins
+++ b/macros/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/macros/latex-dev/base/graphpap.pdf b/macros/latex-dev/base/graphpap.pdf
index d68b5190cc..2f422e2a84 100644
--- a/macros/latex-dev/base/graphpap.pdf
+++ b/macros/latex-dev/base/graphpap.pdf
Binary files differ
diff --git a/macros/latex-dev/base/idx.tex b/macros/latex-dev/base/idx.tex
index 04c8ef6959..001595bb7d 100644
--- a/macros/latex-dev/base/idx.tex
+++ b/macros/latex-dev/base/idx.tex
@@ -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/macros/latex-dev/base/ifthen.dtx b/macros/latex-dev/base/ifthen.dtx
index aefc4a7666..ef7d8ab398 100644
--- a/macros/latex-dev/base/ifthen.dtx
+++ b/macros/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/macros/latex-dev/base/ifthen.ins b/macros/latex-dev/base/ifthen.ins
index 697a4a38b3..0382d2255e 100644
--- a/macros/latex-dev/base/ifthen.ins
+++ b/macros/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/macros/latex-dev/base/ifthen.pdf b/macros/latex-dev/base/ifthen.pdf
index b7638603ef..d5d09c8f6a 100644
--- a/macros/latex-dev/base/ifthen.pdf
+++ b/macros/latex-dev/base/ifthen.pdf
Binary files differ
diff --git a/macros/latex-dev/base/inputenc.dtx b/macros/latex-dev/base/inputenc.dtx
index 02956a8c07..7ab9713d8e 100644
--- a/macros/latex-dev/base/inputenc.dtx
+++ b/macros/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/macros/latex-dev/base/inputenc.ins b/macros/latex-dev/base/inputenc.ins
index 3857827070..2cfe820673 100644
--- a/macros/latex-dev/base/inputenc.ins
+++ b/macros/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/macros/latex-dev/base/inputenc.pdf b/macros/latex-dev/base/inputenc.pdf
index 6e453b6080..bfa0203fdc 100644
--- a/macros/latex-dev/base/inputenc.pdf
+++ b/macros/latex-dev/base/inputenc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lablst.tex b/macros/latex-dev/base/lablst.tex
index b0a3ac1ab6..961928d5ad 100644
--- a/macros/latex-dev/base/lablst.tex
+++ b/macros/latex-dev/base/lablst.tex
@@ -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/macros/latex-dev/base/lamport-manual.pdf b/macros/latex-dev/base/lamport-manual.pdf
index 704346408a..ae4146963f 100644
--- a/macros/latex-dev/base/lamport-manual.pdf
+++ b/macros/latex-dev/base/lamport-manual.pdf
Binary files differ
diff --git a/macros/latex-dev/base/latex209.dtx b/macros/latex-dev/base/latex209.dtx
index b84564bb55..7e4132665f 100644
--- a/macros/latex-dev/base/latex209.dtx
+++ b/macros/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/macros/latex-dev/base/latex209.ins b/macros/latex-dev/base/latex209.ins
index 0c90fa36ea..9226268c28 100644
--- a/macros/latex-dev/base/latex209.ins
+++ b/macros/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/macros/latex-dev/base/latexrelease.dtx b/macros/latex-dev/base/latexrelease.dtx
index 4abde253e1..eeda0f8d55 100644
--- a/macros/latex-dev/base/latexrelease.dtx
+++ b/macros/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/macros/latex-dev/base/latexrelease.ins b/macros/latex-dev/base/latexrelease.ins
index 93739630e3..89c3b0fc3a 100644
--- a/macros/latex-dev/base/latexrelease.ins
+++ b/macros/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/macros/latex-dev/base/latexrelease.pdf b/macros/latex-dev/base/latexrelease.pdf
index a33f14a625..34a4481bc3 100644
--- a/macros/latex-dev/base/latexrelease.pdf
+++ b/macros/latex-dev/base/latexrelease.pdf
Binary files differ
diff --git a/macros/latex-dev/base/latexsym.dtx b/macros/latex-dev/base/latexsym.dtx
index e4e1559e27..4ad1731589 100644
--- a/macros/latex-dev/base/latexsym.dtx
+++ b/macros/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/macros/latex-dev/base/latexsym.ins b/macros/latex-dev/base/latexsym.ins
index 12d658bca9..874f12cbf7 100644
--- a/macros/latex-dev/base/latexsym.ins
+++ b/macros/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/macros/latex-dev/base/latexsym.pdf b/macros/latex-dev/base/latexsym.pdf
index 76b8b57254..444ae58d37 100644
--- a/macros/latex-dev/base/latexsym.pdf
+++ b/macros/latex-dev/base/latexsym.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lb2.err b/macros/latex-dev/base/lb2.err
index 74c0e222b6..7d22f49814 100644
--- a/macros/latex-dev/base/lb2.err
+++ b/macros/latex-dev/base/lb2.err
@@ -1,4 +1,4 @@
-\newcommand\erratafiledate{2014/09/30}
+\newcommand\erratafiledate{2024/01/03}
\def\comando#1{\texttt{\string#1}}
@@ -1203,6 +1203,14 @@ Streiche den letzten Buchstaben von ausf"uhrliche\u{n}.
\erroronpage{647}{Abs.4, Z.1}{JMa}{2006/03/23}{2}
Streiche den letzten Buchstaben von vertikale\u{r}.
+\erroronpage{649}{Beispiel 10-3-9}{WOs}{2024/01/03}{}
+Das Beispiel verwendet \verb=\frame=, was seinen Inhalt immer auf der
+Zeile positioniert und nicht \verb=\fbox=, was je nach Drehung auch
+unter die Zeile dreht (siehe Beispiel 10.3.10).
+Die Ausgabe ist korrekt aber eher überraschend,
+da der nachfolgende Absatz dann \verb=\fbox= diskutiert und die
+Besonderheit von \verb=\frame= hier nicht erwähnt wird.
+
\erroronpage{649}{Abs.2, Z.8}{FMi/HjG}{2006/10/22}{2}
Ersetze: "`\u{Dieser Punkt} ist in \ldots"' \>
"`\u{Dies} ist in \ldots"'
@@ -1605,6 +1613,7 @@ Die Abkürzung NFSS sollte \textsf{NFSS} geschrieben werden.
\contributor{SZi}{Stefan Ziesemer}
\contributor{TNdz}{Timo Niedenzu}
\contributor{VVo}{Vladimir Volovich}
+\contributor{WOs}{Wolfgang Ostmann}
\contributor{YiL}{Yiannis Lazarides}
\end{multicols}
diff --git a/macros/latex-dev/base/lb2.pdf b/macros/latex-dev/base/lb2.pdf
index 1635d1217d..91a6b37f7d 100644
--- a/macros/latex-dev/base/lb2.pdf
+++ b/macros/latex-dev/base/lb2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/letter.dtx b/macros/latex-dev/base/letter.dtx
index 3e3c36d3d0..4df9e5ead6 100644
--- a/macros/latex-dev/base/letter.dtx
+++ b/macros/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/macros/latex-dev/base/letter.ins b/macros/latex-dev/base/letter.ins
index c522f39e59..72bb25531c 100644
--- a/macros/latex-dev/base/letter.ins
+++ b/macros/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/macros/latex-dev/base/letter.pdf b/macros/latex-dev/base/letter.pdf
index bd800591fc..8eeb8e9c2e 100644
--- a/macros/latex-dev/base/letter.pdf
+++ b/macros/latex-dev/base/letter.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lgc2.pdf b/macros/latex-dev/base/lgc2.pdf
index c4cbbd166e..9abfbe67df 100644
--- a/macros/latex-dev/base/lgc2.pdf
+++ b/macros/latex-dev/base/lgc2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lppl.pdf b/macros/latex-dev/base/lppl.pdf
index 1a7b50860d..880331d70f 100644
--- a/macros/latex-dev/base/lppl.pdf
+++ b/macros/latex-dev/base/lppl.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltalloc.dtx b/macros/latex-dev/base/ltalloc.dtx
index c3498fb9c7..d9d5ebd3be 100644
--- a/macros/latex-dev/base/ltalloc.dtx
+++ b/macros/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/macros/latex-dev/base/ltbibl.dtx b/macros/latex-dev/base/ltbibl.dtx
index 8e34ca685a..37d11a97aa 100644
--- a/macros/latex-dev/base/ltbibl.dtx
+++ b/macros/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/macros/latex-dev/base/ltboxes.dtx b/macros/latex-dev/base/ltboxes.dtx
index d84158c161..a041312cc5 100644
--- a/macros/latex-dev/base/ltboxes.dtx
+++ b/macros/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/macros/latex-dev/base/ltclass.dtx b/macros/latex-dev/base/ltclass.dtx
index bb52148508..c6c0495fca 100644
--- a/macros/latex-dev/base/ltclass.dtx
+++ b/macros/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/macros/latex-dev/base/ltcmd.dtx b/macros/latex-dev/base/ltcmd.dtx
index dcb85a1ae8..1733af5416 100644
--- a/macros/latex-dev/base/ltcmd.dtx
+++ b/macros/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/macros/latex-dev/base/ltcmdhooks-code.pdf b/macros/latex-dev/base/ltcmdhooks-code.pdf
index a48cf808d2..8abe240bae 100644
--- a/macros/latex-dev/base/ltcmdhooks-code.pdf
+++ b/macros/latex-dev/base/ltcmdhooks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltcmdhooks-doc.pdf b/macros/latex-dev/base/ltcmdhooks-doc.pdf
index cdff7b57d7..6424ad0033 100644
--- a/macros/latex-dev/base/ltcmdhooks-doc.pdf
+++ b/macros/latex-dev/base/ltcmdhooks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltcmdhooks.dtx b/macros/latex-dev/base/ltcmdhooks.dtx
index 6f885a2c6c..bb071e629c 100644
--- a/macros/latex-dev/base/ltcmdhooks.dtx
+++ b/macros/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/macros/latex-dev/base/ltcntrl.dtx b/macros/latex-dev/base/ltcntrl.dtx
index 52dcdbf983..fad5bf479e 100644
--- a/macros/latex-dev/base/ltcntrl.dtx
+++ b/macros/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/macros/latex-dev/base/ltcounts.dtx b/macros/latex-dev/base/ltcounts.dtx
index 69025fa479..006486d23b 100644
--- a/macros/latex-dev/base/ltcounts.dtx
+++ b/macros/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/macros/latex-dev/base/ltdefns.dtx b/macros/latex-dev/base/ltdefns.dtx
index 209c4e0fba..4d8368e2c0 100644
--- a/macros/latex-dev/base/ltdefns.dtx
+++ b/macros/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/macros/latex-dev/base/ltdirchk.dtx b/macros/latex-dev/base/ltdirchk.dtx
index 6e02929754..d06f68a706 100644
--- a/macros/latex-dev/base/ltdirchk.dtx
+++ b/macros/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/macros/latex-dev/base/lterror.dtx b/macros/latex-dev/base/lterror.dtx
index 77672168ce..99bdc79e4f 100644
--- a/macros/latex-dev/base/lterror.dtx
+++ b/macros/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/macros/latex-dev/base/ltexpl.dtx b/macros/latex-dev/base/ltexpl.dtx
index 4e5eba550b..4aaf799e32 100644
--- a/macros/latex-dev/base/ltexpl.dtx
+++ b/macros/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/macros/latex-dev/base/ltfilehook-code.pdf b/macros/latex-dev/base/ltfilehook-code.pdf
index 1e3965df67..7bfb51e947 100644
--- a/macros/latex-dev/base/ltfilehook-code.pdf
+++ b/macros/latex-dev/base/ltfilehook-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltfilehook-doc.pdf b/macros/latex-dev/base/ltfilehook-doc.pdf
index f104a35011..3e561cdf3a 100644
--- a/macros/latex-dev/base/ltfilehook-doc.pdf
+++ b/macros/latex-dev/base/ltfilehook-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltfilehook.dtx b/macros/latex-dev/base/ltfilehook.dtx
index ae183bfeb4..831d633eef 100644
--- a/macros/latex-dev/base/ltfilehook.dtx
+++ b/macros/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/macros/latex-dev/base/ltfiles.dtx b/macros/latex-dev/base/ltfiles.dtx
index f079c2cf5b..2e2a8884a0 100644
--- a/macros/latex-dev/base/ltfiles.dtx
+++ b/macros/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/macros/latex-dev/base/ltfinal.dtx b/macros/latex-dev/base/ltfinal.dtx
index 2652f6ce44..648e3e1b8b 100644
--- a/macros/latex-dev/base/ltfinal.dtx
+++ b/macros/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/macros/latex-dev/base/ltfloat.dtx b/macros/latex-dev/base/ltfloat.dtx
index 7247824548..a07e5e81da 100644
--- a/macros/latex-dev/base/ltfloat.dtx
+++ b/macros/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/macros/latex-dev/base/ltfntcmd.dtx b/macros/latex-dev/base/ltfntcmd.dtx
index bb6dbfe75c..097b8f692e 100644
--- a/macros/latex-dev/base/ltfntcmd.dtx
+++ b/macros/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/macros/latex-dev/base/ltfssaxes.dtx b/macros/latex-dev/base/ltfssaxes.dtx
index a0746bd08c..8b5014a4cc 100644
--- a/macros/latex-dev/base/ltfssaxes.dtx
+++ b/macros/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/macros/latex-dev/base/ltfssbas.dtx b/macros/latex-dev/base/ltfssbas.dtx
index fa82bd73bb..df02a5749a 100644
--- a/macros/latex-dev/base/ltfssbas.dtx
+++ b/macros/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/macros/latex-dev/base/ltfsscmp.dtx b/macros/latex-dev/base/ltfsscmp.dtx
index 7bdfe2fd3e..57c94ea688 100644
--- a/macros/latex-dev/base/ltfsscmp.dtx
+++ b/macros/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/macros/latex-dev/base/ltfssdcl.dtx b/macros/latex-dev/base/ltfssdcl.dtx
index c3a743d249..32f9eedf19 100644
--- a/macros/latex-dev/base/ltfssdcl.dtx
+++ b/macros/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/macros/latex-dev/base/ltfssini.dtx b/macros/latex-dev/base/ltfssini.dtx
index 7b43f0228b..255abe03f3 100644
--- a/macros/latex-dev/base/ltfssini.dtx
+++ b/macros/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/macros/latex-dev/base/ltfsstrc.dtx b/macros/latex-dev/base/ltfsstrc.dtx
index be0e6c68cf..4f0e43021a 100644
--- a/macros/latex-dev/base/ltfsstrc.dtx
+++ b/macros/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/macros/latex-dev/base/lthooks-code.pdf b/macros/latex-dev/base/lthooks-code.pdf
index 61e9f4a92a..1ebe678058 100644
--- a/macros/latex-dev/base/lthooks-code.pdf
+++ b/macros/latex-dev/base/lthooks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lthooks-doc.pdf b/macros/latex-dev/base/lthooks-doc.pdf
index 4cd9279439..8dc6df576d 100644
--- a/macros/latex-dev/base/lthooks-doc.pdf
+++ b/macros/latex-dev/base/lthooks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lthooks.dtx b/macros/latex-dev/base/lthooks.dtx
index 20d48730c4..ea337d306d 100644
--- a/macros/latex-dev/base/lthooks.dtx
+++ b/macros/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/macros/latex-dev/base/lthyphen.dtx b/macros/latex-dev/base/lthyphen.dtx
index 88d30c9cca..ae1e2182aa 100644
--- a/macros/latex-dev/base/lthyphen.dtx
+++ b/macros/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/macros/latex-dev/base/ltidxglo.dtx b/macros/latex-dev/base/ltidxglo.dtx
index a2dc6b873e..25b8dd12e9 100644
--- a/macros/latex-dev/base/ltidxglo.dtx
+++ b/macros/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/macros/latex-dev/base/ltkeys.dtx b/macros/latex-dev/base/ltkeys.dtx
index 80c36d5cd9..da8340ea9d 100644
--- a/macros/latex-dev/base/ltkeys.dtx
+++ b/macros/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/macros/latex-dev/base/ltlength.dtx b/macros/latex-dev/base/ltlength.dtx
index 10e4b671c8..c81e6edfb7 100644
--- a/macros/latex-dev/base/ltlength.dtx
+++ b/macros/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/macros/latex-dev/base/ltlists.dtx b/macros/latex-dev/base/ltlists.dtx
index d43df93a54..8d4c25d916 100644
--- a/macros/latex-dev/base/ltlists.dtx
+++ b/macros/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/macros/latex-dev/base/ltlogos.dtx b/macros/latex-dev/base/ltlogos.dtx
index 7589cf36e1..4fc710ba40 100644
--- a/macros/latex-dev/base/ltlogos.dtx
+++ b/macros/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/macros/latex-dev/base/ltluatex.dtx b/macros/latex-dev/base/ltluatex.dtx
index 6d274ed5c3..a15019dcd5 100644
--- a/macros/latex-dev/base/ltluatex.dtx
+++ b/macros/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/macros/latex-dev/base/ltluatex.pdf b/macros/latex-dev/base/ltluatex.pdf
index ca793006b1..230cb6527a 100644
--- a/macros/latex-dev/base/ltluatex.pdf
+++ b/macros/latex-dev/base/ltluatex.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltmarks-code.pdf b/macros/latex-dev/base/ltmarks-code.pdf
index 655e71aa4c..2bbd5ea3a0 100644
--- a/macros/latex-dev/base/ltmarks-code.pdf
+++ b/macros/latex-dev/base/ltmarks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltmarks-doc.pdf b/macros/latex-dev/base/ltmarks-doc.pdf
index c5ccd21606..e580cd3319 100644
--- a/macros/latex-dev/base/ltmarks-doc.pdf
+++ b/macros/latex-dev/base/ltmarks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltmarks.dtx b/macros/latex-dev/base/ltmarks.dtx
index 677534dd27..dcfa2fcb27 100644
--- a/macros/latex-dev/base/ltmarks.dtx
+++ b/macros/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/macros/latex-dev/base/ltmath.dtx b/macros/latex-dev/base/ltmath.dtx
index 3b1518dd2e..b40faa8a80 100644
--- a/macros/latex-dev/base/ltmath.dtx
+++ b/macros/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/macros/latex-dev/base/ltmeta.dtx b/macros/latex-dev/base/ltmeta.dtx
index daaa71626b..1e4bdaed2c 100644
--- a/macros/latex-dev/base/ltmeta.dtx
+++ b/macros/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/macros/latex-dev/base/ltmiscen.dtx b/macros/latex-dev/base/ltmiscen.dtx
index 74a9685f1f..accdac24b2 100644
--- a/macros/latex-dev/base/ltmiscen.dtx
+++ b/macros/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/macros/latex-dev/base/ltnews.cls b/macros/latex-dev/base/ltnews.cls
index 45ee3664d1..fa86ce17b7 100644
--- a/macros/latex-dev/base/ltnews.cls
+++ b/macros/latex-dev/base/ltnews.cls
@@ -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/macros/latex-dev/base/ltnews.pdf b/macros/latex-dev/base/ltnews.pdf
index b6fc97ce53..d35b824b96 100644
--- a/macros/latex-dev/base/ltnews.pdf
+++ b/macros/latex-dev/base/ltnews.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews.tex b/macros/latex-dev/base/ltnews.tex
index 0cb6ad55cc..d4a6d274ae 100644
--- a/macros/latex-dev/base/ltnews.tex
+++ b/macros/latex-dev/base/ltnews.tex
@@ -1,7 +1,7 @@
% \iffalse meta-comment
%
% Copyright (C) 2006, 2009, 2011, 2014 Heiko Oberdiek
-% Copyright (C) 2014-2023
+% Copyright (C) 2014-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -40,7 +40,7 @@
\ProvidesFile{ltnews.tex}%
[2022/06/10 v1.4e Master file for ltnews*.tex (LaTeX Project)]
-\providecommand*{\lastissue}{38}
+\providecommand*{\lastissue}{39}
\InputIfFileExists{ltnews-lastissue.cfg}{}{}
diff --git a/macros/latex-dev/base/ltnews01.pdf b/macros/latex-dev/base/ltnews01.pdf
index a7eb8b72ac..119150dcf2 100644
--- a/macros/latex-dev/base/ltnews01.pdf
+++ b/macros/latex-dev/base/ltnews01.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews01.tex b/macros/latex-dev/base/ltnews01.tex
index 55c6b20dd6..5c46b0450e 100644
--- a/macros/latex-dev/base/ltnews01.tex
+++ b/macros/latex-dev/base/ltnews01.tex
@@ -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/macros/latex-dev/base/ltnews02.pdf b/macros/latex-dev/base/ltnews02.pdf
index 1560d5cfae..c549274162 100644
--- a/macros/latex-dev/base/ltnews02.pdf
+++ b/macros/latex-dev/base/ltnews02.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews02.tex b/macros/latex-dev/base/ltnews02.tex
index 58856fe97b..d91af6f8b1 100644
--- a/macros/latex-dev/base/ltnews02.tex
+++ b/macros/latex-dev/base/ltnews02.tex
@@ -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/macros/latex-dev/base/ltnews03.pdf b/macros/latex-dev/base/ltnews03.pdf
index a33ab0d699..525e896caa 100644
--- a/macros/latex-dev/base/ltnews03.pdf
+++ b/macros/latex-dev/base/ltnews03.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews03.tex b/macros/latex-dev/base/ltnews03.tex
index 96a5bec428..22533b9fae 100644
--- a/macros/latex-dev/base/ltnews03.tex
+++ b/macros/latex-dev/base/ltnews03.tex
@@ -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/macros/latex-dev/base/ltnews04.pdf b/macros/latex-dev/base/ltnews04.pdf
index 0fe86c8d1c..759e78dec7 100644
--- a/macros/latex-dev/base/ltnews04.pdf
+++ b/macros/latex-dev/base/ltnews04.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews04.tex b/macros/latex-dev/base/ltnews04.tex
index ab49d7ade3..c1b474bca6 100644
--- a/macros/latex-dev/base/ltnews04.tex
+++ b/macros/latex-dev/base/ltnews04.tex
@@ -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/macros/latex-dev/base/ltnews05.pdf b/macros/latex-dev/base/ltnews05.pdf
index 16be61db08..63b9af2498 100644
--- a/macros/latex-dev/base/ltnews05.pdf
+++ b/macros/latex-dev/base/ltnews05.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews05.tex b/macros/latex-dev/base/ltnews05.tex
index cdfe8bc072..3254b428e3 100644
--- a/macros/latex-dev/base/ltnews05.tex
+++ b/macros/latex-dev/base/ltnews05.tex
@@ -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/macros/latex-dev/base/ltnews06.pdf b/macros/latex-dev/base/ltnews06.pdf
index 62f27b9c09..c3a5d736c7 100644
--- a/macros/latex-dev/base/ltnews06.pdf
+++ b/macros/latex-dev/base/ltnews06.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews06.tex b/macros/latex-dev/base/ltnews06.tex
index 3d5cadb745..9830e55055 100644
--- a/macros/latex-dev/base/ltnews06.tex
+++ b/macros/latex-dev/base/ltnews06.tex
@@ -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/macros/latex-dev/base/ltnews07.pdf b/macros/latex-dev/base/ltnews07.pdf
index 41696cd5b2..5906a1d278 100644
--- a/macros/latex-dev/base/ltnews07.pdf
+++ b/macros/latex-dev/base/ltnews07.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews07.tex b/macros/latex-dev/base/ltnews07.tex
index 43cf204fed..75bbaba715 100644
--- a/macros/latex-dev/base/ltnews07.tex
+++ b/macros/latex-dev/base/ltnews07.tex
@@ -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/macros/latex-dev/base/ltnews08.pdf b/macros/latex-dev/base/ltnews08.pdf
index d3824fd033..093798a6eb 100644
--- a/macros/latex-dev/base/ltnews08.pdf
+++ b/macros/latex-dev/base/ltnews08.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews08.tex b/macros/latex-dev/base/ltnews08.tex
index f1386a5332..540e14c33f 100644
--- a/macros/latex-dev/base/ltnews08.tex
+++ b/macros/latex-dev/base/ltnews08.tex
@@ -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/macros/latex-dev/base/ltnews09.pdf b/macros/latex-dev/base/ltnews09.pdf
index ee50c517ad..18344161cc 100644
--- a/macros/latex-dev/base/ltnews09.pdf
+++ b/macros/latex-dev/base/ltnews09.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews09.tex b/macros/latex-dev/base/ltnews09.tex
index 26eccedd1e..6b932f8f3e 100644
--- a/macros/latex-dev/base/ltnews09.tex
+++ b/macros/latex-dev/base/ltnews09.tex
@@ -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/macros/latex-dev/base/ltnews10.pdf b/macros/latex-dev/base/ltnews10.pdf
index 8aa002886a..d993b06982 100644
--- a/macros/latex-dev/base/ltnews10.pdf
+++ b/macros/latex-dev/base/ltnews10.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews10.tex b/macros/latex-dev/base/ltnews10.tex
index b011eacf7e..e4925794d5 100644
--- a/macros/latex-dev/base/ltnews10.tex
+++ b/macros/latex-dev/base/ltnews10.tex
@@ -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/macros/latex-dev/base/ltnews11.pdf b/macros/latex-dev/base/ltnews11.pdf
index 799f3e69a8..4bd344ad0c 100644
--- a/macros/latex-dev/base/ltnews11.pdf
+++ b/macros/latex-dev/base/ltnews11.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews11.tex b/macros/latex-dev/base/ltnews11.tex
index 07dbd64240..70810e7b09 100644
--- a/macros/latex-dev/base/ltnews11.tex
+++ b/macros/latex-dev/base/ltnews11.tex
@@ -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/macros/latex-dev/base/ltnews12.pdf b/macros/latex-dev/base/ltnews12.pdf
index 3017fe26b4..8b19a4a371 100644
--- a/macros/latex-dev/base/ltnews12.pdf
+++ b/macros/latex-dev/base/ltnews12.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews12.tex b/macros/latex-dev/base/ltnews12.tex
index 38ea9122a0..92d484333c 100644
--- a/macros/latex-dev/base/ltnews12.tex
+++ b/macros/latex-dev/base/ltnews12.tex
@@ -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/macros/latex-dev/base/ltnews13.pdf b/macros/latex-dev/base/ltnews13.pdf
index a471304672..15fd4203d8 100644
--- a/macros/latex-dev/base/ltnews13.pdf
+++ b/macros/latex-dev/base/ltnews13.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews13.tex b/macros/latex-dev/base/ltnews13.tex
index e489b4ff27..278bec28b0 100644
--- a/macros/latex-dev/base/ltnews13.tex
+++ b/macros/latex-dev/base/ltnews13.tex
@@ -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/macros/latex-dev/base/ltnews14.pdf b/macros/latex-dev/base/ltnews14.pdf
index 58c7faeed3..8d615e493d 100644
--- a/macros/latex-dev/base/ltnews14.pdf
+++ b/macros/latex-dev/base/ltnews14.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews14.tex b/macros/latex-dev/base/ltnews14.tex
index 44cc44647e..2d767890e0 100644
--- a/macros/latex-dev/base/ltnews14.tex
+++ b/macros/latex-dev/base/ltnews14.tex
@@ -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/macros/latex-dev/base/ltnews15.pdf b/macros/latex-dev/base/ltnews15.pdf
index a4ccdfcf6a..7c3c35bdc7 100644
--- a/macros/latex-dev/base/ltnews15.pdf
+++ b/macros/latex-dev/base/ltnews15.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews15.tex b/macros/latex-dev/base/ltnews15.tex
index b95801dd6e..9e281e8e0e 100644
--- a/macros/latex-dev/base/ltnews15.tex
+++ b/macros/latex-dev/base/ltnews15.tex
@@ -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/macros/latex-dev/base/ltnews16.pdf b/macros/latex-dev/base/ltnews16.pdf
index 6fbbe159aa..01c228be83 100644
--- a/macros/latex-dev/base/ltnews16.pdf
+++ b/macros/latex-dev/base/ltnews16.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews16.tex b/macros/latex-dev/base/ltnews16.tex
index 7edf8a7f53..8606cffe99 100644
--- a/macros/latex-dev/base/ltnews16.tex
+++ b/macros/latex-dev/base/ltnews16.tex
@@ -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/macros/latex-dev/base/ltnews17.pdf b/macros/latex-dev/base/ltnews17.pdf
index fe38f79c39..3dcf8679dc 100644
--- a/macros/latex-dev/base/ltnews17.pdf
+++ b/macros/latex-dev/base/ltnews17.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews17.tex b/macros/latex-dev/base/ltnews17.tex
index e18e4660eb..8af30edac8 100644
--- a/macros/latex-dev/base/ltnews17.tex
+++ b/macros/latex-dev/base/ltnews17.tex
@@ -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/macros/latex-dev/base/ltnews18.pdf b/macros/latex-dev/base/ltnews18.pdf
index 404206d928..f2533985c9 100644
--- a/macros/latex-dev/base/ltnews18.pdf
+++ b/macros/latex-dev/base/ltnews18.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews18.tex b/macros/latex-dev/base/ltnews18.tex
index 8c70621534..5bca87ddd1 100644
--- a/macros/latex-dev/base/ltnews18.tex
+++ b/macros/latex-dev/base/ltnews18.tex
@@ -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/macros/latex-dev/base/ltnews19.pdf b/macros/latex-dev/base/ltnews19.pdf
index 3f107c4567..0d73b8b4dd 100644
--- a/macros/latex-dev/base/ltnews19.pdf
+++ b/macros/latex-dev/base/ltnews19.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews19.tex b/macros/latex-dev/base/ltnews19.tex
index 7e9492a8f2..5a18300cc2 100644
--- a/macros/latex-dev/base/ltnews19.tex
+++ b/macros/latex-dev/base/ltnews19.tex
@@ -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/macros/latex-dev/base/ltnews20.pdf b/macros/latex-dev/base/ltnews20.pdf
index 8eeacf2590..dd9fe8fb37 100644
--- a/macros/latex-dev/base/ltnews20.pdf
+++ b/macros/latex-dev/base/ltnews20.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews20.tex b/macros/latex-dev/base/ltnews20.tex
index b233f92dc4..6d31e1f56c 100644
--- a/macros/latex-dev/base/ltnews20.tex
+++ b/macros/latex-dev/base/ltnews20.tex
@@ -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/macros/latex-dev/base/ltnews21.pdf b/macros/latex-dev/base/ltnews21.pdf
index 0b70907056..4e58f50dd4 100644
--- a/macros/latex-dev/base/ltnews21.pdf
+++ b/macros/latex-dev/base/ltnews21.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews21.tex b/macros/latex-dev/base/ltnews21.tex
index a48cd0b199..16319e56d7 100644
--- a/macros/latex-dev/base/ltnews21.tex
+++ b/macros/latex-dev/base/ltnews21.tex
@@ -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/macros/latex-dev/base/ltnews22.pdf b/macros/latex-dev/base/ltnews22.pdf
index 60862afc61..013d7190fa 100644
--- a/macros/latex-dev/base/ltnews22.pdf
+++ b/macros/latex-dev/base/ltnews22.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews22.tex b/macros/latex-dev/base/ltnews22.tex
index dfc2e2326a..4a5f70bdb6 100644
--- a/macros/latex-dev/base/ltnews22.tex
+++ b/macros/latex-dev/base/ltnews22.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews23.pdf b/macros/latex-dev/base/ltnews23.pdf
index abf6218395..5a149714d3 100644
--- a/macros/latex-dev/base/ltnews23.pdf
+++ b/macros/latex-dev/base/ltnews23.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews23.tex b/macros/latex-dev/base/ltnews23.tex
index ee75a6463e..6eaaa08fd6 100644
--- a/macros/latex-dev/base/ltnews23.tex
+++ b/macros/latex-dev/base/ltnews23.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews24.pdf b/macros/latex-dev/base/ltnews24.pdf
index 2a8294b46a..8a065321dc 100644
--- a/macros/latex-dev/base/ltnews24.pdf
+++ b/macros/latex-dev/base/ltnews24.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews24.tex b/macros/latex-dev/base/ltnews24.tex
index 6a50ef902c..d34669098a 100644
--- a/macros/latex-dev/base/ltnews24.tex
+++ b/macros/latex-dev/base/ltnews24.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews25.pdf b/macros/latex-dev/base/ltnews25.pdf
index 3b2fcf4928..818b9b84c8 100644
--- a/macros/latex-dev/base/ltnews25.pdf
+++ b/macros/latex-dev/base/ltnews25.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews25.tex b/macros/latex-dev/base/ltnews25.tex
index 0676220a2e..4a168fee7b 100644
--- a/macros/latex-dev/base/ltnews25.tex
+++ b/macros/latex-dev/base/ltnews25.tex
@@ -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/macros/latex-dev/base/ltnews26.pdf b/macros/latex-dev/base/ltnews26.pdf
index 55d618bb30..1f5e0d6eee 100644
--- a/macros/latex-dev/base/ltnews26.pdf
+++ b/macros/latex-dev/base/ltnews26.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews26.tex b/macros/latex-dev/base/ltnews26.tex
index 9fbb6716b1..7ce1b7bd14 100644
--- a/macros/latex-dev/base/ltnews26.tex
+++ b/macros/latex-dev/base/ltnews26.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2017-2023
+% Copyright (C) 2017-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/macros/latex-dev/base/ltnews27.pdf b/macros/latex-dev/base/ltnews27.pdf
index 244be0a0bd..5e5115fab5 100644
--- a/macros/latex-dev/base/ltnews27.pdf
+++ b/macros/latex-dev/base/ltnews27.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews27.tex b/macros/latex-dev/base/ltnews27.tex
index 917bf1cc10..44407da76f 100644
--- a/macros/latex-dev/base/ltnews27.tex
+++ b/macros/latex-dev/base/ltnews27.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2017-2023
+% Copyright (C) 2017-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/macros/latex-dev/base/ltnews28.pdf b/macros/latex-dev/base/ltnews28.pdf
index 9536e57f5a..173d27b6f6 100644
--- a/macros/latex-dev/base/ltnews28.pdf
+++ b/macros/latex-dev/base/ltnews28.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews28.tex b/macros/latex-dev/base/ltnews28.tex
index 3c3b92da97..fec5c5c6c9 100644
--- a/macros/latex-dev/base/ltnews28.tex
+++ b/macros/latex-dev/base/ltnews28.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2017-2023
+% Copyright (C) 2017-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/macros/latex-dev/base/ltnews29.pdf b/macros/latex-dev/base/ltnews29.pdf
index 6ac0eb8b97..306556f994 100644
--- a/macros/latex-dev/base/ltnews29.pdf
+++ b/macros/latex-dev/base/ltnews29.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews29.tex b/macros/latex-dev/base/ltnews29.tex
index 999836b01d..b201c49180 100644
--- a/macros/latex-dev/base/ltnews29.tex
+++ b/macros/latex-dev/base/ltnews29.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2018-2023
+% Copyright (C) 2018-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
diff --git a/macros/latex-dev/base/ltnews30.pdf b/macros/latex-dev/base/ltnews30.pdf
index ad5fb53b4c..815eaf3072 100644
--- a/macros/latex-dev/base/ltnews30.pdf
+++ b/macros/latex-dev/base/ltnews30.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews30.tex b/macros/latex-dev/base/ltnews30.tex
index 8183f7eabb..97d2e9d890 100644
--- a/macros/latex-dev/base/ltnews30.tex
+++ b/macros/latex-dev/base/ltnews30.tex
@@ -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/macros/latex-dev/base/ltnews31.pdf b/macros/latex-dev/base/ltnews31.pdf
index 4a6484d05b..dff2439d12 100644
--- a/macros/latex-dev/base/ltnews31.pdf
+++ b/macros/latex-dev/base/ltnews31.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews31.tex b/macros/latex-dev/base/ltnews31.tex
index 44bf494142..194791cff5 100644
--- a/macros/latex-dev/base/ltnews31.tex
+++ b/macros/latex-dev/base/ltnews31.tex
@@ -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/macros/latex-dev/base/ltnews32.pdf b/macros/latex-dev/base/ltnews32.pdf
index 1964d6203a..f2e80722ec 100644
--- a/macros/latex-dev/base/ltnews32.pdf
+++ b/macros/latex-dev/base/ltnews32.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews32.tex b/macros/latex-dev/base/ltnews32.tex
index c64cd97958..ccc5feff77 100644
--- a/macros/latex-dev/base/ltnews32.tex
+++ b/macros/latex-dev/base/ltnews32.tex
@@ -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/macros/latex-dev/base/ltnews33.pdf b/macros/latex-dev/base/ltnews33.pdf
index 6d8f5775e9..0bc0b4a0fc 100644
--- a/macros/latex-dev/base/ltnews33.pdf
+++ b/macros/latex-dev/base/ltnews33.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews33.tex b/macros/latex-dev/base/ltnews33.tex
index 0b98a707ba..83e8a90c44 100644
--- a/macros/latex-dev/base/ltnews33.tex
+++ b/macros/latex-dev/base/ltnews33.tex
@@ -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/macros/latex-dev/base/ltnews34.pdf b/macros/latex-dev/base/ltnews34.pdf
index 3985ff0d5e..fa2a374667 100644
--- a/macros/latex-dev/base/ltnews34.pdf
+++ b/macros/latex-dev/base/ltnews34.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews34.tex b/macros/latex-dev/base/ltnews34.tex
index d3a9202b56..889531fe78 100644
--- a/macros/latex-dev/base/ltnews34.tex
+++ b/macros/latex-dev/base/ltnews34.tex
@@ -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/macros/latex-dev/base/ltnews35.pdf b/macros/latex-dev/base/ltnews35.pdf
index 820f6a341b..83e8307de1 100644
--- a/macros/latex-dev/base/ltnews35.pdf
+++ b/macros/latex-dev/base/ltnews35.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews35.tex b/macros/latex-dev/base/ltnews35.tex
index 8d49bf1984..8f0c9d6ae3 100644
--- a/macros/latex-dev/base/ltnews35.tex
+++ b/macros/latex-dev/base/ltnews35.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews36.pdf b/macros/latex-dev/base/ltnews36.pdf
index 4c2d70661f..35e707fe85 100644
--- a/macros/latex-dev/base/ltnews36.pdf
+++ b/macros/latex-dev/base/ltnews36.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews36.tex b/macros/latex-dev/base/ltnews36.tex
index 5dee958747..fdd830d870 100644
--- a/macros/latex-dev/base/ltnews36.tex
+++ b/macros/latex-dev/base/ltnews36.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews37.pdf b/macros/latex-dev/base/ltnews37.pdf
index 3ff2725b4d..c63805f098 100644
--- a/macros/latex-dev/base/ltnews37.pdf
+++ b/macros/latex-dev/base/ltnews37.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews37.tex b/macros/latex-dev/base/ltnews37.tex
index 3adda3ea90..1efb0a5127 100644
--- a/macros/latex-dev/base/ltnews37.tex
+++ b/macros/latex-dev/base/ltnews37.tex
@@ -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.
%
diff --git a/macros/latex-dev/base/ltnews38.pdf b/macros/latex-dev/base/ltnews38.pdf
index 80ff1a2127..9693e62fef 100644
--- a/macros/latex-dev/base/ltnews38.pdf
+++ b/macros/latex-dev/base/ltnews38.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews38.tex b/macros/latex-dev/base/ltnews38.tex
index 04ffe1a0ed..bf485de239 100644
--- a/macros/latex-dev/base/ltnews38.tex
+++ b/macros/latex-dev/base/ltnews38.tex
@@ -177,7 +177,7 @@ and \pkg{biblatex}.
For now activation is done through the line
\begin{verbatim}
\DocumentMetadata
- {testphase={phase-III,math,tabular}}
+ {testphase={phase-III,math,table}}
\end{verbatim}
The math and the tabular support are not yet incorporated into
\texttt{phase-III} but need their own activation, so that we can
diff --git a/macros/latex-dev/base/ltnews39.pdf b/macros/latex-dev/base/ltnews39.pdf
new file mode 100644
index 0000000000..f43f43a067
--- /dev/null
+++ b/macros/latex-dev/base/ltnews39.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews39.tex b/macros/latex-dev/base/ltnews39.tex
new file mode 100644
index 0000000000..b4b93d3504
--- /dev/null
+++ b/macros/latex-dev/base/ltnews39.tex
@@ -0,0 +1,640 @@
+% \iffalse meta-comment
+%
+% Copyright 2023
+% 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
+% Filename: ltnews39.tex
+%
+% This is issue 39 of LaTeX News.
+
+\NeedsTeXFormat{LaTeX2e}[2020-02-02]
+
+\documentclass{ltnews}
+
+%% Maybe needed only for Chris' inadequate system:
+\providecommand\Dash {\unskip \textemdash}
+
+%% NOTE: Chris' preferred hyphens!
+%%\showhyphens{parameters}
+%% \hyphenation{because parameters parameter}
+
+\usepackage[T1]{fontenc}
+
+\usepackage{lmodern,url,hologo}
+
+\usepackage{csquotes}
+\usepackage{multicol}
+\usepackage{color}
+
+\providecommand\hook[1]{\texttt{#1}}
+
+\providecommand\meta[1]{$\langle$\textrm{\itshape#1}$\rangle$}
+\providecommand\option[1]{\texttt{#1}}
+\providecommand\env[1]{\texttt{#1}}
+\providecommand\Arg[1]{\texttt\{\meta{#1}\texttt\}}
+
+
+\providecommand\eTeX{\hologo{eTeX}}
+\providecommand\XeTeX{\hologo{XeTeX}}
+\providecommand\LuaTeX{\hologo{LuaTeX}}
+\providecommand\pdfTeX{\hologo{pdfTeX}}
+\providecommand\MiKTeX{\hologo{MiKTeX}}
+\providecommand\CTAN{\textsc{ctan}}
+\providecommand\TL{\TeX\,Live}
+\providecommand\githubissue[2][]{\ifhmode\unskip\fi
+ \quad\penalty500\strut\nobreak\hfill
+ \mbox{\small\slshape(%
+ \href{https://github.com/latex3/latex2e/issues/\getfirstgithubissue#2 \relax}%
+ {github issue#1 #2}%
+ )}%
+ \par\smallskip}
+%% But Chris has to mostly disable \href for his TEXPAD app:
+%% \def\href #1{} % Only For Chris' deficient TeX engine
+
+% simple solution right now (just link to the first issue if there are more)
+\def\getfirstgithubissue#1 #2\relax{#1}
+
+\providecommand\sxissue[1]{\ifhmode\unskip
+ \else
+ % githubissue preceding
+ \vskip-\smallskipamount
+ \vskip-\parskip
+ \fi
+ \quad\penalty500\strut\nobreak\hfill
+ \mbox{\small\slshape(\url{https://tex.stackexchange.com/#1})}\par}
+
+\providecommand\gnatsissue[2]{\ifhmode\unskip\fi
+ \quad\penalty500\strut\nobreak\hfill
+ \mbox{\small\slshape(%
+ \href{https://www.latex-project.org/cgi-bin/ltxbugs2html?pr=#1\%2F\getfirstgithubissue#2 \relax}%
+ {gnats issue #1/#2}%
+ )}%
+ \par}
+
+\let\cls\pkg
+\providecommand\env[1]{\texttt{#1}}
+\providecommand\acro[1]{\textsc{#1}}
+
+\vbadness=1400 % accept slightly empty columns
+
+
+\let\finalpagebreak\pagebreak % for TUB (if they use it)
+
+\makeatletter
+% maybe not the greatest design but normally we wouldn't have subsubsections
+\renewcommand{\subsubsection}{%
+ \@startsection {subsubsection}{2}{0pt}{1.5ex \@plus 1ex \@minus .2ex}%
+ {-1em}{\@subheadingfont\colonize}%
+}
+\providecommand\colonize[1]{#1:}
+\makeatother
+
+\let\finalvspace\vspace % for document layout fixes
+
+% Undo ltnews's \verbatim@font with active < and >
+\makeatletter
+\def\verbatim@font{%
+ \normalsize\ttfamily}
+\makeatletter
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\providecommand\tubcommand[1]{}
+\tubcommand{\input{tubltmac}}
+
+\publicationmonth{June}
+\publicationyear{2024 --- DRAFT version for upcoming release}
+%\publicationyear{2024}
+
+\publicationissue{39}
+
+\begin{document}
+
+\tubcommand{\addtolength\textheight{4.2pc}} % only for TUB
+
+\maketitle
+{\hyphenpenalty=10000 \exhyphenpenalty=10000 \spaceskip=3.33pt \hbadness=10000
+\tableofcontents}
+
+\setlength\rightskip{0pt plus 3em}
+
+\medskip
+
+\section{Introduction}
+
+\emph{to write}
+
+
+\section{News from the \enquote{\LaTeX{} Tagged PDF} project}
+
+In the previous \LaTeX{} News~\cite{39:ltnews38} we announced a first prototype
+support for tagged tabulars. Some of the necessary support code has
+now been moved from \texttt{latex-lab} to the corresponding packages
+(using sockets and plugs) and to the \LaTeX{} kernel (for those parts
+that are also necessary for other aspects of tagging).
+
+The kernel code specific to tagging is implemented in the file
+\texttt{lttagging.dtx}. For now it contains \cs{UseTaggingSocket}, a
+special invocation command for sockets that are specific to
+tagging. This enables us to also provide \cs{SuspendTagging} and
+\cs{ResumeTagging}, i.e., a very efficient way to temporarily disable
+the whole tagging process. This is, for example, necessary, if some
+code is doing trial typesetting. In that case the trials should not
+generate tagging structures\Dash only the finally chosen version
+should. Thus, \pkg{tabularx}, for example, stops the tagging while
+doing its trials to figure out the correct column widths to use, and
+then renables tagging when the table is finally typeset.
+
+Over time, \texttt{lttagging.dtx} will hold more general tagging code
+as appropriate. For now it is only documented as part of
+\texttt{source2e.pdf} but long term we will provide a separate guide
+for tagging, which will then also include the information currently
+found in various other places, e.g., \texttt{tagpdf.pdf}.
+
+We also added support for a few missing commands
+described in Leslie Lamport's \emph{\LaTeX{}
+Manual}~\cite{38:Lamport}: If \texttt{phase-III} is used
+the \cs{marginpar} command will be properly tagged (depending on
+the PDF version) as an \texttt{Aside} or a \texttt{Note} structure.
+In the standard classes \cs{maketitle} will be tagged if the additional
+testphase module \texttt{title} is used.
+
+The \texttt{math} module has been extended and now includes
+options to attach MathML files to the structures.
+First tests with a PDF reader and screen reader that support
+associated files looks very promising. Examples of PDF files tagged with the
+new method can be found at
+\url{https://github.com/latex3/tagging-project/discussions/56}.
+
+At last various small bugs and problems reported at
+\url{https://github.com/latex3/tagging-project}
+has been fixed. Such a feedback is very valuable,
+so we hope to see you there and thank you for
+any contribution, whether it is an issue or a post on a discussion
+thread.
+
+
+
+\section{Enhancements to the new mark mechanism}
+
+In June 2022 we introduced a new mark mechanism in
+\LaTeX{}~\cite[p.~76]{39:ltnews} that allows keeping track of multiple
+independent marks. It also properly supports top marks, something that wasn't
+reliably possible with \LaTeX{} before.
+
+There was, however, one limitation: to retrieve the marks from the
+page data it was necessary to \cs{vsplit} that data artificially so
+that \TeX{} would produce split marks that the mechanism could then
+use. Unfortunately, \TeX{} gets very upset if it finds infinite
+negative glue (e.g., from \cs{vss}) within this data. This is not
+totally surprising because such glue would allow splitting off any
+amount of material as such glue would hide the size of it. \TeX{}
+therefore responds with an error message if it find such glue while
+doing a \cs{vsplit} operation (and it does so even if a later glue
+item cancels the infinite glue).
+
+To account for this, the code in 2022 attempted to detect this
+situation beforehand and if so did not do any splitting but, of
+course, it would then also not extract any mark information.
+
+In this release the approach has been changed and we always do a
+\cs{vsplit} operation and thus always get the right mark data
+extracted. While it is not possible to avoid upsetting \TeX{} in case
+we have infinite negative glue present, it is possible to hide this
+(more or less) from the user.\footnote{A note to \pkg{l3build} users
+that make use of its testing capabilities: the new mechanism
+temporarily changes \cs{interactionmode} and, for implementation
+reasons in \TeX{}, that results in extra newlines in the \texttt{.log}
+file, so instead of seeing \texttt{[1] [2]} you will see each on
+separate lines. This means that test files might show difference of
+that nature, once the code is active, and must therefore be
+regenerated as necessary.} With the new code \TeX{} will neither stop
+nor show anything on the terminal. What we can't do, though, is to
+avoid that an error is written to the log file, but to make it clear
+that this error is harmless and should be ignored we have arranged the
+code so that the error message, if it is issued, takes the following
+format:
+\begin{verbatim}
+! Infinite glue shrinkage found in box being split.
+<argument> Infinite shrink error above ignored !
+l. ... }
+\end{verbatim}
+Not perfect (especially the somewhat unmotivated \texttt{<argument>}),
+but you can only do so much if error messages and their texts are
+hard-wired in the engine.
+
+So why all this? There are two reasons: we do not lose marks in edge
+cases any longer and perhaps more importantly we are now also reliably
+able to extract marks from arbitrarily boxed data, something that
+wasn't possible at all before. This is, for example, necessary to
+support extended marks in \env{multicols} environments or extract them
+from floats, marginpars, etc.
+
+Details about the implementation can be found in \texttt{texdoc
+ ltmarks-code} or in the shorter \texttt{texdoc ltmarks-doc} (which
+only describes the general concepts and the command interfaces).
+
+\section{New or improved commands}
+
+\subsection{\pkg{doc}: provide \cs{ProvideDocElement}}
+
+Beside \cs{NewDocElement} and \cs{RenewDocElement} we now also offer a
+\cs{ProvideDocElement} declaration that does nothing unless the doc
+element could be declared with \cs{NewDocElement}. This can be useful
+if documentation files are processed both individually as well as
+combined.
+
+
+\subsection{\pkg{doc}: better support for \pkg{upquote}}
+
+In \LaTeX{} News~37~\cite{39:ltnews37} we wrote that support for the
+\pkg{upquote} package was added to the \pkg{doc} package, but back
+then this was only done for \cs{verb}, and the \env{verbatim}
+environments. However, the bulk of code in a typical \texttt{.dtx} file is
+within \env{macrocode} or \env{macrocode*} environments which were not
+affected by adding \pkg{upquote}. We have now updated those, such that
+\pkg{upquote} alters the quote characters in these environments as
+well.
+%
+\githubissue{1230}
+
+\section{Providing \pkg{xtemplate} in the format}
+
+In \LaTeX{} News~32, we described the move of one long-term experimental idea
+into the kernel: the package \pkg{xparse}, which was integrated as \pkg{ltcmd}.
+With this edition, we move another long-term development idea to stable status:
+\emph{templates}.
+
+In this context, templates are a mechanism to abstract out various elements of a
+document (such as \enquote{sectioning}) in such a way that different
+implementations can be interchanged, and design decisions are set up efficiently
+and controllably.
+
+In contrast to \pkg{ltcmd}, which provides a mechanism that many document
+authors will exploit routinely, templates are a more specialised tool. We
+anticipate that they will be used by a small number of programmers, providing
+generic ideas that will then be used within document classes. Most document
+authors will therefore likely encounter templates directly only rarely.
+We anticipate though that they will be \emph{using} templates provided
+by the team or others.
+
+The template system requires three separate ideas
+\begin{itemize}
+ \item Template \emph{type}: the \enquote{thing} we are using templates
+ for, such as \enquote{sectioning} or \enquote{enumerated-list}
+ \item A template: a combination of code and keys that can be used
+ to implement a type. Here for example we might have
+ \enquote{standard-\LaTeX{}-sectioning} as a template for
+ \enquote{sectioning}
+ \item One or more \emph{instances}: a specific use case of a template
+ where (some) keys are set to known values. We might for example see
+ \enquote{\LaTeX{}-section}, \enquote{\LaTeX{}-subsection}, etc.
+\end{itemize}
+
+As part of the move from the experimental \pkg{xtemplate} to kernel integration,
+the team have revisited the commands provided. The stable set now comprises
+\begin{itemize}
+ \item \cs{NewTemplateType}
+ \item \cs{DeclareTemplateInterface}
+ \item \cs{DeclareTemplateCode}
+ \item \cs{DeclareTemplateCopy}
+ \item \cs{EditTemplateDefault}
+ \item \cs{UseTemplate}
+ \item \cs{DeclareInstance}
+ \item \cs{DeclareInstanceCopy}
+ \item \cs{EditInstance}
+ \item \cs{UseInstance}
+\end{itemize}
+
+To support existing package authors, we have released an updated version of
+\pkg{xtemplate} which will work smoothly with the new kernel-level code. The
+existing commands provided in \pkg{xtemplate} will continue to work, but
+we encourage programmers to move to the set above.
+
+\section{Code improvements}
+
+\subsection{Loading packages at the top level}
+Classes and packages should only be loaded with \cs{documentclass}, \cs{usepackage},
+or class interface commands such as \cs{LoadClass} or \cs{RequirePackageWithOptions}
+at the top level, not inside a group. Previously \LaTeX\ did not check this,
+which would often lead to low level errors later on if package declarations
+were reverted as a group ended.
+\LaTeX\ now checks the group level and an error is thrown
+if the class or package is loaded in a group.
+%
+\githubissue{1185}
+
+\subsection{Keep track of lost glyphs}
+
+A while ago we changed the \LaTeX{} default value for
+\cs{tracinglostchars} from \texttt{1} to \texttt{2} so that missing
+glyphs generate at least a warning, but we forgot to make the same
+change to \cs{tracingnone}. Thus, when issuing that command \LaTeX{}
+stopped generating warnings about missing glyphs. This has now been
+corrected.
+%
+\githubissue{549}
+
+\subsection{Improve \pkg{fontenc} error message}
+
+If the \pkg{fontenc} is asked to load a font encoding for which it
+doesn't find a suitable \texttt{.def} file it generates an error
+message indicating that the encoding name might be misspelled. That
+is, of course, one of the possible causes, but another one is that the
+installation is missing a necessary support package, e.g., that no
+support for Cyrillic fonts has been installed. The error message text
+has therefore been extended to explain the issue more generally.
+%
+\githubissue{1102}
+
+
+\subsection{Warn if counter names are problematic}
+
+In the past it was possible to declare, for example,
+\verb/\newcounter{index}/ with the side-effect that this defines
+\cs{theindex}, even though \LaTeX{} has a \env{theindex} environment
+that then got clobbered by the declaration.
+%
+This has now been changed: if \cs{the}\meta{counter} is already
+defined it is not altered, but instead a warning message is displayed.
+%
+\githubissue{823}
+
+\subsection{Extended information in \cs{listfiles}}
+
+The \cs{listfiles} command provides useful information when finding issues
+related to variation in package versions. However, this has to date relied on
+the information in the \cs{ProvidesPackage} line, or similar: that can be
+misleading if for example a file has been edited locally. We have now extended
+\cs{listfiles} to take an optional argument which will then include the MD5
+hash of each file (and the size of each file) in the \texttt{.log}. Thus for
+example you can use
+\begin{verbatim}
+\listfiles[hashes,sizes]
+\end{verbatim}
+to get both the file sizes and file hashes in the \texttt{.log} as well as
+the standard release information.
+%
+\githubissue{945}
+
+\subsection{Optimize creation of simple document commands}
+
+Creating document commands using \cs{NewDocumentCommand}, etc., provides a very
+flexible way of grabbing arguments. When the document command only takes simple
+mandatory arguments, this has to-date added an overhead that could be avoided.
+We have now refined the internal code path such that \enquote{simple} document
+commands avoid almost any overhead at point-of-use, making the results
+essentially as efficient as using \cs{newcommand} for low-level \TeX{}
+constructs. Note that as \cs{NewDocumentCommand} makes engine-robust commands,
+the direct equivalent to \cs{newcommand} is \cs{NewExpandableDocumentCommand}.
+%
+\githubissue{1189}
+
+\subsection{Declaring appropriate sub-encodings for \texttt{TS1} symbol fonts}
+
+In 2020 we incorporated support for the \texttt{TS1} symbol encoding
+directly into the kernel and in this way removed the need to load the
+\pkg{textcomp} package~\cite{39:ltnews31} to make commands such as
+\cs{texteuro} available.
+
+There is, however, a big problem with this \texttt{TS1} symbol
+encoding: only very few fonts can provide every glyph that is supposed
+to be part of \texttt{TS1}. This means that changing font families
+might result in certain symbols becoming unavailable. This can be a
+major disaster if, for example, the \cs{texteuro} (\texteuro) or the
+\cs{textohm} (\textohm) are no longer printed in your document, just
+because you altered your text font family.
+
+To mitigate this problem, we also introduced in 2020 the declaration
+\cs{DeclareEncodingSubset}. This declaration is supposed to be used in
+font definition files for the \texttt{TS1} encoding to specify which
+subset (we have defined 10 common ones) a specific font implements. If
+such a declaration is used then missing symbols are automatically
+taking from a fallback font. While this is not perfect, it is the best
+you can do other than painstrickenly checking that your document only
+uses glyphs that the font supports and if necessary switch to a
+different font or avoid the missing symbols. See also the discussion
+in \cite{39:ltnews33}.
+
+To jumpstart the process we also added declarations to the \LaTeX{}
+kernel for most of the fonts found in \TeX{}Live at the time\Dash with
+the assumption that such declarations would over time be superseded by
+declarations in the \texttt{.fd} files. Unfortunately, this hasn't
+happened yet (or not often) and so many of the initial declarations
+went stale: several fonts got new glyphs added to them (so their
+sub-encoding should have been changed but didn't); others (mainly due
+to license issues) changed the family name and thus our declarations
+became useless and the renamed fonts (now without a declaration) ended
+up in the default sub-encoding which offers only few glyphs; yet
+others such as CharisSIL (which triggered the GitHub issue) were
+simply not around at the time.
+
+We have therefore, again attempted to provide the (currently) correct
+declarations, but it is obvious that this is not a workable
+process. As we do not maintain the fonts we do not have the
+information that something has changed, and to regularly check the
+ever growing font support bundles is simply not possible. It is
+therefore very important that maintainers of font packages do not only
+provide \texttt{.fd} files but also add such a declaration to every
+\texttt{TS1...fd} font definition file that they distribute.
+
+To simplify this process, we now provide a simple \LaTeX{} file
+(\texttt{checkencodingsubset.tex}) for determining the correct (safe)
+sub-encoding. If run, it asks for a font family and then outputs its
+findings, for example, for \texttt{AlgolRevived-TLF} you will get:
+\begin{verbatim}
+-----------------------------------------
+Testing font family AlgolRevived-TLF
+(currently TS1-sub-encoding 9)
+-----------------------------------------
+Some glyphs are missing from sub-encoding 8:
+ ==> \textcelsius (137) is missing
+ ==> \texttwosuperior (178) is missing
+ ==> \textthreesuperior (179) is missing
+ ==> \textonesuperior (185) is missing
+Some glyphs are missing from sub-encoding 7:
+ ==> \texteuro (191) is missing
+All glyphs between sub-encoding 6 and 7 exist
+All glyphs between sub-encoding 5 and 6 exist
+All glyphs between sub-encoding 4 and 5 exist
+Some glyphs are missing from sub-encoding 3:
+ ==> \textwon (142) is missing
+All glyphs between sub-encoding 2 and 3 exist
+Some glyphs are missing from sub-encoding 1:
+ ==> \textmho (77) is missing
+ ==> \textpertenthousand (152) is missing
+All glyphs between sub-encoding 0 and 1 exist
+All glyphs in core exist
+-----------------------------------------
+TS1 encoding subset for AlgolRevived-TLF (ok)
+Use sub-encoding 9
+-----------------------------------------
+\end{verbatim}
+This output is meant for human consumption, e.g., you see which glyphs
+are missing and why a certain sub-encoding is suggested, but it is not
+that hard to use it in a script and extract the suggested sub-encoding
+by grepping for the line starting with \texttt{Use sub-encoding}.
+
+Of course, this check will only work if the missing glyphs are really
+missing: some fonts placed \enquote{tofu}\footnote{Little squares to
+indicate a missing symbol.} into such slots and in this case it looks
+to \TeX{} as if the glyph is provided. For example, for the old
+Palatino fonts (family \texttt{ppl}) it would report
+\begin{verbatim}
+-----------------------------------------
+TS1 encoding subset for ppl (bad)
+Use sub-encoding 0 (not 5)
+-----------------------------------------
+\end{verbatim}
+i.e., all glyphs are provided, while in reality more than twenty are
+missing and sub-encoding 5 as declared in the kernel is correct.
+%
+\githubissue{1257}
+
+
+
+%\section{Bug fixes}
+
+%\section{Changes to packages in the \pkg{amsmath} category}
+
+%\section{Changes to packages in the \pkg{graphics} category}
+
+
+
+\section{Changes to packages in the \pkg{tools} category}
+
+
+\subsection{\pkg{array}, \pkg{longtable}, \pkg{tabularx}: support tagging}
+
+The three packages are now extended to enable producing tagged tabulars upon
+request. This is done by adding a number of sockets (see
+\cite{39:ltnews38}) that, by default, do nothing, but are equipped
+with appropriate plugs if tagged PDF is requested.
+
+In the previous \LaTeX{} release this was handled in
+\texttt{latex-lab} patching the packages when tagging was requested.
+
+
+
+
+\subsection{\pkg{verbatim}: \cs{verb} showed visible spaces}
+
+A recent change in the kernel was not reflected in the \pkg{verbatim}
+package with the result that \cs{verb} showed visible spaces
+(\verb*/ /) after the package was loaded. This has already been corrected
+in a hotfix for release 2023-11.
+%
+\githubissue{1160}
+
+\subsection{\pkg{verbatim}: Support tabs in \cs{verbatiminput*}}
+
+Mimicking the kernel update (November, 2023) that allowed \cs{verb*}
+to mark tabs as spaces, the \pkg{verbatim} package has been updated
+such that \cs{verbatiminput*} marks tabs as spaces as well.
+%
+\githubissue{1245}
+
+
+\subsection{\pkg{multicol}: \cs{columnbreak} interferes with mark mechanism}
+
+The \pkg{multicol} package has to keep track of marks (from
+\cs{markright} or \cs{markboth}) as part of its output routine code
+and can't rely on \LaTeX{} handling that automatically. It does so by
+artificially splitting page data with \cs{vsplit} to extract the mark
+data. With the introduction of \cs{columnbreak} that code failed
+sometimes, because it was not seeing any mark that followed such a
+forced column break.
+
+This has now been corrected, but there is further work to do, because
+as of now \pkg{multicol} does not yet handle marks using the new mark
+mechanism\Dash see the discussion at the beginning of the newsletter.
+%
+\githubissue{1130}
+
+\subsection{\pkg{showkeys}: Allow \cs{newline} in \pkg{amsthm} to work}
+%
+Previously \pkg{showkeys} added an extra box layer which disabled the \cs{newline}
+of \pkg{amsthm} theorem styles. This extra box has now been avoided.
+%
+\githubissue{1123}
+
+
+
+\section{Changes to files in the \pkg{cyrillic} category}
+
+\subsection{Correct definition of \cs{k}}
+
+Ages ago, the encoding specific definitions for various accent
+commands were changed to guard against altering some parameter values
+non-locally by mistake. For some reason the definition for \cs{k} in
+the Cyrillic encodings \texttt{T2A}, \texttt{T2B}, and \texttt{T2C}
+didn't get this treatment. This oversight has now been corrected.
+%
+\githubissue{1148}
+
+
+
+\begin{thebibliography}{9}
+
+%\fontsize{9.3}{11.3}\selectfont
+
+
+%\bibitem{39:Lamport}
+%Leslie Lamport.
+%\newblock \emph{{\LaTeX}: {A} Document Preparation System: User's Guide and Reference
+% Manual}.
+%\newblock \mbox{Addison}-Wesley, Reading, MA, USA, 2nd edition, 1994.
+%\newblock ISBN 0-201-52983-1.
+%\newblock Reprinted with corrections in 1996.
+%
+
+\bibitem{39:ltnews} \LaTeX{} Project Team.
+ \emph{\LaTeXe{} news 1--39}. June, 2024.
+ \url{https://latex-project.org/news/latex2e-news/ltnews.pdf}
+%
+%
+\bibitem{39:ltnews31} \LaTeX{} Project Team.
+ \emph{\LaTeXe{} news 31}. February, 2020.
+ \url{https://latex-project.org/news/latex2e-news/ltnews31.pdf}
+
+\bibitem{39:ltnews33} \LaTeX{} Project Team.
+ \emph{\LaTeXe{} news 33}. June 2021.\\
+ \url{https://latex-project.org/news/latex2e-news/ltnews33.pdf}
+
+\bibitem{39:ltnews37} \LaTeX{} Project Team.
+ \emph{\LaTeXe{} news 37}. June 2023.\\
+ \url{https://latex-project.org/news/latex2e-news/ltnews37.pdf}
+
+\bibitem{39:ltnews38} \LaTeX{} Project Team.
+ \emph{\LaTeXe{} news 38}. November 2023.\\
+ \url{https://latex-project.org/news/latex2e-news/ltnews38.pdf}
+
+%\bibitem{39:blueprint} Frank Mittelbach and Chris Rowley.
+% \emph{\LaTeX{} Tagged PDF \Dash A blueprint for a large project}.\\
+% \url{https://latex-project.org/publications/indexbyyear/2020/}
+
+\end{thebibliography}
+
+\end{document}
diff --git a/macros/latex-dev/base/ltoutenc.dtx b/macros/latex-dev/base/ltoutenc.dtx
index 1d257805a4..c18ff01446 100644
--- a/macros/latex-dev/base/ltoutenc.dtx
+++ b/macros/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/macros/latex-dev/base/ltoutenc.ins b/macros/latex-dev/base/ltoutenc.ins
index 2f0c39517f..c5316f9aab 100644
--- a/macros/latex-dev/base/ltoutenc.ins
+++ b/macros/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/macros/latex-dev/base/ltoutput.dtx b/macros/latex-dev/base/ltoutput.dtx
index 18388b1cc6..b067ef5ecb 100644
--- a/macros/latex-dev/base/ltoutput.dtx
+++ b/macros/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/macros/latex-dev/base/ltpage.dtx b/macros/latex-dev/base/ltpage.dtx
index 1a6586d067..f4efe0fd58 100644
--- a/macros/latex-dev/base/ltpage.dtx
+++ b/macros/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/macros/latex-dev/base/ltpageno.dtx b/macros/latex-dev/base/ltpageno.dtx
index 6c02d0fa7f..da80dbaab7 100644
--- a/macros/latex-dev/base/ltpageno.dtx
+++ b/macros/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/macros/latex-dev/base/ltpar.dtx b/macros/latex-dev/base/ltpar.dtx
index 31d863610b..200d3b4238 100644
--- a/macros/latex-dev/base/ltpar.dtx
+++ b/macros/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/macros/latex-dev/base/ltpara-code.pdf b/macros/latex-dev/base/ltpara-code.pdf
index aa77b62b7c..37c0dd52df 100644
--- a/macros/latex-dev/base/ltpara-code.pdf
+++ b/macros/latex-dev/base/ltpara-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltpara-doc.pdf b/macros/latex-dev/base/ltpara-doc.pdf
index 008e6a5f33..7d23332d28 100644
--- a/macros/latex-dev/base/ltpara-doc.pdf
+++ b/macros/latex-dev/base/ltpara-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltpara.dtx b/macros/latex-dev/base/ltpara.dtx
index 9c1a95ee61..e9741ff935 100644
--- a/macros/latex-dev/base/ltpara.dtx
+++ b/macros/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/macros/latex-dev/base/ltpictur.dtx b/macros/latex-dev/base/ltpictur.dtx
index 926fd5c692..ea5ac4205b 100644
--- a/macros/latex-dev/base/ltpictur.dtx
+++ b/macros/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/macros/latex-dev/base/ltplain.dtx b/macros/latex-dev/base/ltplain.dtx
index b41810373d..a628b954d9 100644
--- a/macros/latex-dev/base/ltplain.dtx
+++ b/macros/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/macros/latex-dev/base/ltproperties-code.pdf b/macros/latex-dev/base/ltproperties-code.pdf
index a0757a3b61..85f4ba4e45 100644
--- a/macros/latex-dev/base/ltproperties-code.pdf
+++ b/macros/latex-dev/base/ltproperties-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltproperties-doc.pdf b/macros/latex-dev/base/ltproperties-doc.pdf
index 8dccf572dc..1dc54d6ea6 100644
--- a/macros/latex-dev/base/ltproperties-doc.pdf
+++ b/macros/latex-dev/base/ltproperties-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltproperties.dtx b/macros/latex-dev/base/ltproperties.dtx
index 40c50cd20a..4a5fa78b5f 100644
--- a/macros/latex-dev/base/ltproperties.dtx
+++ b/macros/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/macros/latex-dev/base/ltsect.dtx b/macros/latex-dev/base/ltsect.dtx
index 5a03fd4977..4560704463 100644
--- a/macros/latex-dev/base/ltsect.dtx
+++ b/macros/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/macros/latex-dev/base/ltshipout-code.pdf b/macros/latex-dev/base/ltshipout-code.pdf
index b688db8cc5..0fee02853e 100644
--- a/macros/latex-dev/base/ltshipout-code.pdf
+++ b/macros/latex-dev/base/ltshipout-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltshipout-doc.pdf b/macros/latex-dev/base/ltshipout-doc.pdf
index 9265263918..3051341818 100644
--- a/macros/latex-dev/base/ltshipout-doc.pdf
+++ b/macros/latex-dev/base/ltshipout-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltshipout.dtx b/macros/latex-dev/base/ltshipout.dtx
index b19814a6fd..0c9113ce93 100644
--- a/macros/latex-dev/base/ltshipout.dtx
+++ b/macros/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/macros/latex-dev/base/ltsockets-code.pdf b/macros/latex-dev/base/ltsockets-code.pdf
index 7fa60a7f54..6301f60a3c 100644
--- a/macros/latex-dev/base/ltsockets-code.pdf
+++ b/macros/latex-dev/base/ltsockets-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltsockets-doc.pdf b/macros/latex-dev/base/ltsockets-doc.pdf
index e708f04a3a..a50aad4998 100644
--- a/macros/latex-dev/base/ltsockets-doc.pdf
+++ b/macros/latex-dev/base/ltsockets-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltsockets.dtx b/macros/latex-dev/base/ltsockets.dtx
index 7d2940f454..243963f7bc 100644
--- a/macros/latex-dev/base/ltsockets.dtx
+++ b/macros/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/macros/latex-dev/base/ltspace.dtx b/macros/latex-dev/base/ltspace.dtx
index 03b3445047..206e4f3885 100644
--- a/macros/latex-dev/base/ltspace.dtx
+++ b/macros/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/macros/latex-dev/base/lttab.dtx b/macros/latex-dev/base/lttab.dtx
index e76325d82b..a85b4f8cf7 100644
--- a/macros/latex-dev/base/lttab.dtx
+++ b/macros/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/macros/latex-dev/base/lttagging.dtx b/macros/latex-dev/base/lttagging.dtx
new file mode 100644
index 0000000000..585479df21
--- /dev/null
+++ b/macros/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/macros/latex-dev/base/lttemplates.dtx b/macros/latex-dev/base/lttemplates.dtx
new file mode 100644
index 0000000000..844fb6fd34
--- /dev/null
+++ b/macros/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/macros/latex-dev/base/lttextcomp.dtx b/macros/latex-dev/base/lttextcomp.dtx
index 3602e0a6b0..c67bac00dd 100644
--- a/macros/latex-dev/base/lttextcomp.dtx
+++ b/macros/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/macros/latex-dev/base/ltthm.dtx b/macros/latex-dev/base/ltthm.dtx
index b321c7ac2b..180b8accfe 100644
--- a/macros/latex-dev/base/ltthm.dtx
+++ b/macros/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/macros/latex-dev/base/ltvers.dtx b/macros/latex-dev/base/ltvers.dtx
index e169dee020..3896935525 100644
--- a/macros/latex-dev/base/ltvers.dtx
+++ b/macros/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/macros/latex-dev/base/ltx3info.pdf b/macros/latex-dev/base/ltx3info.pdf
index 61f04c83ca..4abf1f8a46 100644
--- a/macros/latex-dev/base/ltx3info.pdf
+++ b/macros/latex-dev/base/ltx3info.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltx3info.tex b/macros/latex-dev/base/ltx3info.tex
index 096fa2db9a..bfa09b9b87 100644
--- a/macros/latex-dev/base/ltx3info.tex
+++ b/macros/latex-dev/base/ltx3info.tex
@@ -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/macros/latex-dev/base/ltxcheck.tex b/macros/latex-dev/base/ltxcheck.tex
index d219d2ebc2..244bddffce 100644
--- a/macros/latex-dev/base/ltxcheck.tex
+++ b/macros/latex-dev/base/ltxcheck.tex
@@ -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/macros/latex-dev/base/ltxdoc.dtx b/macros/latex-dev/base/ltxdoc.dtx
index e147c9d22f..5e8b494692 100644
--- a/macros/latex-dev/base/ltxdoc.dtx
+++ b/macros/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/macros/latex-dev/base/ltxdoc.pdf b/macros/latex-dev/base/ltxdoc.pdf
index 334349f4bb..61a0b18e68 100644
--- a/macros/latex-dev/base/ltxdoc.pdf
+++ b/macros/latex-dev/base/ltxdoc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltxguide.cls b/macros/latex-dev/base/ltxguide.cls
index 778f7e993e..c202b56acb 100644
--- a/macros/latex-dev/base/ltxguide.cls
+++ b/macros/latex-dev/base/ltxguide.cls
@@ -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/macros/latex-dev/base/ltxref.dtx b/macros/latex-dev/base/ltxref.dtx
index 0f842e4312..79cf01be77 100644
--- a/macros/latex-dev/base/ltxref.dtx
+++ b/macros/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/macros/latex-dev/base/makeindx.dtx b/macros/latex-dev/base/makeindx.dtx
index b91d3a6c44..20da2f159d 100644
--- a/macros/latex-dev/base/makeindx.dtx
+++ b/macros/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/macros/latex-dev/base/makeindx.ins b/macros/latex-dev/base/makeindx.ins
index 1c5f6edcb9..45e5c9aab0 100644
--- a/macros/latex-dev/base/makeindx.ins
+++ b/macros/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/macros/latex-dev/base/makeindx.pdf b/macros/latex-dev/base/makeindx.pdf
index d6c1e08074..a2ab245043 100644
--- a/macros/latex-dev/base/makeindx.pdf
+++ b/macros/latex-dev/base/makeindx.pdf
Binary files differ
diff --git a/macros/latex-dev/base/minimal.cls b/macros/latex-dev/base/minimal.cls
index 89c233c30f..64efdd5287 100644
--- a/macros/latex-dev/base/minimal.cls
+++ b/macros/latex-dev/base/minimal.cls
@@ -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/macros/latex-dev/base/modguide.pdf b/macros/latex-dev/base/modguide.pdf
index ff40b00fa9..5006d07168 100644
--- a/macros/latex-dev/base/modguide.pdf
+++ b/macros/latex-dev/base/modguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/modguide.tex b/macros/latex-dev/base/modguide.tex
index 332b609ab3..ff934ecc34 100644
--- a/macros/latex-dev/base/modguide.tex
+++ b/macros/latex-dev/base/modguide.tex
@@ -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/macros/latex-dev/base/newdc.ins b/macros/latex-dev/base/newdc.ins
index 277e8ea21f..69d74d6167 100644
--- a/macros/latex-dev/base/newdc.ins
+++ b/macros/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/macros/latex-dev/base/newlfont.dtx b/macros/latex-dev/base/newlfont.dtx
index 0b35eddd80..2792395c58 100644
--- a/macros/latex-dev/base/newlfont.dtx
+++ b/macros/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/macros/latex-dev/base/nfssfont.dtx b/macros/latex-dev/base/nfssfont.dtx
index 556ce5f76d..0464053c10 100644
--- a/macros/latex-dev/base/nfssfont.dtx
+++ b/macros/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/macros/latex-dev/base/nfssfont.ins b/macros/latex-dev/base/nfssfont.ins
index 21a13f70a8..00f5a0c8a3 100644
--- a/macros/latex-dev/base/nfssfont.ins
+++ b/macros/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/macros/latex-dev/base/nfssfont.pdf b/macros/latex-dev/base/nfssfont.pdf
index c947cc02bf..44aba54c32 100644
--- a/macros/latex-dev/base/nfssfont.pdf
+++ b/macros/latex-dev/base/nfssfont.pdf
Binary files differ
diff --git a/macros/latex-dev/base/olddc.ins b/macros/latex-dev/base/olddc.ins
index 320b3a4b0e..1f5d12ece4 100644
--- a/macros/latex-dev/base/olddc.ins
+++ b/macros/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/macros/latex-dev/base/oldlfont.dtx b/macros/latex-dev/base/oldlfont.dtx
index 33ae5e6fd9..7a3534f517 100644
--- a/macros/latex-dev/base/oldlfont.dtx
+++ b/macros/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/macros/latex-dev/base/preload.dtx b/macros/latex-dev/base/preload.dtx
index d26bdaa9ed..fb5f86824c 100644
--- a/macros/latex-dev/base/preload.dtx
+++ b/macros/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/macros/latex-dev/base/proc.dtx b/macros/latex-dev/base/proc.dtx
index bbbf71162f..ec69e47396 100644
--- a/macros/latex-dev/base/proc.dtx
+++ b/macros/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/macros/latex-dev/base/proc.ins b/macros/latex-dev/base/proc.ins
index 056816e99e..83f50bda12 100644
--- a/macros/latex-dev/base/proc.ins
+++ b/macros/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/macros/latex-dev/base/proc.pdf b/macros/latex-dev/base/proc.pdf
index b143f929d5..84fbeb3470 100644
--- a/macros/latex-dev/base/proc.pdf
+++ b/macros/latex-dev/base/proc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/slides.dtx b/macros/latex-dev/base/slides.dtx
index a918c337dd..3674a6c05f 100644
--- a/macros/latex-dev/base/slides.dtx
+++ b/macros/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/macros/latex-dev/base/slides.ins b/macros/latex-dev/base/slides.ins
index 3acb556b96..3124ed366f 100644
--- a/macros/latex-dev/base/slides.ins
+++ b/macros/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/macros/latex-dev/base/slides.pdf b/macros/latex-dev/base/slides.pdf
index 5bdcaaa9e6..072806917b 100644
--- a/macros/latex-dev/base/slides.pdf
+++ b/macros/latex-dev/base/slides.pdf
Binary files differ
diff --git a/macros/latex-dev/base/slifonts.fdd b/macros/latex-dev/base/slifonts.fdd
index 5b66975095..b35cd07a8b 100644
--- a/macros/latex-dev/base/slifonts.fdd
+++ b/macros/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/macros/latex-dev/base/slifonts.pdf b/macros/latex-dev/base/slifonts.pdf
index 8dc32739ff..140e317b47 100644
--- a/macros/latex-dev/base/slifonts.pdf
+++ b/macros/latex-dev/base/slifonts.pdf
Binary files differ
diff --git a/macros/latex-dev/base/source2e.pdf b/macros/latex-dev/base/source2e.pdf
index f39b19d128..5fbc7e1c0c 100644
--- a/macros/latex-dev/base/source2e.pdf
+++ b/macros/latex-dev/base/source2e.pdf
Binary files differ
diff --git a/macros/latex-dev/base/source2e.tex b/macros/latex-dev/base/source2e.tex
index c538593ddd..6ff2928a42 100644
--- a/macros/latex-dev/base/source2e.tex
+++ b/macros/latex-dev/base/source2e.tex
@@ -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.
%
@@ -342,6 +342,8 @@ page_precedence "rnaA"
\DocInclude{ltoutput} % Output routine
+ \DocInclude{lttagging}% Tagging support
+
\DocInclude{lthyphen} % Hyphenation (hyphen.ltx).
\DocInclude{ltfinal} % Last minute initialisations and dump
@@ -378,7 +380,7 @@ page_precedence "rnaA"
\def\endash{--}
\catcode`\-\active
\def-{\futurelet\temp\indexdash}
-\def\indexdash{\ifx\temp-\endash\fi}
+\def\indexdash{\ifx\temp-\endash\else:\fi}
\PrintIndex
\endgroup
diff --git a/macros/latex-dev/base/source2edoc.cls b/macros/latex-dev/base/source2edoc.cls
index 5f731af7ae..48ae49b29a 100644
--- a/macros/latex-dev/base/source2edoc.cls
+++ b/macros/latex-dev/base/source2edoc.cls
@@ -2,12 +2,12 @@
% This class is buggy and needs fixing
\ProvidesClass{source2edoc}
- [2022/04/03 v0.2c Quick hack to typeset source2.tex
+ [2024/02/14 v0.2e Quick hack to typeset source2.tex
(not usable for anything else and buggy -- will vanish again)!]
-\LoadClass{l3doc}
+\LoadClass[kernel]{l3doc}
\RemoveFromHook{begindocument}[l3doc] % drop the standard setting making " a shortverb
\AddToHook{begindocument}{\MakeShortVerb \|} % but readd | as one
@@ -50,84 +50,6 @@
}
-
-% some l3doc's def are buggy (already fixed there but not distributed yet)
-
-\RenewDocumentCommand \DocInclude { m }
- {
- \relax\clearpage
- \docincludeaux
- \IfFileExists{#1.fdd}
- { \cs_set:Npn \currentfile{#1.fdd} }
- { \cs_set:Npn \currentfile{#1.dtx} }
- \int_compare:nNnTF \@auxout = \@partaux
- { \@latexerr{\string\include\space cannot~be~nested}\@eha }
- { \@docinclude {#1} } % <--- braces needed!
- \int_compare:nNnF { \tex_currentgrouplevel:D } = { 0 }
- {
- \int_compare:nNnT { \tex_interactionmode:D } = { 0 }
- { \int_set:Nn \tex_interactionmode:D { 1 } }
- \msg_fatal:nnn { source2edoc } { missing-endgroup } {#1}
- }
- }
-\msg_new:nnn { source2edoc } { missing-endgroup }
- {
- \str_if_eq:VnTF \@currenvir { document }
- {
- There~are~\int_use:N \tex_currentgrouplevel:D
- \c_space_tl unclosed~groups~in~#1.dtx.
- }
- {
- The~\@currenvir \c_space_tl environment~on~line~\@currenvline
- \c_space_tl doesn't~have~a~matching~\iow_char:N\\end{\@currenvir}.
- }
- }
-\cs_gset:Npn \@docinclude #1
- {
- \clearpage
- \immediate\write\@mainaux{\string\@input{#1.aux}}
- \@tempswatrue
- \if@partsw
- \@tempswafalse
- \cs_set:Npx \@tempb {#1}
- \clist_map_inline:Nn \@partlist
- {
- \if_meaning:w \@tempa \@tempb
- \@tempswatrue
- \fi:
- }
- \fi
- \if@tempswa
- \cs_set_eq:NN \@auxout \@partaux
- \immediate\openout\@partaux #1.aux
- \immediate\write\@partaux{\relax}
- \cs_set_eq:NN \@ltxdoc@PrintIndex \PrintIndex
- \cs_set_eq:NN \PrintIndex \relax
- \cs_set_eq:NN \@ltxdoc@PrintChanges \PrintChanges
- \cs_set_eq:NN \PrintChanges \relax
- \cs_set_eq:NN \@ltxdoc@theglossary \theglossary
- \cs_set_eq:NN \@ltxdoc@endtheglossary \endtheglossary
- \part{\currentfile}
- {
- \cs_set_eq:NN \ttfamily\relax
- \cs_gset:Npx \filekey
- { \filekey,~ \thepart = { \ttfamily \currentfile } } % <-- mising spaces considered harmful
- }
- \DocInput{\currentfile}
- \cs_set_eq:NN \PrintIndex \@ltxdoc@PrintIndex
- \cs_set_eq:NN \PrintChanges \@ltxdoc@PrintChanges
- \cs_set_eq:NN \theglossary \@ltxdoc@theglossary
- \cs_set_eq:NN \endtheglossary \@ltxdoc@endtheglossary
- \clearpage
- \@writeckpt{#1}
- \immediate \closeout \@partaux
- \else
- \@nameuse{cp@#1}
- \fi
- \cs_set_eq:NN \@auxout \@mainaux
- }
-
-
% change the setup here: we have a lot of long names so better run raggeded
\cs_set_protected:Npn \__codedoc_macro_end_style:n #1
@@ -176,7 +98,7 @@
dd%
\else\@ctrerr\fi}
\def\docincludeaux{%
- \def\thepart{\aalph{part}}\def\filesep{\thepart-}%
+ \def\thepart{\ifnum\value{part}<10 0\fi\arabic{part}}\def\filesep{\thepart-}%
\let\filekey\@gobble
\g@addto@macro\index@prologue{%
\gdef\@oddfoot{\parbox[t]{\textwidth}{\strut\footnotesize
@@ -303,6 +225,9 @@ Bug reports can be opened (category \texttt{#1}) at\\%
\AddToHook{cmd/tableofcontents/after}{\global\let\tableofcontents\relax}
+% pages > 1000
+\renewcommand\@pnumwidth{2em}
+
\InputIfFileExists{ltxdoc.cfg}
{\typeout{*************************************^^J%
* Local config file ltxdoc.cfg used^^J%
diff --git a/macros/latex-dev/base/syntonly.dtx b/macros/latex-dev/base/syntonly.dtx
index 2b0049b696..9844585fa5 100644
--- a/macros/latex-dev/base/syntonly.dtx
+++ b/macros/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/macros/latex-dev/base/syntonly.ins b/macros/latex-dev/base/syntonly.ins
index 8ccaf254d1..6435e0a6ee 100644
--- a/macros/latex-dev/base/syntonly.ins
+++ b/macros/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/macros/latex-dev/base/syntonly.pdf b/macros/latex-dev/base/syntonly.pdf
index 3390b696f3..6beca59509 100644
--- a/macros/latex-dev/base/syntonly.pdf
+++ b/macros/latex-dev/base/syntonly.pdf
Binary files differ
diff --git a/macros/latex-dev/base/testpage.tex b/macros/latex-dev/base/testpage.tex
index 7eae6c142c..e8f06313fb 100644
--- a/macros/latex-dev/base/testpage.tex
+++ b/macros/latex-dev/base/testpage.tex
@@ -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/macros/latex-dev/base/tlc2.pdf b/macros/latex-dev/base/tlc2.pdf
index 87fd9f964d..4945823cda 100644
--- a/macros/latex-dev/base/tlc2.pdf
+++ b/macros/latex-dev/base/tlc2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/tlc3.err b/macros/latex-dev/base/tlc3.err
index d4f94705d7..cb33dd01e4 100644
--- a/macros/latex-dev/base/tlc3.err
+++ b/macros/latex-dev/base/tlc3.err
@@ -1,4 +1,4 @@
-\newcommand\erratafiledate{2023/10/30} % needs / and not -
+\newcommand\erratafiledate{2024/01/29} % needs / and not -
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To produce a printed version of this errata file run this file through
@@ -640,14 +640,37 @@ Output of example misses the page numbers in acronym list \> Run example 3 times
\CHAPTER{Chapter 4 --- Basic Formatting Tools -- Larger \ldots}
+\erroronpage{I-253}{para 2, l.-3}{YEi}{2023/11/27}{s}
+Move comma:\\
+and \textsf{thmtools} packages and \textsf{typed-checklist}\u{,} helps you write \> \\
+and \textsf{thmtools} packages\u{,} and \textsf{typed-checklist} helps you write
+
+
\erroronpage{I-323}{Table 4.4, left column}{BeB}{2023/07/25}{s}
Typo: Assembler (\u{N}otorola68k, x86masm) \> \\ Assembler (\u{M}otorola68k, x86masm)
% Matlab \> Matlab \u{(empty, 5.1)}
% könnte auch aktualisiert werden, steht aber in Version 1.8d nicht drin
+\erroronpage{I-344}{exa 4-3-16}{CAR/FMi}{2024/01/29}{s}
+Use \cs{NewDocumentEnvironment} instead of
+\cs{DeclareDocumentEnvironment} because it is always better to check
+that the declaration is not accidentally overwriting an existing
+environment.
\CHAPTER{Chapter 5 --- The Layout of the Page}
+\erroronpage{I-365}{paras -3 to -2}{YEi}{2023/11/28}{s}
+
+Add/replace:\\
+\ldots package and others. \cs{par} The \u{fifth} section then \> \\
+\ldots package and others.
+\u{In the fifth section we cover ``static'' page} \\
+\u{decorations such as watermarks.} \cs{par} The \u{sixth} section then
+
+\erroronpage{I-368}{table 5.1}{YEi}{2023/11/29}{s}
+A better approximation for \texttt{b5paper} is \u{$6\frac{7}{8}$}${}\times 9 \frac{7}{8}$
+
+
\erroronpage{I-386}{exa 5-3-1, l.7}{EOl}{2023/09/09}{s}
Change:
paragraph over \u{two} pages. \> paragraph over \u{three} pages.
@@ -1302,6 +1325,10 @@ is created only if the entry \u{contains} a shorttitle \u{field} and the title a
is created only if the entry \u{has been referenced (prior to typesetting}\\
\u{the bibliography), contains} a shorttitle \u{field,} and the title and shorttitle fields differ.
+\erroronpage{II-535}{footnote}{FMi}{2024/01/07}{}
+Extend the explanation:\\
+\u{you can} use \cs{mancite} \u{in front of any citation command} to avoid this.
+
\erroronpage{II-560}{exa 16-7-31}{FMi}{2023/08/31}{s}
Jane Doe.\ \textit{A\u{n} second book.}\ 2020.\> Jane Doe.\ \textit{A second book.}\ 2020.
@@ -1367,11 +1394,13 @@ Appendix title not properly capitalized.
\contributor{MJo}{Maciej Jończyk}
\contributor{YFu}{FUJIMURA Yukitoshi}
\contributor{YvH}{Yvon Henel}
+\contributor{YEi}{Yaakov Eisenberg}
\contributor{bb}{Barbara Beeton}
\contributor{kb}{Karl Berry}
\end{multicols}
+
Other people have sent us corrections for errors already found.
Thanks to all of you!
diff --git a/macros/latex-dev/base/tlc3.pdf b/macros/latex-dev/base/tlc3.pdf
index 24ff91e85b..00936f6e57 100644
--- a/macros/latex-dev/base/tlc3.pdf
+++ b/macros/latex-dev/base/tlc3.pdf
Binary files differ
diff --git a/macros/latex-dev/base/tulm.fdd b/macros/latex-dev/base/tulm.fdd
index c8dd8b95fc..6f7a6873cd 100644
--- a/macros/latex-dev/base/tulm.fdd
+++ b/macros/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/macros/latex-dev/base/tulm.ins b/macros/latex-dev/base/tulm.ins
index 85970a5133..ea8fd7b22b 100644
--- a/macros/latex-dev/base/tulm.ins
+++ b/macros/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/macros/latex-dev/base/tulm.pdf b/macros/latex-dev/base/tulm.pdf
index 8316f50ae8..29c84ca59b 100644
--- a/macros/latex-dev/base/tulm.pdf
+++ b/macros/latex-dev/base/tulm.pdf
Binary files differ
diff --git a/macros/latex-dev/base/unpack.ins b/macros/latex-dev/base/unpack.ins
index 5baa2b5447..e81c8dbfa8 100644
--- a/macros/latex-dev/base/unpack.ins
+++ b/macros/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/macros/latex-dev/base/usrguide-historic.pdf b/macros/latex-dev/base/usrguide-historic.pdf
index d41dee80ce..0001be0aae 100644
--- a/macros/latex-dev/base/usrguide-historic.pdf
+++ b/macros/latex-dev/base/usrguide-historic.pdf
Binary files differ
diff --git a/macros/latex-dev/base/usrguide-historic.tex b/macros/latex-dev/base/usrguide-historic.tex
index 40865a2be9..228a253abb 100644
--- a/macros/latex-dev/base/usrguide-historic.tex
+++ b/macros/latex-dev/base/usrguide-historic.tex
@@ -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.
%
@@ -34,15 +34,15 @@
\title{\LaTeX\ for authors --- historic version}
-\author{\copyright~Copyright 1995--2022, \LaTeX\ Project Team.\\
+\author{\copyright~Copyright 1995--2023, \LaTeX\ Project Team.\\
All rights reserved.%
\footnote{This file 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. See the source
- \texttt{usrguide.tex} for full details.}%
+ \texttt{usrguide-historic.tex} for full details.}%
}
-\date{30 August 2022}
+\date{09 November 2023}
\begin{document}
diff --git a/macros/latex-dev/base/usrguide.pdf b/macros/latex-dev/base/usrguide.pdf
index 4ab7004018..c9f3496f57 100644
--- a/macros/latex-dev/base/usrguide.pdf
+++ b/macros/latex-dev/base/usrguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/usrguide.tex b/macros/latex-dev/base/usrguide.tex
index 05fc93e7af..9f5cfb181a 100644
--- a/macros/latex-dev/base/usrguide.tex
+++ b/macros/latex-dev/base/usrguide.tex
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2020-2023
+% Copyright (C) 2020-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -43,7 +43,7 @@
\texttt{usrguide.tex} for full details.}%
}
-\date{2023-05-23}
+\date{2023-12-02}
\NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
\NewDocumentCommand\marg{m}{\arg{#1}}
@@ -794,6 +794,18 @@ a & b & c \\
\end{tabular}
\end{verbatim}
+\subsection{Performance}
+
+For document commands where the argument specification is entirely
+comprised of |m| or |+m| entries (or is entirely empty), the internal structure
+created by \cs{NewDocumentCommand} is essentially as efficient
+as provided by |\newcommand(*)|. As such, document commands may replace
+constructs arising from \cs{newcommand}, etc., without a need to be concerned
+about performance. Note that \cs{newcommand(*)} produces expandable
+results, so the direct replacement is \cs{NewExpandableDocumentCommand};
+in most cases, however, it is better to use \cs{NewDocumentCommand} to
+give more robust structures.
+
\subsection{Details about argument delimiters}
In normal (non-expandable) commands, the delimited types look for the
@@ -951,7 +963,7 @@ The differences between \cs{New...}, \cs{Renew...}, and
\begin{decl}
|\ShowEnvironment| \arg{env}
\end{decl}
-This displays the meaning of the begin end end code for environment \meta{env}.
+This displays the meaning of the begin and end code for environment \meta{env}.
@@ -1161,7 +1173,7 @@ therefore shows the same syntax peculiars as discussed
above. Nevertheless, in practice they are usually sufficient. For
example
\begin{verbatim}
-\newcommand\calculateheight[1]{%
+\NewDocumentCommand\calculateheight{m}{%
\setlength\textheight{\dimeval{\topskip+\baselineskip*\inteval{#1-1}}}}
\end{verbatim}
sets the \cs{textheight} to the appropriate value if a page should
@@ -1186,13 +1198,13 @@ Titlecasing here follows the definition given by the Unicode Consortium: the
first character of the input will be converted to (broadly) uppercase, and the
rest of the input to lowercase. The full range of Unicode UTF-8 input can be
supported.
-\begin{quotation}
+\begin{quote}
\begin{tabular}{rl}
|\MakeUppercase{hello WORLD ßüé}| & \MakeUppercase{hello WORLD ßüé} \\
|\MakeLowercase{hello WORLD ßüé}| & \MakeLowercase{hello WORLD ßüé} \\
|\MakeTitlecase{hello WORLD ßüé}| & \MakeTitlecase{hello WORLD ßüé} \\
\end{tabular}
-\end{quotation}
+\end{quote}
The case-changing commands take an optional argument which can be used to
tailor the output. This optional argument accepts the key \texttt{locale},
@@ -1208,14 +1220,14 @@ are the arguments to the commands \cs{label}, \cs{ref}, \cs{cite}, \cs{begin}
and \cs{end}. Additional exclusions can be added using the command
\cs{AddToNoCaseChangeList}. Input can be excluded from case changing using the
command \cs{NoCaseChange}.
-\begin{quotation}
+\begin{quote}
\begin{tabular}{rl}
|\MakeUppercase{Some text $y = mx + c$}|
& \MakeUppercase{Some text $y = mx + c$} \\
|\MakeUppercase{\NoCaseChange{iPhone}}|
& \MakeLowercase{\NoCaseChange{iPhone}} \\
\end{tabular}
-\end{quotation}
+\end{quote}
To allow robust commands to be used within case changing \emph{and} to produce
the expected output, two additional control commands are available.
@@ -1244,18 +1256,54 @@ apply to a specific one: this is given in BCP-47 format
(\url{https://en.wikipedia.org/wiki/IETF_language_tag}). For example,
the kernel customises the mapping for U+01F0 (\v{j}) when uppercasing in
8-bit engines:
-\begin{quotation}
+\begin{quote}
|\DeclareUppercaseMapping{"01F0}{\v{J}}|
-\end{quotation}
+\end{quote}
as there is no pre-composed \v{J} character, and this is problematic if
the engine does not support Unicode natively. Similarly, to set a locale
\texttt{xx} to behave in the same way as Turkish and retain the difference
between dotted- and dotless-i, one could use for example
-\begin{quotation}
+\begin{quote}
|\DeclareLowercaseMapping[xx]{"0049}{\i}|\\
|\DeclareLowercaseMapping[xx]{"0130}{i}|\\
|\DeclareUppercaseMapping[xx]{"0069}{\.{I}}|\\
|\DeclareUppercaseMapping[xx]{"0131}{I}|
-\end{quotation}
+\end{quote}
+
+\section{Support for problem solving}
+
+\begin{decl}
+ |\listfiles| \oarg{options}
+\end{decl}
+
+If this command is placed in the preamble then a list of the files
+read in (as a result of processing the document) will be displayed
+on the terminal (and in the log file) at the end of the run. Where
+possible, a short description will also be produced. These descriptions
+will (hopefully) include the descriptions, dates and version numbers
+for package and class files.
+
+Sometimes, it may be that a local edit has been made to a package or
+class file (or rather a copy of such a file). To allow these cases to
+be identified, \cs{listfiles} takes an optional argument which allows
+adjustment of the information printed using a key--value approach
+\begin{description}
+ \item[\texttt{hashes}] Adds the MD5 hash for each file to the
+ information printed
+ \item[\texttt{sizes}] Adds the file size for each file to the
+ information printed
+\end{description}
+Note that as Windows and Unix use different line endings (LF \emph{versus} LF
+CR), the hashes and file sizes from the two systems will not be the same. As
+such, you should compare these values between operating systems of the same
+type.
+
+\emph{Warning}: this command will list only files which were read
+using \LaTeX{} commands such as |\input|\arg{file} or
+|\include|\arg{file}. If the file was read using the primitive \TeX{}
+syntax |\input |\emph{file} (without |{ }| braces around the file name)
+then it will not be listed; failure to use the \LaTeX{} form with the
+braces can cause more severe problems, possibly leading to overwriting
+important files, so \textbf{always put in the braces}.
\end{document}
diff --git a/macros/latex-dev/base/utf8ienc.dtx b/macros/latex-dev/base/utf8ienc.dtx
index f1623ee0e6..a2701ac5c8 100644
--- a/macros/latex-dev/base/utf8ienc.dtx
+++ b/macros/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/macros/latex-dev/base/utf8ienc.pdf b/macros/latex-dev/base/utf8ienc.pdf
index da31897579..a7e369b6eb 100644
--- a/macros/latex-dev/base/utf8ienc.pdf
+++ b/macros/latex-dev/base/utf8ienc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/webcomp.err b/macros/latex-dev/base/webcomp.err
index 1b3b7a2475..aabef28187 100644
--- a/macros/latex-dev/base/webcomp.err
+++ b/macros/latex-dev/base/webcomp.err
@@ -373,7 +373,7 @@ preferable in a form usable for this file, i.e.,
\begin{flushleft}
|\erroronpage{|\textit{page-number}|}{|\textit{line-identification}|}{|%
\textit{your-initials}|}{|\textit{date}|}{}| \\
- \hspace*{2em}\textit{description of the the errata}
+ \hspace*{2em}\textit{description of the errata}
\end{flushleft}
Here is an example:
\begin{verbatim}
diff --git a/macros/latex-dev/base/webcomp.pdf b/macros/latex-dev/base/webcomp.pdf
index afda6ddc4b..c9664c681f 100644
--- a/macros/latex-dev/base/webcomp.pdf
+++ b/macros/latex-dev/base/webcomp.pdf
Binary files differ